进度条+ Java中的MVC =?

时间:2009-05-20 18:42:56

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

所以我在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实现?

3 个答案:

答案 0 :(得分: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());
  }
  ...
}

答案 1 :(得分:3)

我会说,别的。

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

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

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

  • 模型可以与商业模式一样高。

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

这个 article 描述了swing体系结构,可能会澄清它在内部使用模型的方式。

答案 2 :(得分:3)

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

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

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

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

希望这有帮助。