Search code examples
javaswingobserver-pattern

Passing values around using observable or events or interfaces


EDIT: I know there is a lot of code but it's really simple, promise!

I have written the following code in an attempt to pass e (from mouseListener) between two JFrames. The only requirement I have is to use Observable/interfaces/events to pass the values around (and not, say, parameters)

import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Observable;
import javax.swing.JFrame;

public class CustomJFrame extends JFrame implements MouseListener 
{
    Observable observe = new Observable();

    public CustomJFrame() 
    {
        setSize(new Dimension(600,800));
        addMouseListener(this);
        setVisible(true);

    }

    @Override
    public void mouseClicked(MouseEvent e) 
    {   
        System.out.println("Clicked");
        observe.notifyObservers(e);
    }
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}


    public Observable getObservable() {
        return observe;
    }

    public void setObservable(Observable observe) {
        this.observe = observe;
    }
}

Class to recieve "e":

import java.awt.Label;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;

public class CallMe extends JFrame implements Observer 
{
Label result = new Label("Still to be changed");

public CallMe() 
{
    add(result);
    setSize(600,600);
    setVisible(true);
}

@Override
public void update(Observable o, Object arg) 
{
    System.out.println("Called");
    result.setText(arg.toString());
}

}

Lastly the main

import java.util.Observable;

public class MainClass 
{
    public static void main(String[] args) 
    {
        CustomJFrame jf = new CustomJFrame();
        CallMe cm = new CallMe();

        Observable ob = new Observable();
        ob.addObserver(cm);

        jf.setObservable(ob);
    }
}

So what's wrong?


Solution

  • Observable.notifyObservers() will notify the observers only if the observable has been marked as changed. The way to set it changed is calling setChanged() - and that method is protected instead of public. In other words, you're meant to extend Observable, instead of using a plain Observable object. (Why the class is not abstract, I don't know. It would make sense for it to be since extending it is the only way to use it).