GUI中的Observer / Observable

时间:2015-01-25 05:25:53

标签: java user-interface

前一段时间我问了一个类似的问题,我试图实施解决方案。我有一个JPanel,它最终会有一些控件来生成一个数字,但是现在它只有一个JButton作为测试。我正在使用Observer和Observable让JPanel让JFrame知道某些事情发生了变化。我似乎能够告诉Observer注意某些东西,但update()似乎没有调用Observer对象。我不确定我哪里出错了,找到一个关于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!");
    }
}

2 个答案:

答案 0 :(得分:3)

发生更改后

notifyObservers() 行为(由hasChanged()方法验证)。

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

由于此方法由notifyObservers方法自动调用,之后需要调用clearChanged()

答案 1 :(得分:1)

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

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

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