【问题标题】:Java MVC: Updating View using Observer patternJava MVC:使用观察者模式更新视图
【发布时间】:2012-01-08 13:26:25
【问题描述】:

在我的应用程序中,我有 View 观察 Model 的变化。 Controller负责处理View派发的事件并更新Model

为了举例,假设我有两个视图。首先,InputView 包含两个 JSpinner 元素(Spinner1Spinner2)。其次,ResultView,包含来自微调器的值的JLabel。作为附加约束,我们希望Spinner2 的值依赖于Spinner1 的值。可以说,Spinner2 中的最小值应该是2x 的当前值Spinner1

当我们更改Spinner1 的值时,Controller 接收ChangeEvent 并更新Model。由于我们还必须调整Spinner2 的值,另一个ChangeEvent 将被调度,Model 将第二次更新。这种模式的问题在于,每个Model 更新观察View 刷新。因此,在此示例中,View 将刷新 3 或 4 次而不是 1 次(Spinner1 更改,Spinner2 最小值更改,Spinner2 值更改)。这会导致闪烁。

如何确保在所有更改完成后View 只更新一次?

【问题讨论】:

  • 请发布一个SSCCE,因为我不知道闪烁,您的代码中肯定还有另一个递归问题
  • 闪烁是指视图随之刷新。如果我们使用某种图表或任何比标签更复杂的东西,多次刷新就会很明显

标签: java model-view-controller swing


【解决方案1】:

gang-of-four book 说:

“谁触发了更新?主体和它的观察者依靠通知机制来保持一致。但是实际上是什么对象调用了Notify来触发更新?这里有两种选择:

Have state-setting operations on Subject call Notify after they change the 
subject's state. The advantage of this approach is that clients don't have 
to remember to call Notify on the subject. The disadvantage is that several
consecutive operations will cause several consecutive updates, which may be
inefficient.

Make clients responsible for calling Notify at the right time. The advantage 
here is that the client can wait to trigger the update until after a series 
of state changes has been made, thereby avoiding needless intermediate updates.
The disadvantage is that clients have an added responsibility to trigger the 
update. That makes errors more likely, since clients might forget to call Notify.

第二个选项可能对你有用。

【讨论】:

    【解决方案2】:

    文章Java SE Application Design With MVC: Issues With Application Design 将问题放在上下文中,并建议使用属性更改“来检查模型的传入更改值与存储在 Swing 组件中的当前值。”

    【讨论】:

      【解决方案3】:

      这就是观察的方式:

      label -> spinner 2 -> spinner 1
      

      如果我是你,我会设置“更改类型”。所以在我的控制器中,我可以控制如何通知我的观察者。

      如果您发布您的代码,我会更有帮助。

      【讨论】:

      • 不,label 观察到Model。带有微调器的面板也观察到“模型”。每个spinnerstate changes 发送到Controller,后者修改Model。此时InputView 更新依赖spinner 2 的值,这会触发第二波Model 更新
      猜你喜欢
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      • 2014-10-20
      • 2010-09-23
      • 2013-03-05
      • 2018-05-16
      • 2015-01-31
      • 1970-01-01
      相关资源
      最近更新 更多