Observer/Observable 在 GUI 中
Observer/Observable in a GUI
不久前我问了一个类似的问题,我正在尝试实施解决方案。我有一个 JPanel,它最终会有许多控件来生成一个数字,但现在它只有一个 JButton 作为测试。我正在使用 Observer 和 Observable 让 JPanel 让 JFrame 知道发生了一些变化。我似乎能够告诉 Observer 去观察一些东西,但是 update() 似乎并没有调用 Observer 对象。我不确定我哪里出错了,找到关于 Observer/Observable 的好教程几乎是不可能的。
对象子面板扩展了 Observable,子面板内部是我添加到 JFrame 的 JPanel。这似乎是我可以获得 GUI 来扩展 Observable 的唯一方法。
如果这听起来令人困惑,我很抱歉。我不知道还能怎么解释。我只希望 GUI 菜单对象能够在发生更改时通知 JFrame。
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestObserver implements Observer{
JFrame frame = new JFrame();
//The panel in the frame that is to be watched for a change.
SubPanel sf = new SubPanel();
TestObserver(){
frame.setTitle("New Program!");
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
sf.addOutsideObserver(this);
frame.add(sf.panel);
frame.setVisible(true);
}
@Override
public void update(Observable arg0, Object arg1) {
// TODO Auto-generated method stub
System.out.println("I have been notified!");
}
public static void main(String[] args) {
TestObserver mf = new TestObserver();
}
}
class SubPanel extends Observable implements ActionListener{
JPanel panel = new JPanel();
JButton b = new JButton();
int count = 0;
// Observer ob = new Observer();
SubPanel(){
b.addActionListener(this);
panel.add(b);
}
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
// The counter is not important, just something to display
count++;
System.out.println("Count: " + count);
// This does not seem to be happening in the Observer object
notifyObservers();
}
public void addOutsideObserver(Observer o){
addObserver(o);
System.out.println("I'm added!");
}
}
Observable
class 有一个名为 changed
的成员默认为 false
可以通过 protected setChanged
方法修改。如果 changed
为假,notifyObservers
方法只是 returns 而不做任何事情。所以在你调用 notifyObservers
之前先调用 setChanged ,这样它就会更新观察者。
public void notifyObservers(Object arg) {
if (!changed)
return;
...
}
编辑:我刚刚注意到评论中已经提供了答案。
notifyObservers()
acts only after a change occurs (as verified by hasChanged()
方法)。
在您的代码中,您需要添加 setChanged()
以便在调用 notify
之前设置更改指示器。
您不需要之后调用clearChanged()
,因为此方法由notifyObservers
方法自动调用.
不久前我问了一个类似的问题,我正在尝试实施解决方案。我有一个 JPanel,它最终会有许多控件来生成一个数字,但现在它只有一个 JButton 作为测试。我正在使用 Observer 和 Observable 让 JPanel 让 JFrame 知道发生了一些变化。我似乎能够告诉 Observer 去观察一些东西,但是 update() 似乎并没有调用 Observer 对象。我不确定我哪里出错了,找到关于 Observer/Observable 的好教程几乎是不可能的。
对象子面板扩展了 Observable,子面板内部是我添加到 JFrame 的 JPanel。这似乎是我可以获得 GUI 来扩展 Observable 的唯一方法。
如果这听起来令人困惑,我很抱歉。我不知道还能怎么解释。我只希望 GUI 菜单对象能够在发生更改时通知 JFrame。
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestObserver implements Observer{
JFrame frame = new JFrame();
//The panel in the frame that is to be watched for a change.
SubPanel sf = new SubPanel();
TestObserver(){
frame.setTitle("New Program!");
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
sf.addOutsideObserver(this);
frame.add(sf.panel);
frame.setVisible(true);
}
@Override
public void update(Observable arg0, Object arg1) {
// TODO Auto-generated method stub
System.out.println("I have been notified!");
}
public static void main(String[] args) {
TestObserver mf = new TestObserver();
}
}
class SubPanel extends Observable implements ActionListener{
JPanel panel = new JPanel();
JButton b = new JButton();
int count = 0;
// Observer ob = new Observer();
SubPanel(){
b.addActionListener(this);
panel.add(b);
}
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
// The counter is not important, just something to display
count++;
System.out.println("Count: " + count);
// This does not seem to be happening in the Observer object
notifyObservers();
}
public void addOutsideObserver(Observer o){
addObserver(o);
System.out.println("I'm added!");
}
}
Observable
class 有一个名为 changed
的成员默认为 false
可以通过 protected setChanged
方法修改。如果 changed
为假,notifyObservers
方法只是 returns 而不做任何事情。所以在你调用 notifyObservers
之前先调用 setChanged ,这样它就会更新观察者。
public void notifyObservers(Object arg) {
if (!changed)
return;
...
}
编辑:我刚刚注意到评论中已经提供了答案。
notifyObservers()
acts only after a change occurs (as verified by hasChanged()
方法)。
在您的代码中,您需要添加 setChanged()
以便在调用 notify
之前设置更改指示器。
您不需要之后调用clearChanged()
,因为此方法由notifyObservers
方法自动调用.