How can I add items to a ComboBox (or other Control) using FXML?
Asked Answered
A

1

6

Recently, I discovered that <ComboBox>—and other controls—can have an <items> element underneath them .

How can I populate, or add items right to a control in the FXML markup?

(One use case for this might be to make the FXML semi-functional as a mockup to show to stakeholders.)

Augur answered 22/12, 2017 at 18:57 Comment(0)
A
16

Research proves that it's done with a combination of the fx:value and fx:factory attributes. These seem to have been added in JavaFX 8 JavaFX 2.

Below, I'll cite the mechanisms and then give some examples.

🦶🔫 Warning:

Note, as @fabian does, that though this works well in the short term for something like a prototype or mockup, adding items directly to the FXML breaks the separation between model and view—and that may likely be an undesired result in the long term.

The Mechanisms

fx:value

The fx:value attribute can be used to initialize an instance of a type that does not have a default constructor but provides a static valueOf(String) method. For example, java.lang.String as well as each of the primitive wrapper types define a valueOf() method and can be constructed in FXML as follows:

<String fx:value="Hello, World!"/>
<Double fx:value="1.0"/>
<Boolean fx:value="false"/>

Custom classes that define a static valueOf(String) method can also be constructed this way.

Source: JavaFX 2 Introduction to FXML


fx:factory

The fx:factory attribute is another means of creating objects whose classes do not have a default constructor. The value of the attribute is the name of a static, no-arg factory method for producing class instances. For example, the following markup creates an instance of an observable array list, populated with three string values:

<FXCollections fx:factory="observableArrayList">
    <String fx:value="A"/>
    <String fx:value="B"/>
    <String fx:value="C"/>
</FXCollections>

Source: JavaFX 2 Introduction to FXML


Some Examples:

ComboBox

<ComboBox value="One">
    <items>
       <FXCollections fx:factory="observableArrayList">
            <String fx:value="Three"/>
            <String fx:value="Two"/>
            <String fx:value="One"/>
        </FXCollections>
    </items>
</ComboBox>

ComboBox in FXML with default value

CheckComboBox

The ControlsFX Controls are a little different:

<CheckComboBox>
    <items>
        <String fx:value="One"/>
        <String fx:value="Two"/>
        <String fx:value="Three"/>
    </items>
</CheckComboBox>

checkcombobox

TableView

TableView gets a little more complicated because it needs CellValueFactorys to know which part of the Person to show in each column.

<TableView prefHeight="200.0" prefWidth="200.0">
    <columns>
        <TableColumn text="Name">
        <cellValueFactory>
            <PropertyValueFactory property="name" />
        </cellValueFactory>
        </TableColumn>
        <TableColumn text="Comment">
        <cellValueFactory>
            <PropertyValueFactory property="comment" />
        </cellValueFactory>
        </TableColumn>
    </columns>  
    <items>
        <FXCollections fx:factory="observableArrayList">
            <Person name="Jacob" comment="Hey!"/>
            <Person name="Isabella" comment="Dude, we're in FXML!"/>
            <Person name="Ethan" comment="No way!"/>
        </FXCollections>
    </items>
</TableView>

TableView in FXML

Augur answered 22/12, 2017 at 18:57 Comment(1)
They were available before, see docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/… . Also the section ** lists a lot more ways to create instances than fx:factory/fx:value. In fact you do use one of these possibilities in the last code snippet. Also doing this you can be sure that you break any separation between model and view...Normie

© 2022 - 2024 — McMap. All rights reserved.