所以我在Java Swing中有这个漂亮的漂亮的MVC架构应用程序,现在我想添加一个进度条,我对Good Design Methods感到困惑,将JProgressBar合并到我的视图中。我应该:
将DefaultBoundedRangeModel添加到我的控制器状态,然后将其导出?
class Model {
final private DefaultBoundedRangeModel progress
= new DefaultBoundedRangeModel();
public void getProgressModel() { return progress; }
public void setProgressCount(int i) { progress.setValue(i); }
}
class Controller {
Model model;
int progressCount;
void doSomething()
{
model.setProgressCount(++progressCount);
}
}
class View {
void setup(Model m)
{
JProgressBar progressBar = /* get or create progress bar */ ;
progressBar.setModel(m.getProgressModel());
}
}
/* dilemma: Model allows progress to be exported so technically
all of the progress state could be set by someone else; should it be put
into a read-only wrapper? */
使用JGoodies Binding尝试将JProgressBar的视觉状态连接到我的模型的状态?
class Model {
private int progress;
public void getProgressCount() { return progress; }
public void setProgressCount(int i) { progress = i; }
}
class View {
void setup(Model m)
{
ProgressBar progressBar = /* get or create progress bar */ ;
CallSomeMagicMethodToConnect(m, "progressCount", progressBar, "value");
// is there something that works like the above?
// how do I get it to automatically update???
}
}
或其他什么???
编辑更具体一点:有人能指出我的Java应用程序的现实来源的良好示例,其中包含一个包含进度条的状态栏,并且具有适当的MVC实现?
答案 0 :(得分:3)
我会说,别的。
我对MVC的问题是定义模型的抽象级别。
模型可以是UI组件的某种对象
模型也可以是其自身程序的其他类型的对象。
和
在这种情况下,我会为进度条分离模型/组件对,并在单独的控制器类中处理它们。
这个 article 描述了swing体系结构,可能会澄清它在内部使用模型的方式。
答案 1 :(得分:3)
否(至1)和NOOOO(至2)。至少在我看来。
否(至1):首先,DefaultBoundedRangeModel是一个javax.swing类。在我看来,这些类在模型中没有位置。例如,考虑一下生活在服务器上的模型,通过RMI访问 - 所有突然把javax.swing类放在那里似乎“不对”。 但是,真正的问题是,您将模型的一部分(有界模型)提供给其他人,而无法控制所触发的事件或查询。
不(到2):呃。绑定很有趣但是(至少在我看来)应该用于UI模型和UI组件之间的同步,而不是数据模型和UI模型之间的同步。再想想,如果您的数据模型存在于RMI访问的远程服务器上会发生什么。
那又怎样?好吧,这只是一个建议,但我会添加一个事件监听器接口并添加标准的事件监听器订阅方法(addListner(...),removeListener(...))。当我进行更新时,我会从我的模型中调用这些监听器。当然,为了使客户端(在这种情况下是UI)能够正确同步(invokeLater和朋友),我确保记录调用线程(或者说无法确定)。由于监听器服务将由控制器公开,这将允许模型在任何地方生活(甚至允许远程调用或合并监听器)。此外,这会将模型与UI分离,从而可以构建包含它的更多模型(翻译/装饰/依赖模型)。
希望这有帮助。
答案 2 :(得分:3)
在我们的应用程序(MVC,大约100 KLOC)中我们就是这样(模式观察者,实际上):
/**
* Observer on progress changes
*/
public interface IProgressListener {
public void setProgress(ProgressEvent e);
}
public class ProgressEvent extends ... {
private int progressCount;
// setter + getter
...
}
class Model {
public void addProgressListener(IProgressListener l);
protected void fireProgressChange(ProgressEvent e); // call .setProgress() on listeners
}
class Controller {
private Model model;
}
class View extends ProgressBar implements IProgressListener {
...
// IProgressListener implementation
public void setProgress(ProgressEvent e) {
this.setValue(e.getProgress());
}
...
}