我正在使用 JavaFX 属性,因为 JavaFX 8.0 ,他们似乎错过了我认为合适的东西。假设我向JavaFX属性添加了一个更改侦听器:
DoubleProperty doubleProp = new SimpleDoubleProperty(1);
doubleProp.addListener((observable,oldValue,newValue)->{ ...code here }));
我想再添加3个,包括InvalidationListener
为什么要创建ChangeListener
JavaDoc或InvalidationListener
JavaDoc的实例?
添加以下代码行:
ChangeListener<? super Number> listener = (observable , oldValue , newValue) -> {
if (newValue.intValue() == 1)
//..... code
};
到处都不清楚。
为什么这些方法不存在:
doubleProp.getChangeListeners().clearAll();
或
doubleProp.getChangeListeners().remove(doubleProp.getChangeListeners().get(0));
或
doubleProp.remove(doubleProp.getChangeListeners().get(0));
或
doubleProp.getInvalidationListeners().get(0));
JavaFX 9.0是否有类似这样的方法?我想要一个糟糕的设计?我需要知道上面的内容:)。
答案 0 :(得分:4)
允许访问属性上所有侦听器的集合将是一个糟糕的设计,因为它会破坏使用这些属性的控件(或其他对象)的封装。 (具体来说,控件可能希望在注册该属性上的侦听器时公开属性并将这些侦听器保持为私有。如果属性公开了侦听器,则这将变得不可能。)
就像一个例子,如果StringProperty
公开了ObservableList<ChangeListener<String>> getListeners()
方法,则API可以实现以下目标:
Label label = new Label("Some text");
label.textProperty().getListeners().clear();
这会完全破坏标签。标签的皮肤使用标签textProperty()
注册一个监听器,以确保在文本更改时皮肤更新。如果删除此侦听器(这是执行上述代码的唯一可能结果),则标签的外观不会知道在调用label.setText(...)
时必须调整大小甚至显示新文本。
如果您需要注册可能需要删除的侦听器,则只需要保留对它的引用。代码中的开销很小,即
之间差别不大label.textProperty().addListener((obs, oldText, newText) -> { /* code */ });
和
ChangeListener<String> listener = (obs, oldText, newText) -> {/* code */} ;
label.textProperty().addListener(listener);
答案 1 :(得分:1)
@James_D,您的解释是,如果不小心删除了某个监听器,可能会出问题。但是,这实际上是一个开发人员问题,而不是 design 问题。确实,对于任何“添加/删除”模式不,也包括对已添加内容的访问权限,都是不好的设计。
例如,可能会临时删除(“暂停”)所有监听器 ,以执行更改值(实际上是多次)的过程,其中值的结尾是过程与开始相同;当该过程完成时,将侦听器重新添加(“还原”)。虽然“引用”解决方案适用于您在设计控件时了解的侦听器,但对开发人员使用控件添加的侦听器无济于事-无法引用这些侦听器,因为您不知道它们将是什么。 “暂停/恢复”技术可以解决此问题,这取决于开发人员在正确的情况下正确使用它。
JavaFX的属性增强(对象属性,绑定等)是对Swing的巨大改进,例如从有盖货车转向布加迪。但是,省略“ getListeners()”功能是一个缺点。