0

I'm making a new program from scratch and adding an action listener to my program really confuses me. This program is just for experimenting and the visual interface is not that pleasant. Just disregard it for now.

I tried but.addActionListener(this); but it still gave me an error.

./Inventory.java:31: error: non-static variable this cannot be referenced from a static context

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.*;

public class Inventory extends JFrame implements ActionListener {
    public Inventory() {
        startgui();
    }

    public static void startgui() {
        JFrame frame = new JFrame("Inventory");

        frame.setLayout(null);
        frame.setSize(500, 480);
        frame.setLocation(540, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        JLabel label = new JLabel("Welcome To My Program");
        label.setBounds(10, 10, 310, 60);
        label.setVisible(true);
        frame.add(label);
        JButton but = new JButton("Well Played");
        but.setBounds(20, 20, 70, 30);
        frame.add(but);

        but.addActionListener(/* what do I insert here? */);
    }

    public void actionPerformed(ActionEvent e) {
        System.out.print("yess");
    }
}
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110

2 Answers2

0

You cannot use the this keyword inside static methods. This is because the this keyword refers to the current instance of the class that runs the method, but static methods don't belong to a single instance and instead are shared among all instances.

You can read more here about the this keyword. You can also read here about the static keyword. In order to fix you issue try:

 but.addActionListener(frame);

This will only work if you change frame to be an instance of Inventory, but be cautious in how you change that because you can create an infinite loop.

In general, I don't think you need to construct a new Frame object and instead make startgui non-static and use the this keyword.

Saviour
  • 302
  • 2
  • 11
0

Saviour explained it very well, i will be adding more things to your code.
Because you implement ActionListener and you want to add functionality to the button in the same class, you need but.addActionListener(this). this refers to an instace of the class. But because you have a static method and inside of the method you have this keyword, the compiler says "no". You can delete the static keyword and add this keyword:

   public class Inventory extends JFrame implements ActionListener{
        public Inventory(){
        startgui();
        }
        public void startgui(){ //<---Here delete static
        JFrame frame = new JFrame("Inventory");

       //Code...

        but.addActionListener(this); //<---Here add this
        }

        public void actionPerformed(ActionEvent e) { 
                System.out.print("yess"); 
        }

}

Or you can make another class named ButtonListener that implements ActionListener and you can keep your static keyword in that method:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ButtonListener implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("HII");
    }

}

then instead of this just make an anonymous object: new ButtonListener(). Personally i would delete that static keyword and make another class implementing the ActionListener, this would delete complexity to your class, you will have fewer lines of code and additionally will increase readability.

Moreover, try to use Layout Managers. Swing has to be used with layouts. You can make an application without, but you will find later problems that tell you "you had to use layouts".

In the end, because you extend JFrame, you won't need a JFrame instance again, because your class is already a JFrame (from inheritance):

public class ApplicationPoint extends JFrame{

       JLabel label;
       JButton but;

        public ApplicationPoint(String title){

        super(title);   
        startgui();
        setVisible(true);

        }

        public void startgui(){

        setLayout(new FlowLayout());
        setSize(500,480); //I'm not using frame.setSize, just simply setSize(500,480)
        setLocationRelativeTo(null); //This will display the frame in the middle of your screen
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        label = new JLabel("Welcome To My Program");
        label.setVisible(true);

        but = new JButton("Well Played");

        add(but);
        add(label);

        but.addActionListener(new ButtonListener()); 
        }

        public void actionPerformed(ActionEvent e) { 
                System.out.print("yess"); 
        }

        public static void main(String []args) {
            new ApplicationPoint("Inventory");
        }

}
xXJinXx
  • 35
  • 3