【问题标题】:progress bars + MVC in Java =?进度条 + Java 中的 MVC =?
【发布时间】:2010-10-27 17:38:38
【问题描述】:

所以我在 Java Swing 中有一个漂亮的、漂亮的 MVC 架构应用程序,现在我想添加一个进度条,我对将 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 实现?

【问题讨论】:

    标签: java model-view-controller swing progress-bar


    【解决方案1】:

    否(对 1)和 NOOOO(对 2)。至少在我看来。

    否(对 1):首先,DefaultBoundedRangeModel 是一个 javax.swing 类。在我看来,这些类在模型中没有位置。例如,考虑生活在服务器上的模型,通过 RMI 访问 - 突然将 javax.swing 类放在那里似乎“不正确”。 但是,真正的问题是您将模型的一部分(有界模型)提供给其他人,而无法控制触发的事件或进行的查询。

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

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

    希望这会有所帮助。

    【讨论】:

    • 顺便说一句,你应该看看 SwingWorker - 它专门处理这个问题(从后台任务更新进度)。
    【解决方案2】:

    我想说点别的。

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

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

    • 模型也可以是它自己的程序的其他类型的对象。

    • 模型可以和商业模型一样高。

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

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

    【讨论】:

      【解决方案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());
        }
        ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-18
        • 2011-07-28
        • 1970-01-01
        • 2013-09-11
        • 2013-02-24
        • 2010-10-25
        相关资源
        最近更新 更多