JavaFX属性和绑定02
对于简单的包装类型,JavaFX针对性地提供了对应的Property,如StringProperty、IntegerProperty等。但在实际的业务场景中,我们还需要处理一些自定义数据类型、一对一、一对多关系等。在JavaFx中,可以使用ObjectProperty和ListProperty来实现。
ObjectProperty可以用于实现复杂对象的一对一关系,ListProperty可以用于实现复杂对象的一对多关系。
这是最常见的数据结构(Java Bean/POJO),对应数据库表。
指一个业务实体中,除了一些简单类型的属性外,还拥有以1:1、1:n方式关联的其它业务实体。即MyBatis中的association和collection。
聚合可以是一主一子、一主多子、多主一子、多主多子、多主等形式。
指两个业务实体之间存在的交叉引用关系。例如,用户实体和角色实体。一个用户可以拥有多个角色,一个角色也可以分配给多个用户。多对多关系一般使用一张独立的表来保存为种关系。
数据库物理模型中,必须有上级节点、是否末级,这两个字段是用于构造树形结构。可选“当前层级”、“当前层级顺序”字段,用于数据排序。 元数据信息中,需要指定唯一排序字段,用于在没有指定“当前层级”、“当前层级顺序”时进行排序。
既要展现方便,如枚举、参照等信息,在UI中要显示为业务人员能够看懂的信息,而不是主键、编码等没有业务意义的信息。 又要数据库设计结构合理,满足或基本满足数据库第三范式的要求。如不能在集团基本信息表中,保存“国家地区”的编码、名称等信息。 还要满足效率尽量优化、性能尽量高、资源占用尽量少等性能要求。要尽量减少访问数据库的次数,减少构造复杂结构的对象。
其中包含JavaFX的包装类型、新的日期时间类型、自定义枚举类型、参照类型、List类型等。
private String testCode;
private String testName;
private Byte testByte;
private Short testShort;
private Long testLong;
private Boolean testBoolean;
private LocalTime testTime;
private LocalDateTime testDateTime;
// 自定义枚举类型
private ValueObjectStatusEnum valueObjectStatus;
private Integer testInteger;
private BigDecimal testDecimal;
private LocalDate testDate;
// 自定义参照类型
private UserReferenceVO pkUser;
// List
private List<SubVO> listChild = new ArrayList<>();
public Integer getTestInteger() {
return testInteger;
}
public void setTestInteger(Integer testInteger) {
Integer oldValue = getTestInteger();
this.testInteger = testInteger;
firePropertyChange("testInteger", oldValue, testInteger);
}
/**
* 属性值变化监听器,用于在javaFX体系下监听属性值的变化,实现双向监听,以保证FXVO和VO中的属性值的一致性
* 该监听器的作用非常重要。所有需要使用FX体系进行包装的VO,在setter中,都必须使用本监听器通知FX来感知属性值的变化。
* <p>
* {@link com.lirong.eap.platform.metadata.pub.vo.PropertyVO}
*/
@DiffIgnore
protected final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
/**
* 属性变化事件
*
* @param propertyName 属性名称
* @param oldValue 原值
* @param newValue 新值
*/
public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
用于前台界面进行数据处理。由于JavaFX Property不支持序列化机制,所以只能从后台接受Bean,然后封装为JavaFX Bean供前台使用。
private TestVO testVO;
private StringProperty testCode;
private StringProperty testName;
private ObjectProperty<Byte> testByte;
private ObjectProperty<Short> testShort;
private ObjectProperty<Long> testLong;
private ObjectProperty<Boolean> testBoolean;
private ObjectProperty<LocalTime> testTime;
private ObjectProperty<LocalDateTime> testDateTime;
// 自定义枚举类型
private ObjectProperty<ValueObjectStatusEnum> valueObjectStatus;
private ObjectProperty<Integer> testInteger;
private ObjectProperty<BigDecimal> testDecimal;
private ObjectProperty<LocalDate> testDate;
// 自定义参照类型
private ObjectProperty<UserReferenceVO> pkUser;
// List
private ListProperty<SubFXVO> listChild;
FXVO的构造器,应以VO为参数,以便于获取VO传递给后台。
public TestFXVO(TestVO testVO) {
super();
setTestVO(testVO);
initProperty();
}
protected void initProperty() {
try {
// 简单对象
testCode = JavaBeanStringPropertyBuilder.create().bean(this.testVO).name("testCode").build();
testName = JavaBeanStringPropertyBuilder.create().bean(this.testVO).name("testName").build();
testInteger = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("testInteger").build();
testDecimal = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("testDecimal").build();
testDate = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("testDate").build();
testByte = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("testByte").build();
testShort = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("testShort").build();
testLong = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("testLong").build();
testBoolean = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("testBoolean").build();
testTime = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("testTime").build();
testDateTime = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("testDateTime").build();
valueObjectStatus = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("valueObjectStatus").build();
// 参照
pkUser = JavaBeanObjectPropertyBuilder.create().bean(this.testVO).name("pkUser").build();
listChild = new SimpleListProperty<>(FXCollections.observableArrayList());
// vo -> fxvo
getValueObject().getListChild().forEach(vo -> getListChild().add(new SubFXVO(vo)));
// fxvo -> vo
listChild.addListener((ListChangeListener<SubFXVO>) change -> {
while (change.next()) {
if (change.wasAdded()) {
for (SubFXVO subFXVO : change.getAddedSubList()) {
getValueObject().getListChild().add(subFXVO.getValueObject());
}
} else if (change.wasRemoved()) {
for (SubFXVO subFXVO : change.getRemoved()) {
getValueObject().getListChild().remove(subFXVO.getValueObject());
}
}
}
});
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
注意对List类型属性的处理方式。
/**
* 验证Bean FXBean的简单属性能够实现双向绑定
*/
@Test
public void testSimpleProperty() {
// bean
TestVO testVO = new TestVO(100);
// fx bean
TestFXVO testFXVO = new TestFXVO(testVO);
System.out.println("初始值:");
System.out.println(" Bean:" + testVO);
System.out.println("FX Bean:" + testFXVO);
System.out.println();
// 修改Bean简单属性,看FX Bean是否自动更新
System.out.println("修改Bean简单属性,看FX Bean是否自动更新:");
System.out.println(String.format(" Bean修改前的值:TestCode=%s, TestInteger=%s.", testVO.getTestCode(), testVO.getTestInteger()));
System.out.println(String.format("FX Bean修改前的值:TestCode=%s, TestInteger=%s.", testFXVO.getTestCode(), testFXVO.getTestInteger()));
testVO.setTestCode("112233");
testVO.setTestInteger(22);
System.out.println(String.format(" Bean修改后的值:TestCode=%s, TestInteger=%s.", testVO.getTestCode(), testVO.getTestInteger()));
System.out.println(String.format("FX Bean修改后的值:TestCode=%s, TestInteger=%s.", testFXVO.getTestCode(), testFXVO.getTestInteger()));
System.out.println();
// 修改FX Bean简单属性,看Bean是否自动更新
System.out.println("修改FX Bean简单属性,看Bean是否自动更新:");
System.out.println(String.format(" Bean修改前的值:TestDecimal=%s, TestDate=%s.", testVO.getTestDecimal(), testVO.getTestDate()));
System.out.println(String.format("FX Bean修改前的值:TestDecimal=%s, TestDate=%s.", testFXVO.getTestDecimal(), testFXVO.getTestDecimal()));
testFXVO.setTestDecimal(new BigDecimal("1234.56"));
testFXVO.setTestDate(LRDateTimeConverterUtil.parserString2Date("2022-02-02"));
System.out.println(String.format(" Bean修改后的值:TestDecimal=%s, TestDate=%s.", testVO.getTestDecimal(), testVO.getTestDate()));
System.out.println(String.format("FX Bean修改后的值:TestDecimal=%s, TestDate=%s.", testFXVO.getTestDecimal(), testFXVO.getTestDecimal()));
}
初始值:
Bean:TestVO(testCode=TestCode_100, testName=TestName_100, testByte=63, testShort=69, testLong=5495577966595199609, testBoolean=false, testTime=13:26:35.650443400, testDateTime=2021-11-11T11:11:11, valueObjectStatus=NORMAL, testInteger=100, testDecimal=2.5E+4, testDate=1999-09-09, pkUser=UserReferenceVO(), listChild=[SubVO(code=SubCode_1, name=SubName_1), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_3, name=SubName_3), SubVO(code=SubCode_4, name=SubName_4), SubVO(code=SubCode_5, name=SubName_5), SubVO(code=SubCode_6, name=SubName_6), SubVO(code=SubCode_7, name=SubName_7), SubVO(code=SubCode_8, name=SubName_8)])
FX Bean:TestFXVO(testVO=TestVO(testCode=TestCode_100, testName=TestName_100, testByte=63, testShort=69, testLong=5495577966595199609, testBoolean=false, testTime=13:26:35.650443400, testDateTime=2021-11-11T11:11:11, valueObjectStatus=NORMAL, testInteger=100, testDecimal=2.5E+4, testDate=1999-09-09, pkUser=UserReferenceVO(), listChild=[SubVO(code=SubCode_1, name=SubName_1), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_3, name=SubName_3), SubVO(code=SubCode_4, name=SubName_4), SubVO(code=SubCode_5, name=SubName_5), SubVO(code=SubCode_6, name=SubName_6), SubVO(code=SubCode_7, name=SubName_7), SubVO(code=SubCode_8, name=SubName_8)]), testCode=TestCode_100, testName=TestName_100, testByte=63, testShort=69, testLong=5495577966595199609, testBoolean=false, testTime=13:26:35.650443400, testDateTime=2021-11-11T11:11:11, valueObjectStatus=NORMAL, testInteger=100, testDecimal=2.5E+4, testDate=1999-09-09, pkUser=UserReferenceVO(), listChild=[SubFXVO(basicVO=SubVO(code=SubCode_1, name=SubName_1), code=SubCode_1, name=SubName_1), SubFXVO(basicVO=SubVO(code=SubCode_2, name=SubName_2), code=SubCode_2, name=SubName_2), SubFXVO(basicVO=SubVO(code=SubCode_3, name=SubName_3), code=SubCode_3, name=SubName_3), SubFXVO(basicVO=SubVO(code=SubCode_4, name=SubName_4), code=SubCode_4, name=SubName_4), SubFXVO(basicVO=SubVO(code=SubCode_5, name=SubName_5), code=SubCode_5, name=SubName_5), SubFXVO(basicVO=SubVO(code=SubCode_6, name=SubName_6), code=SubCode_6, name=SubName_6), SubFXVO(basicVO=SubVO(code=SubCode_7, name=SubName_7), code=SubCode_7, name=SubName_7), SubFXVO(basicVO=SubVO(code=SubCode_8, name=SubName_8), code=SubCode_8, name=SubName_8)])
修改Bean简单属性,看FX Bean是否自动更新:
Bean修改前的值:TestCode=TestCode_100, TestInteger=100.
FX Bean修改前的值:TestCode=TestCode_100, TestInteger=100.
Bean修改后的值:TestCode=112233, TestInteger=22.
FX Bean修改后的值:TestCode=112233, TestInteger=22.
修改FX Bean简单属性,看Bean是否自动更新:
Bean修改前的值:TestDecimal=2.5E+4, TestDate=1999-09-09.
FX Bean修改前的值:TestDecimal=2.5E+4, TestDate=2.5E+4.
Bean修改后的值:TestDecimal=1234.56, TestDate=2022-02-02.
FX Bean修改后的值:TestDecimal=1234.56, TestDate=1234.56.
Process finished with exit code 0
可以看出,Bean、FX Bean中的属性,实现了双向绑定。
/**
* 以List为例,验证Bean FXBean的复杂属性能够实现双向绑定
*/
@Test
public void testListProperty() {
// bean
TestVO testVO = new TestVO(100);
// fx bean
TestFXVO testFXVO = new TestFXVO(testVO);
// 从bean的list属性中,移除一个元素,看fx bean是否同步更新
System.out.println("从bean的list属性中,移除一个元素,看fx bean是否同步更新:");
System.out.println(String.format(" Bean List修改前:大小=%s,信息=%s", testVO.getListChild().size(), testVO.getListChild()));
System.out.println(String.format("FX Bean List修改前:大小=%s,信息=%s", testFXVO.getListChild().size(), testFXVO.getListChild()));
testVO.getListChild().remove(2);
System.out.println(String.format(" Bean List修改后:大小=%s,信息=%s", testVO.getListChild().size(), testVO.getListChild()));
System.out.println(String.format("FX Bean List修改后:大小=%s,信息=%s", testFXVO.getListChild().size(), testFXVO.getListChild()));
System.out.println();
// 从fx bean的list属性中,移除一个元素,看bean是否同步更新
testVO = new TestVO(200);
testFXVO = new TestFXVO(testVO);
System.out.println("从fx bean的list属性中,移除一个元素,看bean是否同步更新:");
System.out.println(String.format(" Bean List修改前:大小=%s,信息=%s", testVO.getListChild().size(), testVO.getListChild()));
System.out.println(String.format("FX Bean List修改前:大小=%s,信息=%s", testFXVO.getListChild().size(), testFXVO.getListChild()));
testFXVO.getListChild().remove(3);
System.out.println(String.format(" Bean List修改后:大小=%s,信息=%s", testVO.getListChild().size(), testVO.getListChild()));
System.out.println(String.format("FX Bean List修改后:大小=%s,信息=%s", testFXVO.getListChild().size(), testFXVO.getListChild()));
System.out.println();
// 在bean中修改、增加元素
testVO = new TestVO(300);
testFXVO = new TestFXVO(testVO);
System.out.println("在bean中修改、增加元素:");
System.out.println(String.format(" Bean List修改前:大小=%s,信息=%s", testVO.getListChild().size(), testVO.getListChild()));
System.out.println(String.format("FX Bean List修改前:大小=%s,信息=%s", testFXVO.getListChild().size(), testFXVO.getListChild()));
testVO.getListChild().add(0, new SubVO(300));
testVO.getListChild().get(1).setName("Name_300");
testVO.getListChild().get(1).setCode("Code_300");
System.out.println(String.format(" Bean List修改后:大小=%s,信息=%s", testVO.getListChild().size(), testVO.getListChild()));
System.out.println(String.format("FX Bean List修改后:大小=%s,信息=%s", testFXVO.getListChild().size(), testFXVO.getListChild()));
System.out.println();
// 在fx bean中,移除、增加、修改参数
testVO = new TestVO(400);
testFXVO = new TestFXVO(testVO);
System.out.println("在fx bean中,移除、增加、修改参数:");
System.out.println(String.format(" Bean List修改前:大小=%s,信息=%s", testVO.getListChild().size(), testVO.getListChild()));
System.out.println(String.format("FX Bean List修改前:大小=%s,信息=%s", testFXVO.getListChild().size(), testFXVO.getListChild()));
testFXVO.getListChild().add(0, new SubFXVO(new SubVO(400)));
testFXVO.getListChild().remove(3);
testFXVO.getListChild().remove(4);
testFXVO.getListChild().get(1).setName("Name_400");
testFXVO.getListChild().get(1).setCode("Code_400");
System.out.println(String.format(" Bean List修改后:大小=%s,信息=%s", testVO.getListChild().size(), testVO.getListChild()));
System.out.println(String.format("FX Bean List修改后:大小=%s,信息=%s", testFXVO.getListChild().size(), testFXVO.getListChild()));
System.out.println();
}
1、从bean的list属性中,移除一个元素,看fx bean是否同步更新:
Bean List修改前:大小=5,信息=[SubVO(code=SubCode_1, name=SubName_1), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_3, name=SubName_3), SubVO(code=SubCode_4, name=SubName_4), SubVO(code=SubCode_5, name=SubName_5)]
FX Bean List修改前:大小=5,信息=[SubFXVO(basicVO=SubVO(code=SubCode_1, name=SubName_1), code=SubCode_1, name=SubName_1), SubFXVO(basicVO=SubVO(code=SubCode_2, name=SubName_2), code=SubCode_2, name=SubName_2), SubFXVO(basicVO=SubVO(code=SubCode_3, name=SubName_3), code=SubCode_3, name=SubName_3), SubFXVO(basicVO=SubVO(code=SubCode_4, name=SubName_4), code=SubCode_4, name=SubName_4), SubFXVO(basicVO=SubVO(code=SubCode_5, name=SubName_5), code=SubCode_5, name=SubName_5)]
Bean List修改后:大小=4,信息=[SubVO(code=SubCode_1, name=SubName_1), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_4, name=SubName_4), SubVO(code=SubCode_5, name=SubName_5)]
FX Bean List修改后:大小=5,信息=[SubFXVO(basicVO=SubVO(code=SubCode_1, name=SubName_1), code=SubCode_1, name=SubName_1), SubFXVO(basicVO=SubVO(code=SubCode_2, name=SubName_2), code=SubCode_2, name=SubName_2), SubFXVO(basicVO=SubVO(code=SubCode_3, name=SubName_3), code=SubCode_3, name=SubName_3), SubFXVO(basicVO=SubVO(code=SubCode_4, name=SubName_4), code=SubCode_4, name=SubName_4), SubFXVO(basicVO=SubVO(code=SubCode_5, name=SubName_5), code=SubCode_5, name=SubName_5)]
2、从fx bean的list属性中,移除一个元素,看bean是否同步更新:
Bean List修改前:大小=9,信息=[SubVO(code=SubCode_1, name=SubName_1), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_3, name=SubName_3), SubVO(code=SubCode_4, name=SubName_4), SubVO(code=SubCode_5, name=SubName_5), SubVO(code=SubCode_6, name=SubName_6), SubVO(code=SubCode_7, name=SubName_7), SubVO(code=SubCode_8, name=SubName_8), SubVO(code=SubCode_9, name=SubName_9)]
FX Bean List修改前:大小=9,信息=[SubFXVO(basicVO=SubVO(code=SubCode_1, name=SubName_1), code=SubCode_1, name=SubName_1), SubFXVO(basicVO=SubVO(code=SubCode_2, name=SubName_2), code=SubCode_2, name=SubName_2), SubFXVO(basicVO=SubVO(code=SubCode_3, name=SubName_3), code=SubCode_3, name=SubName_3), SubFXVO(basicVO=SubVO(code=SubCode_4, name=SubName_4), code=SubCode_4, name=SubName_4), SubFXVO(basicVO=SubVO(code=SubCode_5, name=SubName_5), code=SubCode_5, name=SubName_5), SubFXVO(basicVO=SubVO(code=SubCode_6, name=SubName_6), code=SubCode_6, name=SubName_6), SubFXVO(basicVO=SubVO(code=SubCode_7, name=SubName_7), code=SubCode_7, name=SubName_7), SubFXVO(basicVO=SubVO(code=SubCode_8, name=SubName_8), code=SubCode_8, name=SubName_8), SubFXVO(basicVO=SubVO(code=SubCode_9, name=SubName_9), code=SubCode_9, name=SubName_9)]
Bean List修改后:大小=8,信息=[SubVO(code=SubCode_1, name=SubName_1), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_3, name=SubName_3), SubVO(code=SubCode_5, name=SubName_5), SubVO(code=SubCode_6, name=SubName_6), SubVO(code=SubCode_7, name=SubName_7), SubVO(code=SubCode_8, name=SubName_8), SubVO(code=SubCode_9, name=SubName_9)]
FX Bean List修改后:大小=8,信息=[SubFXVO(basicVO=SubVO(code=SubCode_1, name=SubName_1), code=SubCode_1, name=SubName_1), SubFXVO(basicVO=SubVO(code=SubCode_2, name=SubName_2), code=SubCode_2, name=SubName_2), SubFXVO(basicVO=SubVO(code=SubCode_3, name=SubName_3), code=SubCode_3, name=SubName_3), SubFXVO(basicVO=SubVO(code=SubCode_5, name=SubName_5), code=SubCode_5, name=SubName_5), SubFXVO(basicVO=SubVO(code=SubCode_6, name=SubName_6), code=SubCode_6, name=SubName_6), SubFXVO(basicVO=SubVO(code=SubCode_7, name=SubName_7), code=SubCode_7, name=SubName_7), SubFXVO(basicVO=SubVO(code=SubCode_8, name=SubName_8), code=SubCode_8, name=SubName_8), SubFXVO(basicVO=SubVO(code=SubCode_9, name=SubName_9), code=SubCode_9, name=SubName_9)]
3、在bean中修改、增加元素:
Bean List修改前:大小=6,信息=[SubVO(code=SubCode_1, name=SubName_1), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_3, name=SubName_3), SubVO(code=SubCode_4, name=SubName_4), SubVO(code=SubCode_5, name=SubName_5), SubVO(code=SubCode_6, name=SubName_6)]
FX Bean List修改前:大小=6,信息=[SubFXVO(basicVO=SubVO(code=SubCode_1, name=SubName_1), code=SubCode_1, name=SubName_1), SubFXVO(basicVO=SubVO(code=SubCode_2, name=SubName_2), code=SubCode_2, name=SubName_2), SubFXVO(basicVO=SubVO(code=SubCode_3, name=SubName_3), code=SubCode_3, name=SubName_3), SubFXVO(basicVO=SubVO(code=SubCode_4, name=SubName_4), code=SubCode_4, name=SubName_4), SubFXVO(basicVO=SubVO(code=SubCode_5, name=SubName_5), code=SubCode_5, name=SubName_5), SubFXVO(basicVO=SubVO(code=SubCode_6, name=SubName_6), code=SubCode_6, name=SubName_6)]
Bean List修改后:大小=7,信息=[SubVO(code=SubCode_300, name=SubName_300), SubVO(code=Code_300, name=Name_300), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_3, name=SubName_3), SubVO(code=SubCode_4, name=SubName_4), SubVO(code=SubCode_5, name=SubName_5), SubVO(code=SubCode_6, name=SubName_6)]
FX Bean List修改后:大小=6,信息=[SubFXVO(basicVO=SubVO(code=Code_300, name=Name_300), code=Code_300, name=Name_300), SubFXVO(basicVO=SubVO(code=SubCode_2, name=SubName_2), code=SubCode_2, name=SubName_2), SubFXVO(basicVO=SubVO(code=SubCode_3, name=SubName_3), code=SubCode_3, name=SubName_3), SubFXVO(basicVO=SubVO(code=SubCode_4, name=SubName_4), code=SubCode_4, name=SubName_4), SubFXVO(basicVO=SubVO(code=SubCode_5, name=SubName_5), code=SubCode_5, name=SubName_5), SubFXVO(basicVO=SubVO(code=SubCode_6, name=SubName_6), code=SubCode_6, name=SubName_6)]
4、在fx bean中,移除、增加、修改参数:
Bean List修改前:大小=9,信息=[SubVO(code=SubCode_1, name=SubName_1), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_3, name=SubName_3), SubVO(code=SubCode_4, name=SubName_4), SubVO(code=SubCode_5, name=SubName_5), SubVO(code=SubCode_6, name=SubName_6), SubVO(code=SubCode_7, name=SubName_7), SubVO(code=SubCode_8, name=SubName_8), SubVO(code=SubCode_9, name=SubName_9)]
FX Bean List修改前:大小=9,信息=[SubFXVO(basicVO=SubVO(code=SubCode_1, name=SubName_1), code=SubCode_1, name=SubName_1), SubFXVO(basicVO=SubVO(code=SubCode_2, name=SubName_2), code=SubCode_2, name=SubName_2), SubFXVO(basicVO=SubVO(code=SubCode_3, name=SubName_3), code=SubCode_3, name=SubName_3), SubFXVO(basicVO=SubVO(code=SubCode_4, name=SubName_4), code=SubCode_4, name=SubName_4), SubFXVO(basicVO=SubVO(code=SubCode_5, name=SubName_5), code=SubCode_5, name=SubName_5), SubFXVO(basicVO=SubVO(code=SubCode_6, name=SubName_6), code=SubCode_6, name=SubName_6), SubFXVO(basicVO=SubVO(code=SubCode_7, name=SubName_7), code=SubCode_7, name=SubName_7), SubFXVO(basicVO=SubVO(code=SubCode_8, name=SubName_8), code=SubCode_8, name=SubName_8), SubFXVO(basicVO=SubVO(code=SubCode_9, name=SubName_9), code=SubCode_9, name=SubName_9)]
Bean List修改后:大小=8,信息=[SubVO(code=Code_400, name=Name_400), SubVO(code=SubCode_2, name=SubName_2), SubVO(code=SubCode_4, name=SubName_4), SubVO(code=SubCode_6, name=SubName_6), SubVO(code=SubCode_7, name=SubName_7), SubVO(code=SubCode_8, name=SubName_8), SubVO(code=SubCode_9, name=SubName_9), SubVO(code=SubCode_400, name=SubName_400)]
FX Bean List修改后:大小=8,信息=[SubFXVO(basicVO=SubVO(code=SubCode_400, name=SubName_400), code=SubCode_400, name=SubName_400), SubFXVO(basicVO=SubVO(code=Code_400, name=Name_400), code=Code_400, name=Name_400), SubFXVO(basicVO=SubVO(code=SubCode_2, name=SubName_2), code=SubCode_2, name=SubName_2), SubFXVO(basicVO=SubVO(code=SubCode_4, name=SubName_4), code=SubCode_4, name=SubName_4), SubFXVO(basicVO=SubVO(code=SubCode_6, name=SubName_6), code=SubCode_6, name=SubName_6), SubFXVO(basicVO=SubVO(code=SubCode_7, name=SubName_7), code=SubCode_7, name=SubName_7), SubFXVO(basicVO=SubVO(code=SubCode_8, name=SubName_8), code=SubCode_8, name=SubName_8), SubFXVO(basicVO=SubVO(code=SubCode_9, name=SubName_9), code=SubCode_9, name=SubName_9)]
Process finished with exit code 0
-
从bean的list属性中,移除一个元素,看fx bean是否同步更新
可以发现有问题。bean中的list变化时,fx bean无法感知。
-
从fx bean的list属性中,移除一个元素,看bean是否同步更新
fx bean中的list变化时,会处理bean中的数据。
-
在bean中修改、增加元素
同第一种情况,bean中的元素变化时,fx bean无法感知。
-
在fx bean中,移除、增加、修改参数
fx bean中的list变化时,会处理bean中的数据。
- 对于简单类型的属性(String、Integer、BigDecimal等)来说,能够实现bean、fx bean之间的双向绑定
- 对于复杂类型的属性(List、Set等)来说,fx bean会把元素变化传递给bean,而反之则不行