7

I have a class let's say MyJFrame which represent the GUI of my application. It implements the interface Observer and override the method update.

public class MyJFrame extends JFrame implements Observer{
  ...
  public void update(Observable arg0, Object arg1){
     ...
  }
}

Now I want to make also my JFram an Observable object but I can't because it already extend the class JFrame. I tried to create a variable of type Observable in my class.

public class MyJFrame extends JFrame implements Observer{
  Observable observable = new Observable();

The problem here is that I can add Observer to this observable field and I can also notify the observer but I cannot invoke the method setChanghed() (because it is declared as protected) which has to be called before the notification.

Do you have any idea about I can implement it?

Thanks!!

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Maverik
  • 2,358
  • 6
  • 34
  • 44

3 Answers3

7

I think many here, myself included use the Observer Design Pattern without using Java's formal Observer/Observable interface/class, and there are many ways to implement this, especially in Swing. Probably the most flexible is to use PropertyChangeSupport with PropertyChangeListeners which is how SwingWorkers implement this. Another is to use the very basic ChangeListener interface.

If you need more specific help, please provide more detail on your problem and likely we can offer suggestions.

Edit 1
This also alights on a separate but important issue that's suggested by the description of your program: your GUI class extending JFrame. Many here (again myself included) recommend that you should avoid doing this unless your code alters the intrinsic behavior of JFrame -- that is that your class overrides one or more of JFrame's methods. This is a small sub-discussion in the much greater discussion on which is better: enhancing classes through inheritance or through composition.

For example: Prefer composition over inheritance?

Edit 2
Next unrequested recommendation: I try to gear my GUI code toward creating JPanels rather than JFrames. This way if I want to display my GUI as a stand-alone GUI, I simply create a JFrame on the fly, place my gui's JPanel into the JFrame's contentPane, pack the JFrame and display it. I do the same procedure if I want to place the gui into a JDialog, a JApplet, a JOptionPane, or also in a CardLayout using container, another JPanel,... . This gives me tremendous flexibility in how I use my gui's.

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
3

Extend Observable and declare setChanged() public.

Jeffrey
  • 44,417
  • 8
  • 90
  • 141
  • Can you be more detailed please? Thanks! – Maverik Aug 06 '11 at 17:46
  • 2
    When you extend a class, you can redeclare its methods with a visibility modifier that is higher than it previously was. Since `Observable`s `setChanged()` was protected, you can create a subclass of `Observable` with `setChanged()` being public. – Jeffrey Aug 06 '11 at 17:49
  • 1
    I don't now way but I was sure that it was not possible modify the visibility of a method. Thanks, it works! – Maverik Aug 06 '11 at 17:53
  • You might also want to look at Hovercraft's answer. People tend to go with `PropertyChangeListener`s as opposed to `Observable` / `Observer`. – Jeffrey Aug 06 '11 at 17:55
  • So it is possible to increase the visibility but not to decrease, right? It's the same for the variable? Thanks – Maverik Aug 06 '11 at 17:59
2

This will do it.

public class MyJFrame extends JFrame implements Observer {
    private static class MyObservable extends Observable {
        @Override
        public void setChanged() {
            super.setChanged();
        }
    }
    private final MyObservable observable = new MyObservable();

    // rest of your code
} 
Steve McLeod
  • 51,737
  • 47
  • 128
  • 184
  • 1
    maybe correct for OP, but there I think that for this implementations output to the GUI must be wrapped into invokeAndWait(), – mKorbel Aug 06 '11 at 18:03