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方法自动调用.