在Java中处理循环事件的优雅方式?

Def*_*efd 6 java events swing awt cyclic

我觉得这对我来说不是一个特定的问题; 以前每个人都可能遇到过这个问题.为了正确说明它,这是一个简单的UI:

alt text http://www.freeimagehosting.net/uploads/7aec06ea46.png

如您所见,这两个微调器控制着一个变量 - "A".唯一的区别是他们使用不同的视图来控制它.

由于这两个微调器的显示值是同步的,因此出现循环事件.

如果我更改顶部微调器,"A"将被更改,底部微调器的值也将相应更新.但是,更新底部微调器的调用(例如setValue)也会触发另一个事件,指示顶级微调器根据底部微调器的值进行更新.因此创建一个错误的循环,最终可能导致StackOverFlow异常.

我以前的解决方案有点麻烦:我放置了一个保护布尔值来指示是否应该执行第二次更新调用.

现在我想问一下" 我怎么能优雅地处理这种情况?(一般来说,不是特定于纺纱厂)"

谢谢


更新:

由于我有2个答案建议我利用观察者结构,我不得不说些什么.

就像我说的那样,它很棒,但远非完美.不仅因为其固有的复杂性,而且还因为它无法解决问题.

为什么?要了解原因,您必须在Java Swing中实现View和Model-Controller 的紧密耦合.让我们以我的微调器UI为例.假设变量A实际上是Observer对象.然后,在从顶部微调器触发第一个状态更改事件后,观察者"A"将更新其值并触发PropertyChange事件以通知底部微调器.然后是第二次更新,更新底部微调器的视图.但是,更改底部微调器的视图不可避免地会触发冗余事件,该事件将再次尝试设置"A"的值.然后,完全构造致命循环并抛出堆栈溢出.

理论上,Observer模型试图通过引入2个独立的反馈路径来解决直接循环.链式更新赔率(在事件响应代码中)隐含地形成连接两个路径的桥,再次进行循环.

Rev*_*nzo 3

回到模型-视图-控制器,想想你的模型是什么,你的视图是什么。

在当前的实现中,您有两个模型(每个 Spinner 控件一个),并且它们通过视图层同步。

不过,您应该做的是共享相同的支持模型。对于具有减去值的微调器,创建原始模型的代理。IE:

class ProxySpinnerModel implements SpinnerModel {
    getValue() { return originalSpinner.getValue() - 10 }
    setValue(v) { originalSpinner.setValue(v+10) }
}

spinnerA = new JSpinner()
spinnerB = new JSpinner( new ProxySpinnerModel( spinnerA.getModel() ) )
Run Code Online (Sandbox Code Playgroud)

现在,您不需要添加侦听器,因为它们都使用相同的模型,并且默认实现(originalModel)已经具有向视图触发的更改侦听器。