可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I got two errors after I compiled my code.
The errors are:
1.
local variable input is accessed within inner class;
needs to be declared final
String name = input.getText();
2.
local variable c_age is accessed within inner class;
needs to be declared final
Object child_age = c_age.getSelectedItem();
This is my code:
import javax.swing.*;
import java.awt.event.*;
public class GUI
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Try GUI");
JLabel l1 = new JLabel("Please Enter Your Child's Name");
JTextField input = new JTextField("",10);
JLabel l2 = new JLabel("Choose Your Child's Age");
String[] age = {"Age","1","2","3","4","5","6"};
JComboBox c_age = new JComboBox(age);
JButton button = new JButton("Search");
JTextArea result = new JTextArea();
JScrollPane extend_area = new JScrollPane(result);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
String name = input.getText();
Object child_age = c_age.getSelectedItem();
}
});
JPanel panel = new JPanel();
panel.add(l1);
panel.add(input);
panel.add(l2);
panel.add(c_age);
panel.add(button);
panel.add(extend_area);
frame.add(panel);
frame.setSize(350,350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
How can I solve this error?
回答1:
You need to declare
JTextField input = new JTextField("",10);
and
JComboBox c_age = new JComboBox(age);
like this:
final JTextField input = new JTextField("",10);
final JComboBox c_age = new JComboBox(age);
This means that input
and c_age
cannot change:
Any local variable, used but not
declared in an inner class must be
definitely assigned before the
body of the inner class.
Explanation taken from The Java Language Specification, Section - 8.1.3 Inner Classes and Enclosing Instances
回答2:
If you declare the variables as an final then it will solve your errors but according to me its not the good solution for the problem. Similar problem has discussed here you can have a look here for more understanding.
In solution to yours problem you can have define methods by using them you can get better solution. For hint you can read
How to access non-final local variable inside anonymous inner class
回答3:
Any variable that you use inside the actionPerformed
method of your inner class will need to be declared final. Try the following:
import javax.swing.*;
import java.awt.event.*;
public class GUI
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Try GUI");
JLabel l1 = new JLabel("Please Enter Your Child's Name");
final JTextField input = new JTextField("",10);
JLabel l2 = new JLabel("Choose Your Child's Age");
String[] age = {"Age","1","2","3","4","5","6"};
final JComboBox c_age = new JComboBox(age);
JButton button = new JButton("Search");
JTextArea result = new JTextArea();
JScrollPane extend_area = new JScrollPane(result);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
String name = input.getText();
Object child_age = c_age.getSelectedItem();
}
});
JPanel panel = new JPanel();
panel.add(l1);
panel.add(input);
panel.add(l2);
panel.add(c_age);
panel.add(button);
panel.add(extend_area);
frame.add(panel);
frame.setSize(350,350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
回答4:
As adding final
takes away a lot of flexibility, I'd like to suggest the following: create an accessor method, which is encouraged anyway. But this is mostly useful when dealing with objects, while in your case everything is static. Therefore, this answer might not apply to your specific situation, but because googling for your error message yields this question as the top result, I think an alternative that's applicable in most cases (using objects is more common than doing everything from a static method) should be present here as well.
public class MyClass extends MySuperClass {
private MyPropertyClass aProperty;
public MyClass() {
new JButton().setActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// aProperty.aMethod(); -- Bang! That should be final, the compiler says.
getMyProperty().aMethod(); // -- Everything okay, works fine, no compiler complaints.
}
});
}
public getMyProperty() {
return aProperty;
}
}
回答5:
The JTextField named input was declared inside of the main method. You should probably do something like this:
public class GUI{
//declare all your components here e.g.
JTextField input;
public static void main(String args[]){
new GUI();
}
public GUI(){
//instantiate components here
input = new JTextField();
//and so on.
}
}
That way the reference to input inside the inner class will give no problems.
回答6:
You have to declare final
the two variables you're accesing: input
and c_age
.
If you don't want to do this, then you can either create a new proper class (not an ad-hoc one) and pass those as parameters in the constructor, or (I did this when working with GUIs in Java) create a listener class that takes objects in its constructor and makes them available locally, then ad-hoc instantiate that.
回答7:
The input variable and the c_age variable disappears after the method execution is completed. You wont be allowed to use these variables inside the local inner classes unless it is final.
回答8:
I just created a temporary var in the main class e.g 'tempString' and then it can be set to the var that's causing the problem. So:
tempString = myString
that way I can call tempString without any problem at all. Check my example below:
// Create my temp var here
private String tempUrl;
// my function here
public void updatePage(String url)
{
// Can use 'url' here because it's not within inner class
if(!url.equals(""))
{
// Set 'tempUrl' to 'url' so I can use it without problem
tempUrl = url;
// My inner class that used to cause the problem
backgroundUpdate = new Thread(new Runnable()
{
// From here on I use 'tempUrl' to solve the problem
public void run()
{
// Do something with 'tempUrl' here (where 'url' used to be used)
}
});
backgroundUpdate.start();
}
}