【问题标题】:Java MVC with Observer-pattern not synchronize for different views具有观察者模式的 Java MVC 不同步不同的视图
【发布时间】:2015-01-31 11:12:45
【问题描述】:

我正在使用观察者模式编写一个简单的 java Canvas 应用程序,因此我可以创建多个同步窗口(视图)。但是我遇到了一个问题,多个视图在调试时同步,但在实际运行时不同步。

谁能帮我解决这个问题?

我是这样实现的(我接受了@Hovercraft Full Of Eels 的建议,并尝试创建和发布一个最小、完整且可验证的示例程序。):

监听器,它是一个接口:

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

我有一个模型,用来不断通知所有听众;

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

一个视图实现了Listener,我重写了dragMouse函数并实现了画布:

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();
  }
}

在主课中,我创建了 2 个视图。

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

但是如果我在一个窗口上绘制,只有一个显示图形,如picture所示

但是如果我追溯代码,两个窗口都会反映图形,如picture所示

谢谢!

【问题讨论】:

  • 要获得更好的帮助,请考虑创建并发布Minimal, Complete, and Verifiable Example Program。我们不想看到你的整个程序,而是你应该将你的代码压缩成仍然可以编译的最小部分,没有与你的问题无关的额外代码,但仍然可以证明你的问题。并且模型不应调用 dragMouse 或其他侦听器方法。它应该只是更改其状态,然后通过调用通知方法通知侦听器状态已更改,就是这样。
  • 另外,您的视图不应使用通过在组件上调用 getGraphics() 获得的 Graphics 对象进行绘制,但这是另一个讨论的主题。
  • @HovercraftFullOfEels 感谢您的建议!
  • 不客气。理解模型应该完全不知道视图和控件,这意味着它不应该知道任何关于它们的字段或它们的方法,并且不应该调用任何内容。它所知道的是,当它的状态发生变化时,它必须将变化通知侦听器,仅此而已。这是绝对必要的,因为模型应该可供各种控件和视图使用。
  • 您明白,除非您改进,否则您提出的问题仍然无法回答。我再次建议您创建并发布mcve(请查看链接)。

标签: java swing model-view-controller observer-pattern synchronize


【解决方案1】:

根据可用的不可编译代码,我无法告诉你出了什么问题,但我可以说:

  • CanvasModel 保存关键程序数据,这里可能是List&lt;Point&gt; 或者更好的是List&lt;List&lt;Point&gt;&gt;。* CanvasModel 不应该调用监听器方法。所有视图共享的数据。
  • CanvasModel 绝对应该调用任何侦听器或视图方法,例如您编写的。
  • 相反,侦听器/控件应该调用可以更改 CanvasModel 变量状态的 CanvasModel 方法。
  • 然后 CanvasModel 应该调用通知方法,以便任何监听其状态的类都会收到更改通知。
  • 然后侦听器可以调用方法从模型中提取状态(getter 方法)。
  • 视图将使用此信息来更改其显示。

【讨论】:

  • 嗨@HovercraftFullOfEels,再次感谢您对 MVC 的所有伟大建议,真的让我更好地理解它!我正在努力改进它,让它更像“MVC” :) 同时,这是我这个程序的原始代码,如果你愿意,可以看一下 :) dropbox.com/sh/crt3kinngy66uvi/AABmAksb8lQBl2oP5qH0P56ga?dl=0
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
  • 2015-04-09
  • 1970-01-01
  • 2012-09-02
  • 2012-05-11
  • 2011-12-21
相关资源
最近更新 更多