设置属性
有多种方法可以在 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>