我正在编写一个Swing程序,其中所有面板都声明为单独的类和一个保存面板的JFrame。输入面板有一个子面板,上面有许多按钮。当单击其中一个按钮并计算一个值时,我想将该值传递回持有输入面板的JFrame,以便该值可用于许多其他计算。
我知道我可以使用JFrame ActionListener直接负责子面板上的按钮,但这似乎违反了可移植性,封装或两者兼而有之。我希望子面板能够独立工作,并让使用它的JFrame知道某个值何时发生变化。
我宁愿将值保留为原语,但如果只有一个对象可以工作,我可以继续使用它。
该程序已经编写为一个类,它工作正常,但编辑的野兽。当我完成后,我意识到不将它分成六个面板作为他们自己的类是错误的。未来项目的一课。因此,我正在重写它并遇到JFrame依赖于知道其中一个面板(实际上是该面板上的面板)何时重新计算值的问题。值计算不是问题,但JFrame需要知道它何时发生变化。
我希望这很清楚。我觉得很清楚! : - )
以下代码简化了我尝试做的事情。
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
public class ChangeState extends JFrame {
// This is to receive the value when changed in ButtonPanel
private JTextField answer = new JTextField(5);
private InputPanel inputPanel = new InputPanel();
public ChangeState() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(inputPanel, BorderLayout.CENTER);
add(answer, BorderLayout.SOUTH);
pack();
setVisible(true);
}
public static void main(String[] args) {
ChangeState mf = new ChangeState();
}
}
class InputPanel extends JPanel {
private ButtonPanel buttonPanel = new ButtonPanel();
InputPanel() {
add(buttonPanel);
}
}
class ButtonPanel extends JPanel implements ActionListener {
private int value;
JButton b1 = new JButton("Value *2");
JButton b2 = new JButton("Value *3");
public ButtonPanel() {
value = 1;
b1.addActionListener(this);
add(b1);
b2.addActionListener(this);
add(b2);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
value *= 2;
}
if (e.getSource() == b2) {
value *= 3;
}
System.out.println("Value: " + value);
/*
* How do I let ChangeState.answer know VALUE has changed and needs
* to be updated?
*/
}
}
答案 0 :(得分:2)
你可以通过成为一个听ButtonPanel的ActionListener,或者通过一些你可以创建的更抽象的自定义观察者,将ChangeState变为ButtonPanel的observer。
当类观察不是另一个只有一个事件的GUI类时,我推荐一个更抽象的自定义观察者,但在这种情况下,因为它可能只是使用一个ActionListener(另一方面,ChangeState是不是很多GUI类,你可以让它由JFrame组成。
如果您有多个事件可以通过该ActionListener传递,那么您可能需要使ChangeState实现更抽象的观察器实现,以便您可以更好地区分事件。否则,您需要让ChangeState知道创建事件的一些不同GUI组件的名称,或者引用它们并不是那么好的设计。