2014-09-19 78 views
8

我想知道如何綁定綁定的源可能爲null的值。JavaFX綁定和空值

我有一個屬性:

private ObjectProperty<Operation> operation = new SimpleObjectProperty<>(null); 

我也有一個文本字段:

@FXML 
private Text txtCurrentOperation; 

我想現場的textProperty綁定到操作對象的值。

我首先想到的是使用FluentAPI其時/那麼/否則建造,但它急切地評價這樣的解決方案:

Bindings.when(operation.isNotNull()) 
    .then("null") 
    .otherwise(operation.get().getName())); 

將拋出一個NPE,因爲otherwise參數進行評估,無論when的結果是什麼。

我的下一個想法是使用拉姆達莫名其妙:

txtCurrentOperation.textProperty().bind(() -> 
     new SimpleStringProperty(
      operation.isNotNull().get() ? "Null" : operation.get().getName() 
      )); 

但綁定沒有拉姆達啓用的解決方案。 (後來,我意識到它不可能有,因爲真正的工作倒退:綁定對象(操作)的更改將觸發活頁夾(字段文本屬性)的更新。)

我發現的一些文章建議爲屬性使用「極值」值而不是null。但是Operation是一個複雜而重量級的組件,因此構造一個人工實例來表示null並不是微不足道的。更重要的是,這對我來說似乎是boilercode,這個綁定機制旨在幫助消除。

我的下一個嘗試是邏輯交換綁定方向,並將偵聽器添加到操作屬性,並讓它以編程方式更新字段。它的工作原理和相當簡單,只要更新只需要依賴的操作對象實例:它拋出:

operation.addListener((e) -> { 
     txtCurrentOperation.setText(operation.isNull().get() ? 
      "Null" : operation.get().getName()); 
}); 
operation.set(oper); 

這是比較簡單的,但是不工作「A限值不能設置。」例外,我不明白爲什麼控件的文本屬性被視爲綁定。

我跑出了想法。經過多次搜索,我仍然無法解決簡單的問題,根據源是否爲空來不同地更新文本字段。

這似乎是如此簡單和日常問題,我相信我錯過了解決方案。

回答

6

如果第三方庫是一個選項,請查看EasyBind。嘗試是這樣的:

EasyBind.select(operation) 
     .selectObject(Operation::nameProperty) 
     .orElse("null"); 

還有一個JavaFX JIRA issue通過EasyBind提供的功能類型。如果你不希望使用第三方庫,儘量Bindings.select

Bindings.when(operation.isNotNull()) 
    .then("null") 
    .otherwise(Bindings.select(operation, "name")); 

注意空在Bindings.select檢查是不是超級效率。有一個JIRA issue for it

+0

感謝這兩種解決方案。儘管第二個代碼有小小的打字錯誤(在選擇(操作部分)之後出現錯位的右括號),但它效果很好。我閱讀了關於低效率的文章,但這不是一個問題,因爲單一的綁定會更改很少 另外我檢查了這個庫,它看起來像是在兌現,所以我可能也會試一試。 – Balage1551 2014-09-19 19:54:09

+0

另外,lambda的另一個解決方案(在EasyBind的示例中找到,但不需要庫):'txtCurrentOperation。 textProperty()。bind(Bindings.createStringBinding() - > operation.isNull()。get()?「null」:operation.get()。getName(),operation));' – Balage1551 2014-09-19 20:12:29

+0

這解決了我的問題保存按鈕爲我的編輯器API在這裏被打破 – 2017-10-05 04:56:17

0

只是爲了防止有人使用Java本身而不使用Kotlin。 使用精彩的tornadofx庫是一個不錯的主意。 在那裏你可以使用operation.select{it.name}。雖然這個功能似乎還沒有被記錄下來,所以花了一些時間來發現它。

+0

這是一個javafx的問題不是javafx vs kotlin的問題 – JRichardsz 2017-05-28 14:22:40

+0

@JRichardsz,javafx和java和kotlin是一樣的我的觀點是如果你由於某種原因KO特林,這個問題有一個很好的解決方案。 Tornadofx只是一個在javafx之上的庫。 – Darksnake 2017-05-29 12:37:20