目前,我想做的是使用 JAXB 生成的 POJO 将每个 Java 属性绑定到 JavaFX 组件。为此,我按照以下方式进行:
- 我更改了 JAXB 的默认生成以添加PropertyChangeSupport以使 POJO 支持绑定。
- 我创建了一种工厂,它在输入中获取一个类实例并返回一个 Map,其中键是属性本身,JavaFX 组件的值与属性的值绑定。
- 返回的地图显示在 JFXPanel 中。
这是我工厂的样品:
public static Map<Field, Node> createComponents(Object obj) throws NoSuchMethodException
{
Map<Field, Node> map = new LinkedHashMap<Field, Node>();
for (final Field field : obj.getClass().getDeclaredFields())
{
@SuppressWarnings("rawtypes")
Class fieldType = field.getType();
if (fieldType.equals(boolean.class) || (fieldType.equals(Boolean.class))) //Boolean
{
map.put(field, createBool(obj, field));
}
else if (fieldType.equals(int.class) || (fieldType.equals(Integer.class))) //Integer
{
map.put(field, createInt(obj, field));
}
else if (fieldType.equals(BigInteger.class)) //BigInteger
{
map.put(field, createBigInt(obj, field));
}
else if (fieldType.equals(long.class) || fieldType.equals(Long.class)) //Long
{
map.put(field, createLong(obj, field));
}
else if (fieldType.equals(String.class)) //String
{
map.put(field, createString(obj, field));
}
...
}
return map;
}
public static Node createBool(Object obj, final Field field) throws NoSuchMethodException
{
System.out.println(field.getType().getSimpleName() + " spotted");
JavaBeanBooleanProperty boolProperty = JavaBeanBooleanPropertyBuilder.create().bean(obj).name(field.getName()).build();
boolProperty.addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2)
{
prettyPrinter(field, arg1, arg2);
}
});
CheckBox cb = new CheckBox();
cb.setText(" : " + field.getName());
cb.selectedProperty().bindBidirectional(boolProperty);
return cb;
}
public static Node createInt(Object obj, final Field field) throws NoSuchMethodException
{
System.out.println(field.getType().getSimpleName() + " spotted");
JavaBeanIntegerProperty intProperty = JavaBeanIntegerPropertyBuilder.create().bean(obj).name(field.getName()).build();
StringProperty s = new SimpleStringProperty();
StringConverter sc = new IntegerStringConverter();
Bindings.bindBidirectional(s, intProperty, sc);
s.addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2)
{
prettyPrinter(field, arg1, arg2);
}
});
TextField tf = new TextField();
tf.textProperty().bindBidirectional(s);
return tf;
}
所以,我遇到的问题是:在大多数情况下,例如,当我更改一个 textField 时,POJO 属性不会注意到。但在某些情况下,当我更改 POJO 中字段的顺序时,每个侦听器都会注意到任何更改。
下面是一个 GUI 看起来像跟随Personne类的示例(当前有效)
public class Personne
{
private int taille;
private Boolean lol;
private long pointure;
private BigInteger age;
private boolean zombified;
private String name;
private PropertyChangeSupport _changeSupport = new PropertyChangeSupport(this);
public Boolean getLol()
{
return this.lol;
}
public long getPointure()
{
return this.pointure;
}
public int getTaille()
{
return taille;
}
public boolean getZombified()
{
return zombified;
}
public BigInteger getAge()
{
return age;
}
public String getName()
{
return name;
}
public void setPointure(long pointure)
{
final long prev = this.pointure;
this.pointure = pointure;
_changeSupport.firePropertyChange("pointure", prev, pointure);
}
public void setTaille(int taille)
{
final int prev = this.taille;
this.taille = taille;
_changeSupport.firePropertyChange("taille", prev, taille);
}
public void setAge(BigInteger age)
{
final BigInteger prev = this.age;
this.age = age;
_changeSupport.firePropertyChange("age", prev, age);
}
public void setName(String name)
{
final String prev = this.name;
this.name = name;
_changeSupport.firePropertyChange("name", prev, name);
}
public void setLol(Boolean lol)
{
final Boolean prev = this.lol;
this.lol = lol;
_changeSupport.firePropertyChange("lol", prev, lol);
}
public void setZombified(boolean zombified)
{
final boolean prev = this.zombified;
this.zombified = zombified;
_changeSupport.firePropertyChange("zombified", prev, zombified);
}
public void addPropertyChangeListener(final PropertyChangeListener listener)
{
_changeSupport.addPropertyChangeListener(listener);
}
}
我想知道属性顺序如何影响这样的绑定。此外,我注意到如果我想返回包装在 HBox 中的节点,则绑定不再起作用。
我认为我做错了什么,但我不知道是什么。