gpt4 book ai didi

java - 来自 Action 处理程序的 "Cannot refer to a non-final variable"?

转载 作者:行者123 更新时间:2023-11-30 05:55:19 25 4
gpt4 key购买 nike

我保证我已经阅读了无数关于此的帖子,所以我猜我无法将我阅读的内容转化为我正在尝试做的事情。先说叙事。在基础上,我想做的是在我的例子中开发一个对象列表,对象是汽车。汽车列表显示在我的主窗口中。当我想添加一辆新车时,我打开一个对话框来设置属性并创建它。

问题是我一直在对象引用中兜圈子。我试过使用公共(public)方法创建子类并在构造函数中传递对象。这些尝试会导致有关非静态字段或非最终变量的错误。如果我能看到一个关于如何进行引用的可靠示例,我认为其余部分就会水到渠成。

对象

public class Car {
private String size;

public Car(String sizeIn){
this.size = sizeIn;
}
public void setSize(String sizeIn){
this.size = sizeIn;
}
public String getSize(){
return this.size;
}
public String toString(){
return this.size;
}
}

主窗口

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

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JList;

public class MainGUI {

private JFrame frame;
private LinkedList<Car> carList;
private DefaultListModel model;

/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainGUI window = new MainGUI();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Create the application.
*/
public MainGUI() {
initialize();
}

/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JButton btnAddCar = new JButton("Add Car");
btnAddCar.addActionListener(new EditLauncher());
frame.getContentPane().add(btnAddCar, BorderLayout.NORTH);

JList list = new JList(model);
frame.getContentPane().add(list, BorderLayout.CENTER);
}

public void addCar(String size){
Car car = new Car(size);
carList.add(car);
model.addElement(car);
frame.getContentPane().invalidate();
frame.getContentPane().validate();
}

public class EditLauncher implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub

}

}

}

对话框

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;


public class EditDialog extends JDialog {

private final JPanel contentPanel = new JPanel();
private JTextField fldSize;
private MainGUI mainGUI;

/**
* Launch the application.
*/
public static void main(String[] args) {

try {
EditDialog dialog = new EditDialog(mainGUI); //<<ERROR - Cannot make a static reference to the non-static field mainGU
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Create the dialog.
*/
public EditDialog(MainGUI mainGUI) {
this.mainGUI = mainGUI;
setBounds(100, 100, 225, 125);
getContentPane().setLayout(new BorderLayout());
contentPanel.setLayout(new FlowLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
JLabel lblSize = new JLabel("Size");
contentPanel.add(lblSize);
fldSize = new JTextField();
contentPanel.add(fldSize);
fldSize.setColumns(10);

JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
mainGUI.addCar(fldSize.getText()); // << ERROR Cannot refer to a non-final variable mainGUI inside an inner class defined in a different method
}
});
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);

JButton cancelButton = new JButton("Cancel");
cancelButton.setActionCommand("Cancel");
buttonPane.add(cancelButton);

}

}

最佳答案

对于“无法对非静态字段 mainGUI 进行静态引用”

问题是 (EditDialogs) main 是静态的,因此只能访问静态成员或显式对象实例的成员(例如 object.member 形式)。在这种情况下,mainGUI 不是静态成员,因此无法访问:这很好,因为如果调用“main”,则不会创建 MainGUI 实例! (请记住,每次启动应用程序时,只使用一个 main!去掉 EditDialog 中的“main”以避免这种混淆。)

相反,请考虑这个(但是请参阅 Dave 的评论以获得完全更好的方法!):

btnAddCar.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e) {
EditDialog dialog = new EditDialog(MainGUI.this);
dialog.show(); // or whatever
}
});

对于“无法在不同方法中定义的内部类中引用非最终变量 mainGUI”

错误是因为在匿名内部类型 (new ActionListener() { ... }}) 中只能使用成员变量(封闭类型)或“final”局部变量。

现在,有人可能会说“但 mainGUI 是一个成员变量!”

是的,但是它被同名的局部变量遮蔽(this.mainGUI vs mainGUI).以下是我所知道的解决方案:

  1. 更改局部变量名称以避免阴影:public EditDialog(MainGUI theMainGUI) ...

  2. 限定 mainGUI 以告诉 Java 需要成员变量,从而绕过阴影:EditDialog.this.mainGUI.addCar(...),其中EditDialog 是封闭类型的名称。 (上面对 MainGUI.this 使用了相同的方法。)

  3. final注释mainGUI 参数:public EditDialog(final MainGUI mainGUI) ...。成员变量仍将被隐藏,但局部变量将满足访问要求,因为它是“最终的”。

快乐编码。

关于java - 来自 Action 处理程序的 "Cannot refer to a non-final variable"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8406583/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com