設定屬性

有多種方法可以在 fxml 中向物件新增資料:

<property> 標籤

可以將具有屬性名稱的標記新增為用於建立例項的元素的子標記。此標記的子項使用 setter 分配給屬性或新增到屬性的內容(只讀列表/對映屬性)。

預設屬性

可以使用 @DefaultProperty 註釋來註釋類。在這種情況下,元素可以直接新增為子元素,而不使用具有屬性名稱的元素。

property="value" 屬性

可以使用屬性名稱作為屬性名稱並將值作為屬性值來指定屬性。這與將以下元素新增為標記的子元素具有相同的效果:

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

靜態 setter

也可以使用 static setter 設定屬性。這些是名為 setProperty 的 static 方法,它將元素作為第一個引數,將值設定為第二個引數。這些方法可以在任何類中進行,並且可以使用 ContainingClass.property 而不是通常的屬性名稱來使用。

注意: 目前似乎有必要使用相應的靜態 getter 方法(即名為 getProperty 的靜態方法,將元素作為與靜態 setter 相同的類中的引數),除非值型別為 String。

型別強制

以下機制用於在賦值期間獲取正確類的物件,例如,以適合 setter 方法的引數型別。

如果類是可分配的,則使用值本身。

否則,該值轉換如下

目標型別 使用價值(來源價值 s)
Boolean,boolean Boolean.valueOf(s)
char,Character s.toString.charAt(0)
其他原始型別或包裝型別 適用於目標型別的方法,如果 s 是 Number,則 valueOf(s.toString()) 為包裝型別,否則
BigInteger BigInteger.valueOf(s.longValue()) 是 s 是 Number,new BigInteger(s.toString()) 否則
BigDecimal BigDecimal.valueOf(s.doubleValue()) 是 s 是 Number,new 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>