Shukant Pal
Shukant Pal

Reputation: 730

FXML, Alternate Uses: Using ObservableList<>

As in this thread FXML: Alternate Uses, I am building an application that uses FXML for loading objects into memory directly.

I have successfully setup objects where specific properties can be easily set like hostName, typeName, moto, e.g. But, in FXML you have lists - like child nodes of JavaFX UI elements held in a ObservableList. I am having trouble using a features (ObservableList) property in FXML. It gives an error that UnsupportedOperationException: cannot determine type for property. Why isn't it able to add elements to the list if it can for other objects like BorderPane.

Upvotes: 0

Views: 158

Answers (1)

Slaw
Slaw

Reputation: 45786

Because ObservableList has no public concrete types you have to use FXCollections factory methods to obtain an instance. Luckily, FXML was designed to handle cases like this: by using the fx:factory attribute. You can learn more about the different fx: options in Introduction to FXML | JavaFX 10.

An example.

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.collections.FXCollections?>

<FXCollections fx:factory="observableArrayList" xmlns="http://javafx.com/javafx/10.0.2"
            xmlns:fx="http://javafx.com/fxml/1">

    <!-- your children elements -->

</FXCollections>

The type of the element will be the type returned by the factory method declared by fx:factory. In this case, an ObservableList (backed by an ArrayList).


If you have a class defined with an ObservableList field (such as features) with an appropriate getter you should be able to do this:

<YourObject>
    <features>
        <!-- your feature elements -->
    </features>
</YourObject>

However, I am having trouble getting that to work. When I tried it only the first element was added to the ObservableList and I have no idea why (maybe it's a bug).

I managed to workaround this using:

<fx:define>
    <ArrayList fx:id="tempList">
        <!--- your feature elements -->
    </ArrayList>
</fx:define>

<YourObject>
    <features>
        <fx:reference source="tempList"/>
    </features>
</YourObject>

I was also having issues using the DefaultProperty annotation as well for some reason. It kept telling me "doesn't have a default property"... but it does!

Other than the "workaround" you could simply have it "set" the ObservableList just like any other property. Or you could (probably) use an FXML annotation in combination with fx:id.

Upvotes: 1

Related Questions