【问题标题】:Observer/Observable in a GUIGUI 中的观察者/可观察者
【发布时间】:2015-01-25 05:25:52
【问题描述】:

不久前我问了一个类似的问题,我正在尝试实施该解决方案。我有一个 JPanel,它最终会在上面有许多控件来生成一个数字,但现在它只有一个 JButton 作为测试。我正在使用 Observer 和 Observable 让 JPanel 让 JFrame 知道某些事情发生了变化。我似乎能够告诉观察者注意什么,但 update() 似乎没有调用观察者对象。我不确定我哪里出错了,几乎不可能找到关于 Observer/Observable 的好教程。

Object Subpanel 扩展了 Observable,在 Subpanel 内部是我添加到 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!");
    }
}

【问题讨论】:

  • Java the JavaDocs for notifyObserver "如果这个对象发生了变化,如hasChanged方法所示,则通知其所有的观察者,然后调用clearChanged方法表明这个对象不再改变了。"

标签: java user-interface


【解决方案1】:

notifyObservers() 动作仅在发生更改后(通过hasChanged()方法验证)。

在您的代码中,您需要添加setChanged() 以便在调用notify 之前设置更改指示器。

您确实不需要事后调用clearChanged(),因为此方法由notifyObservers 方法自动调用

【讨论】:

  • 谢谢。它的工作方式与我预期的不同。我认为在寻求帮助时甚至没有提到任何关于需要 setChange() 的内容。
【解决方案2】:

Observable 类有一个名为changed 的成员,默认为false,可以通过受保护的setChanged 方法修改。如果changed 为假,notifyObservers 方法只会返回而不做任何事情。所以在你调用notifyObservers 之前先调用setChanged,这样它就会更新观察者。

public void notifyObservers(Object arg) {
    if (!changed)
        return;
    ...
}

编辑:我刚刚注意到 cmets 中已经提供了答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    • 2021-04-13
    • 1970-01-01
    相关资源
    最近更新 更多