javafx Instance creation in FXML


Example

The following class is used to demonstrate, how instances of classes can be created:

JavaFX 8

The annotation in Person(@NamedArg("name") String name) has to be removed, since the @NamedArg annotation is unavailable.

package fxml.sample;

import javafx.beans.NamedArg;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Person {

    public static final Person JOHN = new Person("John");

    public Person() {
        System.out.println("Person()");
    }
    
    public Person(@NamedArg("name") String name) {
        System.out.println("Person(String)");
        this.name.set(name);
    }
    
    public Person(Person person) {
        System.out.println("Person(Person)");
        this.name.set(person.getName());
    }

    private final StringProperty name = new SimpleStringProperty();

    public final String getName() {
        System.out.println("getter");
        return this.name.get();
    }

    public final void setName(String value) {
        System.out.println("setter");
        this.name.set(value);
    }

    public final StringProperty nameProperty() {
        System.out.println("property getter");
        return this.name;
    }
    
    public static Person valueOf(String value) {
        System.out.println("valueOf");
        return new Person(value);
    }
    
    public static Person createPerson() {
        System.out.println("createPerson");
        return new Person();
    }
    
}

Assume the Person class has already been initialized before loading the fxml.

A note on imports

In the following fxml example the imports section will be left out. However the fxml should start with

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

followed by an imports section importing all classes used in the fxml file. Those imports are similar to non-static imports, but are added as processing instructions. Even classes from the java.lang package need to be imported.

In this case the following imports are should be added:

<?import java.lang.*?>
<?import fxml.sample.Person?>

 

JavaFX 8

@NamedArg annotated constructor

If there is a constructor where every parameter is annotated with @NamedArg and all values of the @NamedArg annotations are present in the fxml, the constructor will be used with those parameters.

<Person name="John"/>
<Person xmlns:fx="http://javafx.com/fxml">
    <name>
        <String fx:value="John"/>
    </name>
</Person>

Both result in the following console output, if loaded:

Person(String)

 

No args constructor

If there is no suitable @NamedArg annotated constructor is available, the constructor that takes no parameters will be used.

Remove the @NamedArg annotation from the constructor and try loading.

<Person name="John"/>

This will use the constructor without parameters.

Output:

Person()
setter

 

fx:value attribute

The fx:value attribute can be used to pass it's value to a static valueOf method taking a String parameter and returning the instance to use.

Example

<Person xmlns:fx="http://javafx.com/fxml" fx:value="John"/>

Output:

valueOf
Person(String)

 

fx:factory

The fx:factory attribute allows creation of objects using arbitrary static methods that do not take parameters.

Example

<Person xmlns:fx="http://javafx.com/fxml" fx:factory="createPerson">
    <name>
        <String fx:value="John"/>
    </name>
</Person>

Output:

createPerson
Person()
setter

 

<fx:copy>

Using fx:copy a copy constructor can be invoked. Specifying the fx:id of another The source attribute of the tag will invoke the copy constructor with that object as parameter.

Example:

<ArrayList xmlns:fx="http://javafx.com/fxml">
    <Person fx:id="p1" fx:constant="JOHN"/>
    <fx:copy source="p1"/>
</ArrayList>

Output

Person(Person)
getter

 

fx:constant

fx:constant allows getting a value from a static final field.

Example

<Person xmlns:fx="http://javafx.com/fxml" fx:constant="JOHN"/>

won't produce any output, since this just references JOHN which was created when initializing the class.