- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个用例,我想将多个 ObservableValue
绑定(bind)到一个 Observable
上,因为我实际上不感兴趣,值的变化是什么,我只需要一种在更改时得到通知的方法。
所以这是 Observable 绑定(bind),我想到了:
BooleanBinding() {
{
super.bind(proxy.activeShipProperty());
INavigableVessel activeShip = proxy.getActiveShip();
super.bind(activeShip.getLoadBinding());
if (activeShip instanceof IShip) {
super.bind(((IShip) activeShip).travelState());
} else {
super.bind(((IConvoy) activeShip).getOrlegShip().travelState());
}
super.bind(date.dayDateBinding());
}
private boolean value = true;
@Override
protected boolean computeValue() {
value = !value;
return value;
}
};
然后是这个测试代码,以验证它是否按预期工作:
Observable observable = contentProvider.createObservable(ENoticeBoardType.SHIP_WARE_INFO, proxy);
IntegerProperty invalidationCounter = new SimpleIntegerProperty(0);
InvalidationListener listener = observable1 -> invalidationCounter.setValue(invalidationCounter.get() + 1);
observable.addListener(listener);
// When
dayBinding.invalidate();
loadBinding.invalidate();
travelState.set(EShipTravelState.ANCHOR);
activeVessel.set(mock(IShip.class));
// Then
assertEquals(4, invalidationCounter.get());
事实并非如此。 invalidationCounter 仅在第一次 invalidate 调用时增加一次。
然而,当我将上面的 BooleanBinding 作为 ObservableValue
处理时,我可以添加一个 ChangeListener:
ChangeListener listener = (obs, oldValue, newValue) -> invalidationCounter.setValue(invalidationCounter.get() + 1);
observable.addListener(listener);
// When
dayBinding.invalidate();
loadBinding.invalidate();
travelState.set(EShipTravelState.ANCHOR);
activeVessel.set(mock(IShip.class));
// Then
assertEquals(4, invalidationCounter.get());
这按预期工作。
我想知道/已经确认: InvalidationListener 只被调用一次,当 Observable
变为无效时,它不会变回有效,因此它可以再次变为有效。但是,使用 ChangeListener
会强制计算新值,因此 ObservableValue
再次有效。
根据这个观察,有没有我可以实际使用 Observable
的用例? ?
最佳答案
Observable
只是一个接口(interface),实现决定了调用 invalidate
是否会触发处于特定状态的监听器。您在此处观察到的行为是 BooleanBinding
仅触发一次 invalidation
更新,直到使用 get()
方法检索到该值。
一旦通知了监听器,观察器就应该知道该值可能已更改。
这是一种避免不必要计算的优化。例如。考虑以下场景:存在三个 BooleanProperty
b1
、b2
和 b3
,您对 b1 && (b2 || b3)
。在这种情况下,您可以应用短路评估,如果 b1
为 false
并且评估(b2 || b3)
不要求您评估 b3
,如果 b2
为 true
。如果 b2
和/或 b3
的计算成本很高,那么不评估它们会使代码性能更高,如果您可以避免的话,例如使用以下实现
BooleanBinding binding = new BooleanBinding() {
{
bind(b1, b2, b3);
}
@Override
protected boolean computeValue() {
if (!b1.get()) {
return false;
}
if (b2.get()) {
return true;
} else {
return b3.get();
}
// the above is basically a longer version of
// return b1.get() && (b2.get() || b3.get());
// to highlight the short circuiting behaviour
}
};
ChangeListener
与 InvalidationListener
相比,需要将新值传递给它们,因此添加任何 ChangeListener
都会导致 get ()
被调用,每个 invalidation
调用都会触发 computeValue
的调用。
关于java - InvalidationListener 与 ChangeListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51453064/
我只关心属性是否已更改,而不是新值。 注册 InvalidationListener 而不是 ChangeListener 是否有利? 我假设对属性的更改首先会使该属性无效并通知所有无效监听器。仅当注
我有一个用例,我想将多个 ObservableValue 绑定(bind)到一个 Observable 上,因为我实际上不感兴趣,值的变化是什么,我只需要一种在更改时得到通知的方法。 所以这是 Obs
我的 InvalidationListener 有问题。它被设置为 SimpleStringProperty 上的监听器。但它只在第一次更改 SimpleStringProperty 时调用。我进入了
我有一个用例,我想将多个 ObservableValue 绑定(bind)到一个 Observable 上,因为我实际上对值变化是什么不感兴趣,我只需要一种在变化时收到通知的方法。 这就是 Obser
运行程序出现如下错误。 NoClassDefFoundError: javafx/beans/InvalidationListener 命令行如下 java -cp "%JAVA_HOME%\lib\
假设我有一个 JavaFX 应用程序,它有一个可观察类 SomeObservableClass 和一些属性: public class SomeObservableClass{ private S
我是一名优秀的程序员,十分优秀!