Java another Static/Non-Static issue
Ok, using Eclipse IDE and getting tripped up on the static/non static issue. I think I understand it, but not completely, here is the code.
First Part, mostly created with the swing UI builder. edited out comments/imports
public class Screen {
private JFrame frame;
public JLabel lblNewLabel;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Screen window = new Screen();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Screen() {
initialize();
}
void initialize() {
XListener listenItem = new XListener("Woot"); // creates listen object
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JLabel lblNewLabel = new JLabel("New label");
lblNewLabel.setBounds(193, 154, 56, 16);
frame.getContentPane().add(lblNewLabel);
JButton btnNewButton = new JButton("New button");
btnNewButton.setBounds(163, 73, 97, 25);
frame.getContentPane().add(btnNewButton);
btnNewButton.addActionListener(listenItem); // attaches it to listen object
}
void changeLabel(String setString) {
lblNewLabel.setText(setString);
}
}
Second part is the listener class
// creates class for listen item
public class XListener implements A开发者_运维问答ctionListener {
String foo;
XListener(String setString) {
foo = setString;
}
public void actionPerformed(ActionEvent btnNewButton) {
**Screen.changeLabel(foo);**
}
}
It complains that cannot make a static reference to the non-static method changeLabel(String) from the type Screen. Yet, if I use window, in place of Screen, it cannot find the object. This has me extremely confused. The way I understand the code, is the main method creates a Screen object, named window, which when initialized also creates a XListener object. Why does it consider the actionPerformed method to be static? I know there is something fundamental I am missing, and I have been following the java 'trails' and just don't get it.
You should pass in a reference to the Screen
object you want to affect when the action occurs:
// creates class for listen item
public class XListener implements ActionListener {
String foo;
Screen myScreen;
XListener(String setString, Screen scr) {
foo = setString;
myScreen = scr;
}
public void actionPerformed(ActionEvent btnNewButton) {
myScreen.changeLabel(foo);
}
}
Then, initialize your listener like so:
XListener listenItem = new XListener("Woot", this);
You have to do this because the changeLabel()
method is an instance method on the Screen
class, but you're attempting to access it like a static
method. By having access to the correct Screen
instance, you can call the method properly.
Your XListener class needs an object to call it on. Calling Screen.changeLabel(foo)
will try to call a static method on the class Screen. You need a Screen object passed into your XListener class.
public class XListener implements ActionListener {
String foo;
Screen myScreen; // added
XListener(String setString, Screen theScreen) {
foo = setString;
myScreen= theScreen; // added
}
public void actionPerformed(ActionEvent btnNewButton) {
screen.changeLabel(foo); // fixed
}
}
Then change your init method:
void initialize() {
XListener listenItem = new XListener("Woot",this); // creates listen object
// rest below
}
The method changeLabel
is an instance method, yet you are trying to invoke it using the static method syntax of <Class Name>.<Method Name>. You need to obtain a reference to the Screen
object in order to invoke this method.
One way to resolve it might be to pass such an object to the listener's constructor, like so:
XListener(Screen screen, String setString)
...
this.screen=screen;
...
}
window
is a local variable within the run
method within the anonymous Runnable
subclass created in main
. You certainly can't refer to that within XListener.actionPerformed
.
Java isn't considering the actionPerformed
method to be static - it's saying changeLabel
is non-static but you're trying to access it as if it's static from actionPerformed
, here:
Screen.changeLabel(foo);
It's irrelevant whether actionPerformed
is static or not - the point is that you need to have a reference to an instance of Screen
in order to call the changeLabel
method. Otherwise it's like asking "How tall is the person?" - it doesn't make sense unless you specify which person you're talking about.
If you're finding static/non-static confusing, I would strongly advise you to leave user interfaces well alone for the moment. Write some simple console applications which create some objects, call methods on them etc. Get comfortable with the language, and ideally some of the core libraries (e.g. collections and IO). Then you'll be able to enter the sometimes-daunting world of user interfaces and at least know what's going on at the language level.
You have defined a non-static method called changeLabel but then you try access it off the class, i.e. Screen.changeLabel() which you cannot do since it is not a static method. You first need to instantiate Screen and then call this method off the instance that you have created (or pass through an instance, etc, the point is non-static methods need be be accessed off an Object, not directly off a Class).
精彩评论