从内部类内部访问局部变量:需要声明 final 错误 java swing
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19280796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Local variable is accessed from within inner class: needs to be declared final error java swing
提问by james kerr
I am having trouble making a button that closes this swing and returns to the previous swing menu. I have tried the following...
我在制作关闭此秋千并返回上一个秋千菜单的按钮时遇到问题。我尝试了以下...
btnBack = new JButton("Back");
btnBack.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MainMenu gui = new MainMenu(uname);
gui.setVisible(true);
gui.pack();
gui.setLocationRelativeTo(null);
frame.setVisible(false);
frame.dispose();
}
});
When I try this, it's giving me the error
当我尝试这个时,它给了我错误
Local variable frame is accessed from within inner class: needs to be declared final
从内部类内部访问局部变量 frame:需要声明为 final
I have trimmed my code removing my JDBC
我已经删除了我的 JDBC 代码
public class newImageViewer implements ActionListener {
JLabel lblInstru, lblInstruVal, lblInstrumentID, lblImgnameVal, lblImgtagVal, lblImgsizeVal, lblDateVal, lblImgpathVal, lblTakenbyVal, lblNoteVal, lblImgpath, lblTakenby, lblSalary, lblImgsize, lblDate, lblS,
lblSVal, lblNote, lblImgtag, lblImgname, imagel;
JTextField txtDate, txtImgpath, txtTakenby, txtImgname, txtImgtag, txtImgsize, txtNote, txtInstrumentID;
JButton btnAdd, btnUpdate, btnDelete, btnPrev, btnNext, btnBack;
ResultSet rs;
private ImageIcon image1;
String imagepath, uname;
static final String DATABASE_URL = "jdbc:mysql://localhost:3306/mysql";
static final String USERNAME = "root";
static final String PASSWORD = "root";
public static void main(String[] args) {
newImageViewer obj = new newImageViewer();
obj.createUI();
}
private void createUI() {
JFrame frame = new JFrame("Image Details");
JPanel pnlInput = new JPanel(new GridLayout(4, 2));
lblImgname = new JLabel(" Image Name : ");
txtImgname = new JTextField();
lblImgtag = new JLabel(" ImageTag : ");
txtImgtag = new JTextField();
lblDate = new JLabel(" Date Stamp : ");
txtDate = new JTextField(15);
lblImgpath = new JLabel(" Image Path : ");
txtImgpath = new JTextField();
lblTakenby = new JLabel(" Taken By : ");
txtTakenby = new JTextField();
lblImgsize = new JLabel(" Image Size : ");
txtImgsize = new JTextField();
lblNote = new JLabel(" Note : ");
txtNote = new JTextField();
lblInstrumentID = new JLabel(" Instrument ID : ");
txtInstrumentID = new JTextField();
pnlInput.add(lblImgname);
pnlInput.add(txtImgname);
pnlInput.add(lblImgtag);
pnlInput.add(txtImgtag);
pnlInput.add(lblImgsize);
pnlInput.add(txtImgsize);
pnlInput.add(lblNote);
pnlInput.add(txtNote);
pnlInput.add(lblDate);
pnlInput.add(txtDate);
pnlInput.add(lblImgpath);
pnlInput.add(txtImgpath);
pnlInput.add(lblTakenby);
pnlInput.add(txtTakenby);
pnlInput.add(lblNote);
pnlInput.add(txtNote);
pnlInput.add(lblInstrumentID);
pnlInput.add(txtInstrumentID);
JPanel pnlButton = new JPanel(new GridLayout(1, 3));
btnAdd = new JButton("Add");
btnAdd.addActionListener(this);
btnUpdate = new JButton("Update");
btnUpdate.addActionListener(this);
btnDelete = new JButton("Delete");
btnDelete.addActionListener(this);
btnBack = new JButton("Back");
btnBack.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MainMenu gui = new MainMenu(uname);
gui.setVisible(true);
gui.pack();
gui.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
pnlButton.add(btnAdd);
pnlButton.add(btnUpdate);
pnlButton.add(btnBack);
pnlButton.add(btnDelete);
JPanel pnlNavigate = new JPanel(new GridLayout(1, 2));
btnPrev = new JButton(" << ");
btnPrev.setActionCommand("Prev");
btnPrev.addActionListener(this);
btnNext = new JButton(" >> ");
btnNext.setActionCommand("Next");
btnNext.addActionListener(this);
pnlNavigate.add(btnPrev);
pnlNavigate.add(btnNext);
JPanel pnlNavAns = new JPanel(new GridLayout(4, 2));
lblImgname = new JLabel(" Image Name : ");
lblImgnameVal = new JLabel("Val");
lblImgtag = new JLabel(" Image Tag : ");
lblImgtagVal = new JLabel("Val");
lblImgsize = new JLabel(" Image Size : ");
lblImgsizeVal = new JLabel("Val");
lblDate = new JLabel(" Date Stamp : ");
lblDateVal = new JLabel("Val");
lblImgpath = new JLabel(" Image Path : ");
lblImgpathVal = new JLabel("Val");
lblTakenby = new JLabel(" Taken By : ");
lblTakenbyVal = new JLabel("Val");
lblNote = new JLabel(" Note : ");
lblNoteVal = new JLabel("Val");
lblInstru = new JLabel(" Instrument ID : ");
lblInstruVal = new JLabel("Val");
pnlNavAns.add(lblImgname);
pnlNavAns.add(lblImgnameVal);
pnlNavAns.add(lblImgtag);
pnlNavAns.add(lblImgtagVal);
pnlNavAns.add(lblImgsize);
pnlNavAns.add(lblImgsizeVal);
pnlNavAns.add(lblDate);
pnlNavAns.add(lblDateVal);
pnlNavAns.add(lblImgpath);
pnlNavAns.add(lblImgpathVal);
pnlNavAns.add(lblTakenby);
pnlNavAns.add(lblTakenbyVal);
pnlNavAns.add(lblNote);
pnlNavAns.add(lblNoteVal);
pnlNavAns.add(lblInstru);
pnlNavAns.add(lblInstruVal);
final Container cn = frame.getContentPane();
cn.setLayout(new BoxLayout(cn, BoxLayout.Y_AXIS));
frame.add(pnlInput);
frame.add(pnlButton);
frame.add(pnlNavAns);
frame.add(pnlNavigate);
//If this will not be written, the only frame will be closed
// but the application will be active.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent evt) {
String action = evt.getActionCommand();
if (action.equals("Add")) {
addOperation();
} else if (action.equals("Update")) {
updateOperation();
} else if (action.equals("Delete")) {
deleteOperation();
} else if (action.equals("Prev")) {
preNavigation();
} else if (action.equals("Next")) {
nextNavigation();
}
}
private void addOperation()
private void updateOperation()
private void deleteOperation()
private void preNavigation()
private void nextNavigation()
private void populateValue()
}
回答by Hovercraft Full Of Eels
As noted, all you need to do is listen to your compiler and simply make the frame variable final:
如前所述,您需要做的就是听取编译器并简单地将 frame 变量设为 final:
final JFrame frame = new JFrame("Image Details");
An alternative solution is to make frame a non-static class field.
另一种解决方案是使 frame 成为非静态类字段。
The reason for the problem is that you're trying to use a local variable in an anonymous inner class, and since these classes make copies of these variables, if the variable is not marked final, there's a chance that the two frame variables, the local one and the copy inside the anonymous class's object, might hold different values.
问题的原因是您试图在匿名内部类中使用局部变量,并且由于这些类制作这些变量的副本,如果变量未标记为 final,则有可能两个框架变量,本地的和匿名类对象内的副本可能持有不同的值。
Edit
As per my comment, your question is a very common one. For details on the problem please see this possible duplicate question: Why are only final variables accessible in anonymous class?. I'm going to vote to close this question as a duplicate and encourage others to to the same so that the comments to the accepted answer get read. The comments to the answer are where the real answer is.
编辑
根据我的评论,您的问题很常见。有关该问题的详细信息,请参阅这个可能的重复问题:为什么在匿名类中只能访问最终变量?. 我将投票结束这个重复的问题,并鼓励其他人也这样做,以便阅读对已接受答案的评论。对答案的评论才是真正的答案所在。