1

In a java swing project I have a model class that holds the state of a certain JPanel. I need to make this data available to the view. There are two options as I see it. Have a class that extends Observable and has the model as an instance variable. See the code example below. Or just have the model class extend Observable itself.

public class BoardObservable extends Observable {

private Board board;

public Board getBoardText() {
    return board;
}

public void setBoardText(Board board) {
    this.board = board;
    setChanged();
    notifyObservers(board);
}
}

So in the view class that implements Observer it will either use the Observable parameter or the Object parameter to populate the JPanel.

    @Override
public void update(Observable o, Object arg) {
    if(o instanceof BoardObservable) {
        this.board = (Board) arg;
    }
}

Which is the best option?

user1213428
  • 77
  • 2
  • 7

2 Answers2

1

As shown above, the use of an extra class seems redundant. However, in actually trying to understand what you are trying to do, it looks like you have backed into a Model-View-Controller (MVC) design.

Since that link handles MVC really well, I'll address your question directly. The primary goal is to decouple the View and interaction (controller) from the model so you can reuse the model for other user interfaces.

The BoardObserver should become your Controller. It should also be an observer of the Board, but it also makes direct calls to the Board object. If there is any change to the model that impacts the view (not merely updating of information, but logical state - like a button becoming disabled due to the state of the program or data), the controller should process that information and make the corresponding updates to the view.

Make the View an observer of the Board. The view should inform the controller of any actions and the controller should update the logical state (disable of button, etc) of the view. If the raw data in the model changes, you can directly update the view from that.

Finally, pulling it all together. I tend to pass the model into the Controller's constructor and let the Controller create (and...control) the view.

Model m = new Model();
Controller c = new Controller(m);
Chris
  • 694
  • 3
  • 18
1

Your approach hinges on the observer pattern, examined here. Because Observable and Observer are complementary, you need both. Typically, the model can extend Observable, as shown in your BoardObservable, but your model can delegate to a contained Observable if necessary. In contrast, the view only has to implement the Observer interface; this example delegates updates to a nested ModelObserver.

Alternative approaches to implementing the observer pattern are cited here. See also this answer on Swing controllers.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045