我认为这对我来说不是一个特定的问题;每个人以前可能都遇到过这个问题。
为了正确地说明它,这里有一个简单的 UI:
正如您所看到的,这两个旋转器控制着一个变量——“A”。唯一的区别是他们使用不同的视图来控制它。
由于这两个旋钮的显示值是同步的,因此会出现循环事件。
如果我更改顶部微调器,“A”将更改,底部微调器的值也将相应更新。However,更新底部微调器的调用(例如 setValue)也会触发另一个事件,指示顶部微调器根据底部微调器的值进行更新。这会造成一个坏循环,最终导致 StackOverFlow 异常。
我以前的解决方案有点麻烦:我放置了一个保护布尔值来指示是否应该执行第二次更新调用。
现在我想问“我该如何优雅地处理这种情况? ( 一般而言,不特定于旋转器 )"
thx
Update:
由于我有两个答案建议我利用观察者结构,所以我必须对此说一些话。
就像我所说的,它很棒,但远非完美。不仅因为其固有的复杂性,还因为其无力解决问题.
为什么?要了解其原因,您必须认识到紧耦合Java Swing 中的视图和模型控制器。让我们以我的微调 UI 为例。假设变量A实际上是一个Observer对象。然后,在顶部微调器触发第一个状态更改事件后,观察者“A”将更新其值并触发 PropertyChange 事件以通知底部微调器。然后是第二次更新,更新底部微调器的视图。However,改变底部微调器的视图不可避免地会触发一个冗余事件,该事件将尝试再次设置“A”的值。之后,致命循环完全构建完毕,并且将抛出堆栈溢出。
理论上,观察者模型试图通过引入2条独立的反馈路径来解决直接循环。链式更新赔率(在事件响应代码中)隐式形成连接两条路径的桥梁,再次形成循环。
回到模型-视图-控制器,想想你的模型是什么,你的视图是什么。
在当前的实现中,您有两个模型(每个 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() ) )
现在,您不需要添加侦听器,因为它们都使用相同的模型,并且默认实现(originalModel)已经具有向视图触发的更改侦听器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)