【发布时间】:2012-10-06 12:04:21
【问题描述】:
当使用 SwingWorker 时,如何将视图与模型分离,该进程需要将更新发送回控制器?
我可以使用
SwingWorkersdoInBackground()来保持 EDT 响应,例如从那里调用model.doLongProcess()很棒!我遇到的问题是尝试在进程完成之前取回数据,以更新视图的进度..
我知道我可以使用
SwingWorkerspublish()方法取回数据,但我认为这迫使我在doInBackground()中编写doLongProcess()方法的代码。
为了参考 MVC 实现,我看起来有点像这样:
http://www.leepoint.net/notes-java/GUI/structure/40mvc.html
/ structure/calc-mvc/CalcMVC.java -- Calculator in MVC pattern.
// Fred Swartz -- December 2004
import javax.swing.*;
public class CalcMVC {
//... Create model, view, and controller. They are
// created once here and passed to the parts that
// need them so there is only one copy of each.
public static void main(String[] args) {
CalcModel model = new CalcModel();
CalcView view = new CalcView(model);
CalcController controller = new CalcController(model, view);
view.setVisible(true);
}
}
我有一个模型类,它将许多其他类包装在一起形成一个简单的控制器接口。
我真的不想将所有/部分/任何代码从这些类移到控制器中 - 它不属于那里。
更新:
这是我正在采用的方法 - 它不是最干净的解决方案,它可能被视为在语义层面上滥用 PropertyChangeSupport..。
基本上所有具有长时间运行方法的低级类都会有一个propertyChangeSupport 字段。长时间运行的方法会定期调用firePropertyChange() 来更新方法的状态,而不必报告属性的变化——这就是我所说的语义滥用!
然后包装低级类的模型类捕获这些事件并发出自己的高级firePropertyChange .. controller 可以监听...
编辑:
澄清一下,当我调用 firePropertyChange(propertyName, oldValue, newValue);
- propertyName ---> 我滥用propertyName 来表示主题名
- oldValue =null
- newValue = 我要广播的消息
然后是模型中的 PropertyChangeListener 或任何可以根据主题名称识别消息的地方。
所以 Iv 基本上将系统弯曲为像发布-订阅一样使用它......
我猜想代替上述方法,我可以向要更新的低级类添加一个进度字段,然后基于它的 firePropertyChange.. 这将符合它的预期使用方式。
【问题讨论】:
-
请查看对我的回答的编辑以响应您的更新。
标签: java swing model-view-controller design-patterns swingworker