我有一個工作人員填充結果列表。一個ListView綁定到這個結果列表,並在它們可用時立即用部分結果填充。很棒!JavaFX DataBinding的行爲很奇怪
然後有一個按鈕可以處理列表中的項目。所以它應該被禁用,只要列表是空的。這適用於其他列表。但不是這個。
我已通過剝離UI組件並僅使用屬性來減少了示例。結果是一樣的。要麼有某種錯誤,要麼我不明白綁定是如何工作的。
我希望對此有所幫助。
只需將此代碼放入main()方法中,您應該會看到問題。我使用Java 1.8更新74
// a list of items, e.g. in a list view
ReadOnlyObjectWrapper<ObservableList<String>> items = new ReadOnlyObjectWrapper<>(
FXCollections.observableArrayList(new ArrayList<>()));
// a button that is disabled if there are no items
BooleanProperty disabled = new SimpleBooleanProperty();
disabled.bind(Bindings.createBooleanBinding(() -> Boolean.valueOf(items.get().isEmpty()), items));
// a list with results, e.g. from a worker
ReadOnlyObjectWrapper<ObservableList<String>> results = new ReadOnlyObjectWrapper<>(
FXCollections.observableArrayList(new ArrayList<>()));
// the items are bound to the results (the list is showing partial result then)
items.bind(results);
// the button is still disabled
System.out.println(disabled.get()); // expected true !WORKS!
// add a result (should inform the items and the button)
results.get().add("Hello");
// both list should be identical now
System.out.println(results.get()); // expected [Hello] !WORKS!
System.out.println(items.get()); // expected [Hello] !WORKS!
// the button should not be disabled anymore
System.out.println(disabled.get()); // expected false !FALIED!
// try to re-bind the button
disabled.unbind();
disabled.bind(Bindings.createBooleanBinding(() -> Boolean.valueOf(items.get().isEmpty()), items));
System.out.println(disabled.get()); // expected false !WORKS!
我做了一些更多的測試,考慮到您的信息。其實是調用'項目。綁定(結果);'在我的代碼中改變'items'包裝的值。如果你在前後調用'items.get()',你會得到一個不同的值。所以任何綁定到由'items'包裝的列表都是無用的。如果我事後做,一切都會奏效。我沒有想到這一點,仍然不完全明白爲什麼。 – Future
@未來:我在答案中加了幾行。我希望它們幫助你理解並且不會混淆你......基本綁定不會重新計算值,除非他們認爲它是根據依賴項上發生的事件進行的必要步驟,並且'Property's不會將偵聽器添加到包裹的值,除非它是一個特殊的屬性,比如'MapProperty','ListProperty'或'SetProperty' – fabian