2009-05-20 101 views
4

所以我在Java Swing中有这个漂亮的MVC架构的应用程序,现在我想添加一个进度条,并且我对好的设计方法感到困惑,以便将JProgressBar合并到我的视图中。我应该:进度条+ Java中的MVC =?

  • 将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数据绑定尝试关于SpringLayout的视觉状态连接到我的模型状态?

    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实现它的一个应用程序?

回答

3

否(至1)和NOOOO(至2)。最起码,我是这么想的。

否(对1):首先,DefaultBoundedRangeModel是一个javax.swing类。在我看来,这些课程在模型中没有地位。例如,想想服务器上的模型,通过RMI访问 - 所有突然把javax.swing类放在那里似乎“不正确”。然而,真正的问题在于,你将模型的一部分(有界模型)给予其他人,无法控制事件触发或查询。

否(至2):呃。绑定很有趣,但是(至少在我看来)应该用来在UI模型和UI组件之间进行同步,而不是在数据模型和UI模型之间进行同步。再次想一想,如果您的数据模型位于RMI访问的远程服务器上,会发生什么情况。

那么是什么?那么,这只是一个建议,但我会添加一个事件侦听器接口并添加标准事件侦听器订阅方法(addListner(...),removeListener(...))。当我进行更新时,我会在模型中调用这些侦听器。当然,为了使客户端(本例中的UI)能够正确同步(invokeLater和朋友),我会确保记录调用线程(或者说它不能被确定)。由于监听器服务将被控制器公开,这将允许模型在任何地方居住(甚至允许远程调用或合并监听器)。此外,这将使模型与UI分离,从而可以构建包含它的更多模型(译者/装饰者/依赖模型)。

希望这会有所帮助。

+0

顺便说一句,你应该看看SwingWorker的 - 它与这个问题涉及(从一个更新的进展后台任务)。 – 2009-05-21 10:34:14

3

我会说,别的。

我用MVC的问题是定义模型的抽象级别。

  • 型号可能是某种对UI组件对象的

  • 型号也可能是一些其他类型的节目是自我的对象。

  • 模型可以高达的商业模式。

在这种情况下,我会为进度条分开模型/组件对,并在单独的控制器类中处理它们。

This article描述了摆动架构,并可能阐明它在内部使用模型的方式。

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