我有一个 ListView
,并且它在其 selectedItemProperty()
中添加了一个 ChangeListener
。如果监听器内部某些条件为真,则可能会以某种方式使监听器无效,例如:
listView.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> {
if (thereIsUnsavedData()) {
// invalidate somehow so to don't change from item A to B
} else{
// load the content of the newValue
}
});
当条件为真时,我可以让它不执行任何操作,但仍然更改 listView
中的选择,这不是 listView.getSelectionModel().select(oldValue); 的解决方案。因为它再次触发听众。有什么想法吗?
编辑:
所以我发现存在一些误解,所以让我们澄清一下:
当用户点击 listView
中非当前的另一个元素且当前 View 上有未保存的数据时,会弹出一个 Dialog
并询问用户:有未保存的数据,您希望继续吗?并回答是/否。如果用户选择是,那么一切都很好,让他更改 View ,但如果他选择否,那么应该保留实际 View 。因此,在我的情况下,任何禁用这些元素的建议都是错误的。我在这里找到了一个解决方案,但我不确定它是否是最佳的:
private ChangeListener<Item> changeListener =
(observable, oldValue, newValue) -> {
if (thereAreUnsavedData()) {
listView.getSelectionModel().selectedItemProperty().removeListener(getListener());
Platform.runLater(() -> {
listView.getSelectionModel().select(oldValue);
listView.getSelectionModel().selectedItemProperty().addListener(getListener());
});
} else {
loadSelected(newValue);
}
};
最佳答案
因此,我不推荐两种解决方案:
- 使用
listView.getSelectionModel().select(oldValue);
将其设置为旧值,但先取消注册监听器,然后再注册回来。 - Alternativley 还可以使用
listView.getSelectionModel().select(oldValue);
,但设置一个标志,在再次触发监听器时检查该标志。
这两种解决方案都容易出错。
因此,我建议的解决方案是通过删除或更好地停用列表中的项目来阻止用户做出当前没有意义的选择。这将提高应用程序的可用性,因为用户在撤消选择时不会感到沮丧。
关于JavaFx:使 ChangeListener 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45194895/