我正在使用观察者模式编写一个简单的 java Canvas 应用程序,因此我可以创建多个同步窗口( View )。但是我遇到了一个问题,多个 View 在调试时同步,但在实际运行时不同步。
谁能帮我解决这个问题?
以下是我实现这一点的方法(我采纳了 @Hovercraft Full Of Eels 的建议,并尝试创建和发布一个最小、完整且可验证的示例程序。):
监听器,它是一个接口(interface):
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);
}
}
}
View 实现了监听器,我重写了dragMouse函数并实现了 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();
}
}
在主类中,我创建了 2 个 View 。
public static void main(String[] args){
CanvasModel model = new CanvasModel();
new CanvasView(model);
new CanvasView(model);
}
但是如果我在一个窗口上绘图,则只有一个窗口显示图形,如picture所示
但是如果我跟踪代码,两个窗口都会反射(reflect)图形,如picture所示
谢谢!
最佳答案
根据可用的不可编译代码,我无法告诉您出了什么问题,但我可以说:
- CanvasModel 保存着关键的程序数据,这里可能是
List<Point>
或者更好的是List<List<Point>>
.* CanvasModel 不应调用监听器方法。所有 View 共享的数据。 - CanvasModel 绝对应该不调用任何监听器或 View 方法,例如您编写的那样。
- 相反,监听器/控件应该调用可以更改 CanvasModel 变量状态的 CanvasModel 方法。
- 然后 CanvasModel 应调用通知方法,以便任何监听其状态的类都将收到更改通知。
- 然后,监听器可以调用方法从模型中提取状态(getter 方法)。
- View 将使用此信息来更改其显示。
关于具有观察者模式的 Java MVC 不同步不同 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27262423/