1

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?

Gabriel Stellini
  • 426
  • 4
  • 13

1 Answers1

3

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).

kiheru
  • 6,588
  • 25
  • 31
  • Is there a viable alternative which allows me to keep using JFrame the way it is, rather than making Jframe an object and using extends on observable? – Gabriel Stellini Jan 23 '16 at 12:18
  • 1
    @Gabrielus Generally it's advisable to use a `JFrame` rather than extend it. Anyway, extending `Observable` such way that it makes `setChanged()` `public` (or in any other way that has the effect that ensures `setChanged()` is called when needed) would allow using the custom `Observable` subclass the way you want. – kiheru Jan 23 '16 at 12:26
  • @kiheru is correct; alternatively, use `setChanged()` to defer notification; a complete example illustrating `Observable` is seen [here](http://stackoverflow.com/a/3072979/230513). – trashgod Jan 23 '16 at 14:02