nafg
nafg

Reputation: 2534

Binding.scala FXML: How to populate an ObservableList property

I have code like this:

val state = Var(initialState)

// ...
type SavedSearchCmb = ComboBox[SavedSearch]
val savedSearchesCmb: Binding[SavedSearchCmb] =
  <SavedSearchCmb>
    <items>
      {state.bind.savedSearches}
    </items>
  </SavedSearchCmb>

The compiler complains,

[error]  found   : Seq[com.dev1on1.timer.YouTrackAPI.SavedSearch]
[error]  required: javafx.collections.ObservableList[com.dev1on1.timer.YouTrackAPI.SavedSearch]
[error]         <items>

What's the right way to generate the items?

Upvotes: 1

Views: 200

Answers (1)

Yang Bo
Yang Bo

Reputation: 3718

According to the specification of FXML:

A read-only list property is a Bean property whose getter returns an instance of java.util.List and has no corresponding setter method. The contents of a read-only list element are automatically added to the list as they are processed.

items is a list property of SavedSearchCmb, however, it is not read-only as there is a setter setItems. As a result, the previous version of Binding.scala does append content of the savedSearches to the items property, instead, it tries to assign the Constants to items via setItems.

That is to say, the previous behavior of Binding.scala is extractly correct according to the specification.


The FXML behavior is very inconvenient.

Fortunately, Binding.scala does not have to support the extractly same syntax of Oracle's javafx.fxml.FXMLLoader.

I decide to break the specification, allowing appending content of the data-binding expressions to any list properties, no matter it is read-only or not.

The change has been include in Binding.scala 11.0.1. Your code should compile if you upgrade to Binding.scala 11.0.1.

We can do better than the original FXML specification. That's why you choose Binding.scala over javafx.fxml.FXMLLoader.

Upvotes: 1

Related Questions