Is it possible to bind a StringProperty to a POJO's String in JavaFX?

末鹿安然 提交于 2019-11-27 02:58:04

问题


I'm creating an application using JavaFX 2. I intend to isolate the UI from data and logics. Considering that, I have a lot of data objects like this:

public class Entity {
    private String m_Value;
    public Entity(String value) { m_Value = value; }
    public String getValue() { return m_Value; }
    public void setValue(String value) { m_Value = value; }
}

I'm having a hard time creating a binding between the m_Value attribute and the textProperty of a Label, for instance.

Another similar question here suggested people to use JFXtras, however I'm not sure I'm allowed to use that (company restrictions). So I'm trying to find some alternative to that.

My idea would be to use objects to represent all attributes of my data entities, instead of primitive types (int would use Integer and so on). That way, I can take advantage of the pass by reference model of java. Then, in the UI domain, I could create a Property referencing this attribute. But I'm not sure whether this is possible or not.

It it possible to solve this problem using the ObjectProperty class?

Another alternative could be using the JavaBeanProperty family of classes, like JavaBeanStringPropertyBuilder, JavaBeanIntegerPropertyBuilder. Is it possible?

I've tried both ways, but I'm affraid I'm not that experienced in JavaFX yet to solve this. Can anyone help?

I don't want to use StringProperty or IntegerProperty inside my data objects because I don't want any JavaFX dependencies in this package. There is a strong possibility this application becomes an Eclipse plugin and probably JavaFX would be off. This way I can avoid too much rework in the future.

Thanks very much.


回答1:


You can obviously set the values in Entity without doing anything except using a listener in JavaFX. If you want to go the other way you can add java.beans.PropertyChangeSupport. It's not in a javafx package.

package bindpojo;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class BindPojo extends Application {
    StringProperty fxString = new SimpleStringProperty();
    StringProperty tmpString = new SimpleStringProperty();

    @Override
    public void start(Stage primaryStage) {
        VBox vbox = new VBox();
        TextField text = new TextField();
        Label label1 = new Label();
        Label label2 = new Label();
        Entity entity = new Entity("");
        vbox.getChildren().addAll(text,label1,label2);
        Scene scene = new Scene(vbox, 300, 200);
        primaryStage.setScene(scene);
        primaryStage.show();

        fxString.bindBidirectional(text.textProperty());

        fxString.addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                entity.setValue(newValue);
                label1.setText(entity.getValue());
            }
        });

        entity.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                tmpString.set(evt.getNewValue().toString());
            }
        });

        label2.textProperty().bind(tmpString);
    }

    public class Entity {
    private String m_Value;
    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    public Entity(String value) { m_Value = value; }
    public String getValue() { return m_Value; }
    public void setValue(String value) {
        pcs.firePropertyChange("m_Value", m_Value, value);
        m_Value = value;
    }
    public void addPropertyChangeListener(PropertyChangeListener listener) {
                    pcs.addPropertyChangeListener(listener);
                }
    }
}

You don't really need the tmpString, I just used used it in case you want to have Entity resemble a javafx string property. You could just set the label in the property change listener instead of setting a string property and then binding to it.



来源:https://stackoverflow.com/questions/22105162/is-it-possible-to-bind-a-stringproperty-to-a-pojos-string-in-javafx

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!