Пользуюсь java 8.0.45. Я реализовал свое первое приложение javafx (очень простое) с привязкой данных. Однако ожидание от пользовательского ввода-> pojo, похоже, работает с ошибками. Проверял около 200 раз. Я ввел новые значения в текстовые поля и после этого проверил значения модели. Тот же код, то же мое поведение. Иногда все работает нормально (в большинстве случаев - около 80-90%) иногда значение модели! = Значение текстового поля. Я заметил следующее. Связывание данных для некоторого определенного текстового поля работает, работает, а затем в какой-то момент эта привязка перестает работать, и все новые значения для этого определенного текстового поля не передаются в модель. Никаких исключений. Никаких предупреждений. Ничего такого. Просто привязка не работает.
У меня есть 4 текстовых файла, которые создаются через fxml. Два для струнного типа модели. Один для целого числа. Один для bigdecimal. Проблема возникает со всеми этими полями (иногда с одним, иногда с несколькими). Поскольку мои числовые поля могут иметь нулевые значения, я использую, например, PropertyObject, но не IntegerProperty (так советовали люди из openjfx).
Так это ошибка JavaFx или что? P.S. Я использую felix osgi, weld cdi и pax - не знаю, имеет ли это значение ...
Мой код следующий:
DTO - модель POJO
public class Task {
private String name;
private Integer order;
private BigDecimal weight;
private String comment;
private final PropertyChangeSupport propertyChangeSupport;
public Task() {
this.propertyChangeSupport = new PropertyChangeSupport(this);
}
public String getName() {
return name;
}
public void setName(String name) {
String pv = this.name ;
this.name = name;
propertyChangeSupport.firePropertyChange("name", pv, name);
}
public Integer getOrder() {
return order;
}
public void setOrder(Integer order) {
Integer pv = this.order;
this.order = order;
propertyChangeSupport.firePropertyChange("order", pv, this.order);
}
public BigDecimal getWeight() {
return weight;
}
public void setWeight(BigDecimal weight) {
BigDecimal pv = this.weight;
this.weight = weight;
propertyChangeSupport.firePropertyChange("weight", pv, weight);
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
String pv = this.comment;
this.comment = comment;
propertyChangeSupport.firePropertyChange("comment", pv, this.comment);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
}
Адаптер
public class TaskAdapter {
private StringProperty nameProperty;
private ObjectProperty<Integer> orderProperty;
private ObjectProperty<BigDecimal> weightProperty;
private StringProperty commentProperty;
public TaskAdapter(Task task) {
try {
nameProperty=new JavaBeanStringPropertyBuilder().bean(task).name("name").build();
orderProperty=new JavaBeanObjectPropertyBuilder<Integer>().bean(task).name("order").build();
weightProperty=new JavaBeanObjectPropertyBuilder<BigDecimal>().bean(task).name("weight").build();
commentProperty=new JavaBeanStringPropertyBuilder().bean(task).name("comment").build();
} catch (NoSuchMethodException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
}
public StringProperty getNameProperty() {
return nameProperty;
}
public ObjectProperty<Integer> getOrderProperty() {
return orderProperty;
}
public ObjectProperty<BigDecimal> getWeightProperty() {
return weightProperty;
}
public StringProperty getCommentProperty() {
return commentProperty;
}
}
Конвертер BigDecimal
public class SimpleBigDecimalStringConverter extends StringConverter<BigDecimal>{
@Override
public String toString(BigDecimal i) {
if (i == null) {
return "" ;
} else {
return i.toString();
}
}
@Override
public BigDecimal fromString(String string) {
if (string.trim().length() == 0) {
return null ;
} else {
try {
return new BigDecimal(string);
} catch (NumberFormatException nfe) {
return null ;
}
}
}
}
IntegerConverter
public class SimpleIntegerStringConverter extends StringConverter<Integer>{
@Override
public String toString(Integer i) {
if (i == null) {
return "" ;
} else {
return i.toString();
}
}
@Override
public Integer fromString(String string) {
if (string.trim().length() == 0) {
return null ;
} else {
try {
return Integer.valueOf(string);
} catch (NumberFormatException nfe) {
return null ;
}
}
}
}
Инициализирующий код
Task task=new Task();
TaskAdapter adapter=new TaskAdapter(task);
nameTextField.textProperty().bindBidirectional(adapter.getNameProperty());
orderTextField.textProperty().bindBidirectional(adapter.getOrderProperty(),new SimpleIntegerStringConverter());
weightTextField.textProperty().bindBidirectional(adapter.getWeightProperty(),new BigDecimalStringConverter());
commentTextField.textProperty().bindBidirectional(adapter.getCommentProperty());