如何处理相关的FX属性?

属性 – ol’样式bean属性与blinky fx属性相同 – 如果它们彼此正交则效果最佳。 如果它们以某种方式相关,它们会再次出现问题 – 两种类型。 在我讨厌的真实世界中,这种情况可能比我们更喜欢。

例如,取twosome selectedIndex / selectedItem:索引指向列表中项目的位置(如果包含),否则为否定。 更新一个也需要更新另一个。

对于java bean,解决方案很简单,因为bean本身可以完全控制何时触发更改。 而对于fx豆?

SelectionModel中使用的基本模式

Property theRealItemProperty = new SimpleObjectProperty(); ReadOnlyProperty readOnlyItemProperty = new ReadOnlyObjectProperty(theRealItemProperty); /** * Public access is read-only */ public final ReadOnlyProperty itemProperty() { return readOnlyItemProperty; } /** * Setting allowed for subclasses only (and mis-behaving package neighbors ;-) */ protected final void setItem(T item) { theRealItemProperty.set(item); } /** * Special setting api for general public */ public void select(T item) { setIndex(indexOf(item)); setItem(item); } 

这些属性在调用它们的setter时触发,bean无法控制。 由于内部状态在这些调用之间是不稳定的,因此第一个调用者必须在接收通知时才能访问第二个调度器。因为他们无法知道哪个是第一个触发,所以他们不能依赖于bean的稳定性。

现在该做什么,无论是拥有bean还是客户端? 以某种方式推迟火灾? ol’技巧Platform.runLater()分散了所有应用程序代码? 难倒……

正如James_D所建议的那样, ReactFX的InhiBeans来救援。

从头开始编写bean时,使用该包提供的属性 – 它们扩展核心类,具有相同的名称,因此它与交换导入一样简单。 然后保护修改方法,如:

 public void select(T item) { Guard guard = Guard.multi(theRealItemProperty.guard(), theRealIndexProperty.guard()); setIndex(indexOf(item)); setItem(item); guard.close(); } 

子类化最终确定其相关属性的核心类时,选项可能是脏的:通过reflection替换它们。 一个例子是AbstractSelectionModelBase ,它当前是我实验中的基础MultipleSelectionModel

 // going dirty: replace super's selectedItem/Index property // with guarded cousins itemReplacement = new ReadOnlyObjectWrapper<>(this, "selectedItem"); replaceField("selectedItem", itemReplacement); indexReplacement = new ReadOnlyIntegerWrapper(this, "selectedIndex", -1); replaceField("selectedIndex", indexReplacement); // usage in methods that update single selection state protected void syncSingleSelectionState(int selectedIndex) { Guard guard = Guard.multi(itemReplacement.guard(), indexReplacement.guard()); setSelectedIndex(selectedIndex); if (selectedIndex > -1) { setSelectedItem(getModelItem(selectedIndex)); } else { // PENDING JW: do better? can be uncontained item setSelectedItem(null); } guard.close(); focus(selectedIndex); } 

在核心中拥有(并使用它!)这样的function会很酷。