属性 - ol'样式bean属性与blinky fx属性相同 - 如果它们彼此正交,则效果最佳。如果它们以某种方式相互关联,它们会再次出现问题 - 两种类型。这可能发生在令人讨厌的真实世界中,而不是我们喜欢的。
作为示例,取twosome selectedIndex / selectedItem:索引指向列表中项目的位置(如果包含),否则为否定。更新一个也需要更新另一个。
对于java bean,解决方案是straightforward,因为bean本身可以完全控制何时触发更改。对于fx bean?
SelectionModel
中使用的基本模式Property<T> theRealItemProperty = new SimpleObjectProperty<>();
ReadOnlyProperty<T> readOnlyItemProperty = new ReadOnlyObjectProperty(theRealItemProperty);
/**
* Public access is read-only
*/
public final ReadOnlyProperty<T> 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&#39;技巧Platform.runLater()分散了所有应用程序代码?难倒..
答案 0 :(得分:2)
正如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();
}
当子类化最终确定其相关属性的核心类时,一个选项可能是变脏:通过反射替换它们。一个例子是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);
}
在核心中拥有(并使用它!)这样的功能会很酷。