设置属性

有多种方法可以在 fxml 中向对象添加数据:

<property> 标签

可以将具有属性名称的标记添加为用于创建实例的元素的子标记。此标记的子项使用 setter 分配给属性或添加到属性的内容(只读列表/映射属性)。

默认属性

可以使用 @DefaultProperty 注释来注释类。在这种情况下,元素可以直接添加为子元素,而不使用具有属性名称的元素。

property="value" 属性

可以使用属性名称作为属性名称并将值作为属性值来指定属性。这与将以下元素添加为标记的子元素具有相同的效果:

<property>
    <String fx:value="value" />
</property>

静态 setter

也可以使用 static setter 设置属性。这些是名为 setPropertystatic 方法,它将元素作为第一个参数,将值设置为第二个参数。这些方法可以在任何类中进行,并且可以使用 ContainingClass.property 而不是通常的属性名称来使用。

注意: 目前似乎有必要使用相应的静态 getter 方法(即名为 getProperty 的静态方法,将元素作为与静态 setter 相同的类中的参数),除非值类型为 String

类型强制

以下机制用于在赋值期间获取正确类的对象,例如,以适合 setter 方法的参数类型。

如果类是可分配的,则使用值本身。

否则,该值转换如下

目标类型 使用价值(来源价值 s
Booleanboolean Boolean.valueOf(s)
charCharacter s.toString.charAt(0)
其他原始类型或包装类型 适用于目标类型的方法,如果 sNumber,则 valueOf(s.toString()) 为包装类型,否则
BigInteger BigInteger.valueOf(s.longValue())sNumbernew BigInteger(s.toString()) 否则
BigDecimal BigDecimal.valueOf(s.doubleValue())sNumbernew BigDecimal(s.toString()) 否则
Number Double.valueOf(s.toString()) 如果 s.toString() 包含 .,则 Long.valueOf(s.toString()) 否则
Class Class.forName(s.toString()) 使用当前线程的上下文 ClassLoader 调用而不初始化类
enum valueOf 方法的结果,如果 s 是以小写字母开头的 String,则另外转换为全部大写的 String,由每个大写字母前插入的 _ 分隔。
other targetType 中 static valueOf 方法返回的值,其参数与 s 的类型或该类型的超类相匹配

注意: 此行为没有详细记录,可能会有所变化。

public enum Location {
    WASHINGTON_DC,
    LONDON;
}
package fxml.sample;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.beans.DefaultProperty;

@DefaultProperty("items")
public class Sample {
    
    private Location loaction;

    public Location getLoaction() {
        return loaction;
    }

    public void setLoaction(Location loaction) {
        this.loaction = loaction;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
    
    int number;

    private final List<Object> items = new ArrayList<>();

    public List<Object> getItems() {
        return items;
    }
    
    private final Map<String, Object> map = new HashMap<>();

    public Map<String, Object> getMap() {
        return map;
    }
    
    private BigInteger serialNumber;

    public BigInteger getSerialNumber() {
        return serialNumber;
    }

    public void setSerialNumber(BigInteger serialNumber) {
        this.serialNumber = serialNumber;
    }

    @Override
    public String toString() {
        return "Sample{" + "loaction=" + loaction + ", number=" + number + ", items=" + items + ", map=" + map + ", serialNumber=" + serialNumber + '}';
    }
    
}
package fxml.sample;

public class Container {

    public static int getNumber(Sample sample) {
        return sample.number;
    }

    public static void setNumber(Sample sample, int number) {
        sample.number = number;
    }

    private final String value;

    private Container(String value) {
        this.value = value;
    }

    public static Container valueOf(String s) {
        return new Container(s);
    }

    @Override
    public String toString() {
        return "42" + value;
    }

}

打印加载以下 fxml 文件的结果

Sample{loaction=WASHINGTON_DC, number=5, items=[42a, 42b, 42c, 42d, 42e, 42f], map={answer=42, g=9.81, hello=42A, sample=Sample{loaction=null, number=33, items=[], map={}, serialNumber=null}}, serialNumber=4299}
<?xml version="1.0" encoding="UTF-8"?>

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

<Sample xmlns:fx="http://javafx.com/fxml/1" Container.number="5" loaction="washingtonDc">
    
    <!-- set serialNumber property (type coercion) -->
    <serialNumber>
        <Container fx:value="99"/>
    </serialNumber>
    
    <!-- Add elements to default property-->
    <Container fx:value="a"/>
    <Container fx:value="b"/>
    <Container fx:value="c"/>
    <Container fx:value="d"/>
    <Container fx:value="e"/>
    <Container fx:value="f"/>
    
    <!-- fill readonly map property -->
    <map g="9.81">
        <hello>
            <Container fx:value="A"/>
        </hello>
        <answer>
            <Container fx:value=""/>
        </answer>
        <sample>
            <Sample>
                <!-- static setter-->
                <Container.number>
                    <Integer fx:value="33" />
                </Container.number>
            </Sample>
        </sample>
    </map>
</Sample>