Reputation: 319
I asked a similar question a while back and I'm trying to implement the solution. I have a JPanel that will eventually have a number of controls on it to generate a number, but right now it just has a single JButton as a test. I am using Observer and Observable to have that JPanel let the JFrame know something has changed. I seem to be able to tell the Observer to watch for something, but the update() doesn't seem to call the Observer object. I am not sure where I am going wrong and finding a good tutorial on Observer/Observable is almost impossible.
The Object Subpanel extends Observable and inside Subpanel is the JPanel that I add to the JFrame. This seems to be the only way I can get a GUI to also extend Observable.
I'm sorry if this sounds confusing. I'm not sure how else to explain it. I just want an GUI menu object to be able to notify the JFrame when a change occurs.
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!");
}
}
Upvotes: 0
Views: 2744
Reputation: 13334
notifyObservers()
acts only after a change occurs (as verified by hasChanged()
method).
In your code you need to add setChanged()
in order to set the change indicator before calling notify
.
You do not need to call clearChanged()
afterwards since this method is called automatically by the notifyObservers
methods.
Upvotes: 3
Reputation: 1622
Observable
class has a member called changed
defaulted to false
which can be modified by protected setChanged
method. notifyObservers
method just returns without doing anything if changed
is false. So before you call notifyObservers
call setChanged first, so it'll update the observers.
public void notifyObservers(Object arg) {
if (!changed)
return;
...
}
Edit: I've just noticed the answer was already provided in the comments.
Upvotes: 1