Java MVC with Observer-pattern not synchronize for different views

274 Views Asked by At

I'm writing a simple java Canvas app using Observer-pattern, so I can create multiple synchronous windows(views). But I came into an issue that multiple views synchronize when I debug, but not synchronize when actually running.

Anyone can help me out of this?

Here's how I implemented this (I took @Hovercraft Full Of Eels's advice and trying to creating and posting a Minimal, Complete, and Verifiable Example Program.):

Listener, which is an interface:

public interface CanvasListener {
  void dragMouse(MouseEvent e);
}

I have a model, which used to keep notifying all listeners;

public class CanvasModel{
  private List<CanvasListener> listeners;
  //...other functions
  public void mouseDragged(MouseEvent e) {
    for(CanvasListener listener: listeners){
        listener.dragMouse(e);
    }
  }
}

A view implements Listener, and I overrided dragMouse function and implements the canvas:

public class CanvasView implements CanvasListener {
  private CanvasModel model;
  private JPanel panel;

  public CanvasView(CanvasModel myModel) {
    // some initializations
    panel.addMouseMotionListener(new MouseMotionAdapter() {
      public void mouseDragged(MouseEvent e) {
        model.mouseDragged(e);
      }
    });
  }

  @Override
  public void dragMouse(MouseEvent e) {
    Graphics g = panel.getGraphics();
    g.drawLine(a, b, c, d); //parameters here are not real
    g.dispose();
  }
}

And in main class, I created 2 Views.

public static void main(String[] args){
    CanvasModel model = new CanvasModel();
    new CanvasView(model);
    new CanvasView(model);
}

But if I draw on one windows, only one shows the graphics, as shown in picture

But if I trace into the codes, both windows reflect the graphics, as shown in picture

Thanks!

1

There are 1 best solutions below

1
On

I can't tell you what's wrong based on the non-compilable code available, but I can say:

  • The CanvasModel holds the key program data, here perhaps it would be a List<Point> or maybe even better, a List<List<Point>>.* CanvasModel should not be calling a listener method. Data that is shared by all views.
  • CanvasModel should most definitely not be calling any listener or view methods, such as you have it written.
  • Instead, the listeners/Control should be calling CanvasModel methods that can change the state of CanvasModel's variables.
  • Then CanvasModel should call notification methods so that any class listening to its state will be notified of changes.
  • The listeners can then call methods to extract the state from the model (getter methods).
  • And the views would use this information to change their displays.