2015-01-25 4 views
0

Я задал подобный вопрос некоторое время назад, и я пытаюсь реализовать это решение. У меня есть JPanel, который, в конце концов, будет иметь несколько элементов управления, чтобы сгенерировать число, но сейчас у него просто один JButton в качестве теста. Я использую Observer и Observable для того, чтобы JPanel позволял JFrame знать, что что-то изменилось. Кажется, я могу сказать Наблюдателю что-то посмотреть, но update(), похоже, не вызывает объект Observer. Я не уверен, где я ошибаюсь, и найти хороший учебник по Observer/Observable почти невозможно.Наблюдатель/Наблюдаемый в графическом интерфейсе

Подпанель объекта расширяема Наблюдаемая и внутри Subpanel - это JPanel, который я добавляю в JFrame. Кажется, это единственный способ получить графический интерфейс для расширения 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!"); 
    } 
} 
+0

Java JavaDocs for notifyObserver * «Если этот объект был изменен, как указано методом hasChanged, то уведомите всех его наблюдателей, а затем вызовите метод clearChanged, чтобы указать, что этот объект больше не изменен. *« – MadProgrammer

ответ

3

notifyObservers()действует только после того, как произошло изменение (подтверждено hasChanged() способ).

В вашем коде вам нужно добавить setChanged(), чтобы установить индикатор изменения перед вызовом notify.

Вы делаете не необходимость вызова clearChanged() впоследствии так этот метод вызывается автоматически с помощью notifyObservers методов.

+0

Спасибо. Это просто работает по-другому, чем я ожидал. Я не думаю, что в поисках помощи было даже упомянуто о необходимости setChange(). –

1

Observable класс имеет член называется changed обязательство к false, которые могут быть модифицированы с помощью защищенного setChanged метода. notifyObservers метод просто возвращается, ничего не делая, если changed является ложным. Поэтому прежде чем вы вызовете notifyObservers, сначала вызовите setChanged, чтобы он обновил наблюдателей.

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

Редактировать: Я только что заметил, что ответ уже указан в комментариях.

+0

Да, но спасибо за то, что вы все еще даете свой вклад. –

Смежные вопросы