JavaFx: can data binding (textfield) be used in production mode?
Tom Schindl
tom.schindl at bestsolution.at
Sat Jun 13 14:10:13 UTC 2015
In the given sample the adapter is a local variable and hence it is garbage collected at some point in time and because javafx bindings are implemented with weaklisteners (see the javadoc) it will stop updateing your Bean!
So it works as designed and your code is simply wrong!
Tom
Von meinem iPhone gesendet
> Am 13.06.2015 um 14:32 schrieb Александр Свиридов <ooo_saturn7 at mail.ru>:
>
> I use java 8.0.45. I have implemented my first javafx application (very simple) with data binding. However, biding from user input-> pojo seems to work with bugs. I've checked about 200 times. I entered new values in text fields and after that I checked model values. The same code, the same my behaviour. Sometimes everything works fine (in most cases - about 80-90%) sometimes model value!=textfield value. I've noticed the following. Data binding for some certain text field works,works and then at some point of time that binding stops working and all new values for this certain textfield are not passed to model. Nor exceptions. Nor any warnings. Nothing. Just binding doesn't work.
> I have 4 textfiled which are created via fxml. Two for string model type. One for integer. One for bigdecimal. The problem happens to all these fields(sometimes to one, sometimes to several). As my number fields can have null values, I use for example PropertyObject but not IntegerProperty (people from openjfx advised so).
> So is this JavaFx bug or what? P.S. I use felix osgi, weld cdi, and pax - I don't know if it matters...
> My code is the following:
>
> DTO - POJO Model
> 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);
> }
>
> }
> Adapter
> 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 Converter
> 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 ;
> }
> }
> }
> }
> Initializing code
> 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());
More information about the openjfx-dev
mailing list