I am using eclipse
and windows builder --> Swing --> Jframe
. I have added textField
, lblNewLabel
and btnNewButton
. By clicking and dropping it on contentPane
. When trying to assign a value to a lblNewLabel
using methods lblNewLabel.setText(textField.getText());
. I get the following error: Cannot refer to a non-final variable lblNewLabel inside an inner class defined in a different method
.
This is my source code:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MultAppMed extends JFrame {
private JPanel contentPane;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MultAppMed frame = new MultAppMed();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public MultAppMed() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblNewLabel = new JLabel("New label");
lblNewLabel.setBounds(106, 14, 46, 14);
contentPane.add(lblNewLabel);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
lblNewLabel.setText(textField.getText());
}
});
btnNewButton.setBounds(335, 228, 89, 23);
contentPane.add(btnNewButton);
textField = new JTextField();
textField.setBounds(10, 11, 86, 20);
contentPane.add(textField);
textField.setColumns(10);
}
}
Why is this happening? I was reading some answers that say: "Java requires references to variables from inner classes to be final variables" but if needed why doesn't Jframe
insert it as such automatically. My textField
is working and I can get and set Its value using the same methods. I was meaning to ask why and how to solve this. I appreciate your help.
You most probably want to change the settings of the window builder with this option "Declare variable as final" on local varaibles.
This should do the trick, since "... . However, a local class can only access local variables that are declared final."
Alternative with fields
Consider using the "convert to local field" operation inside the window builder.
This will change the definition of the label from
JLabel lblNewLabel = new JLabel("New label");
into
private JLabel lblNewLabel;
// in initialization method / c'tor
lblNewLabel = new JLabel("New label");
Environment
Everything tested using
eclipse.ini
-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.200.v20130807-1835
-product
org.eclipse.epp.package.standard.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
--launcher.appendVmargs
-vmargs
-Dosgi.requiredJavaVersion=1.6
-Xms40m
-Xmx512m
java version
C:\....\isi>java -version
java version "1.6.0_30"
Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
Java HotSpot(TM) 64-Bit Server VM (build 20.5-b03, mixed mode)
My question is why do i have to tweak the code to use a simple example of assigning a value to a label. Given that i don't need to do that for a text field
lblNewLabel
is a local variable that can't be accessed inside the anonymous inner class until and unless it's final.
JLabel lblNewLabel = new JLabel("New label");
where as textField
is instance member that can be accessed easily inside the anonymous inner class.
private JTextField textField;
Local variables always live on the stack, the moment method is over all local variables are gone.
But your inner class objects might be on heap even after the method is over (Say an instance variable holds on to the reference), so in that case it cannot access your local variables since they are gone, unless you mark them as final
.
The local variable could change before the inner class accesses it. Making it final
prevents that because final
variable can't be changed once assigned.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.