我有一个经典的JavaBean,它将与JavaFX TextField绑定。Javafx中的双向绑定StringProperty不能反向工作
public class Cell {
public static final String CELL_VALUE = "Cell.Value";
private Optional<Integer> value;
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public Optional<Integer> getValue() {
return value;
}
public void setValue(Optional<Integer> value) {
Optional<Integer> old = this.value;
this.value = value;
this.pcs.firePropertyChange(CELL_VALUE, old, value);
}
/**
* The values must be from 1 to 9. 0 or null will be converted to Option.none.
*/
public void setValue(int value) {
this.setValue(Optional.of(value));
}
}
另外我创建了一个字符串转换子类:
import java.util.Optional;
import javafx.util.StringConverter;
public class CellValueStringConverter extends StringConverter<Optional<Integer>> {
@Override
public String toString(Optional<Integer> value) {
System.out.printf("toString() : %s%n", value);
return value.isPresent()? String.valueOf(value.get()): "";
}
@Override
public Optional<Integer> fromString(String string) {
System.out.printf("fromString() : %s%n", string);
if(string.matches("^[1-9]$")) {
return Optional.of(Integer.valueOf(string));
}
if(string.isEmpty() || string.matches("^(|0)$")) {
return Optional.empty();
}
throw new IllegalArgumentException("Illegal value for a Cell: " + string);
}
}
在控制器类,前主级变得可见,我发细胞值和TextField之间的结合:
ObjectProperty<Optional<Integer>> valueProperty = JavaBeanObjectPropertyBuilder.create().bean(cell)
.name("value").build();
final StringProperty textProperty = textField.textProperty();
// Binding ...
textProperty.bindBidirectional(valueProperty, new CellValueStringConverter());
textField.addEventFilter(MouseEvent.MOUSE_CLICKED, me -> {
if (me.getClickCount() == 2) {
cell.setValue(random.nextInt(8) + 1);
}
});
textProperty.addListener(
(ov, oldValue, newValue) -> System.out.printf("textProperty : %s -> %s%n", oldValue, newValue));
valueProperty.addListener(
(ov, oldValue, newValue) -> System.out.printf("valueProperty: %s -> %s%n", oldValue, newValue));
cell.addPropertyChangeListener(
evt -> System.out.printf("cell : %s -> %s%n", evt.getOldValue(), evt.getNewValue()));
当我开始申请时,我收到消息toString() : Optional.empty
。当我输入一个值(比方说,“4”)在一个空的文本字段,这些信息将显示:
fromString() : 4
cell : Optional.empty -> Optional[4]
valueProperty: Optional.empty -> Optional[4]
textProperty : -> 4
如果键入“8”,在此TextField我得到这个:
fromString() :
cell : Optional[4] -> Optional.empty
valueProperty: Optional[4] -> Optional.empty
textProperty : 4 ->
fromString() : 8
cell : Optional.empty -> Optional[8]
valueProperty: Optional.empty -> Optional[8]
textProperty : -> 8
最后,如果我输入“0”,单元格将变为空:
fromString() :
cell : Optional[8] -> Optional.empty
valueProperty: Optional[8] -> Optional.empty
textProperty : 8 ->
到目前为止,这么好。但是,如果双击TextField,而不是替换文本,则什么都不会发生。假设单元格的值(和texfField)为4。当我双击,我得到这个消息:
cell : Optional[4] -> Optional[8]
然而,文本框会继续带出“4”。未显示CellValueStringConverter.toString()
中的消息。
假设,当我将单元格值包装在ObjectProperty
(JavaBeanObjectPropertyBuilder.create().bean(cell).name("value").build()
)中时,它应该观察值属性中的所有更改。但是没有发生。这里缺少什么?
感谢,
拉斐尔·阿丰索