我保证我已经阅读了无数关于此的帖子,所以我猜我无法将我读到的内容翻译成我想要做的事情。首先是叙述。在此基础上,我想做的是在我的例子中开发一个对象列表,对象是汽车。汽车列表显示在我的主窗口中。当我想添加一辆新车时,我打开一个对话框来设置属性并创建它。
问题是我继续用对象引用在圈子里跑。我尝试使用公共方法创建子类并在构造函数中传递对象。这些尝试导致非静态字段或非最终变量的错误。如果我能看到如何制作参考文献的一个可靠的例子,我认为其余部分将落实到位。
对象
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);
}
}
答案 0 :(得分:6)
问题是(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
}
});
错误是因为只能在匿名内部类型(new ActionListener() { ... }
)中使用成员变量(封闭类型)或“最终”局部变量。
现在,有人可能会“但是mainGUI是一个成员变量!”
嗯,它是但是它被阴影由具有相同名称的本地变量(this.mainGUI
vs mainGUI
)。以下是我所知道的解决方案:
更改本地变量名称以避免出现阴影:public EditDialog(MainGUI theMainGUI) ...
限定mainGUI
告诉Java需要成员变量,绕过阴影:EditDialog.this.mainGUI.addCar(...)
,其中EditDialog
是封闭类型的名称。 (上面针对MainGUI.this
执行了相同的方法。)
使用mainGUI
final
注释public EditDialog(final MainGUI mainGUI) ...
参数。成员变量仍将被遮蔽,但局部变量将满足访问要求,因为它是“最终”。
快乐的编码。