【问题标题】:JavaFX: Binding a TextProperty (eg. Label) to a simple IntegerJavaFX:将 TextProperty(例如标签)绑定到简单的整数
【发布时间】:2016-04-05 10:13:36
【问题描述】:

一般问题:当一个简单整数的值发生变化时,有没有办法更新标签?

我说的是简单的 int,而不是像 ReadOnlyIntegerWrappers 这样的东西。我根据Converting Integer to ObservableValue<Integer> in javafx尝试了以下方法 (我不得不将 ObservableValue 的标识符(它叫什么?)从 Integer 更改为 String,因为我找不到将它绑定到 TextProperty 的方法)

我在下面包含了我的演示代码,它似乎在label.textProperty().bind(m.getObsValue()); 处导致了 NullPointerException。该应用程序是用 MVC 模式编写的。

型号:

public class Model {

private int value;
private ObservableValue<String> obsInt;

public Model(){
    value = 5;
    obsInt = new ReadOnlyObjectWrapper<>(value + "");
}

public int getValue(){
    return value;
}

public void setValue(int value){
    this.value = value;
}

public ObservableValue<String> getObsValue(){
    return obsInt;
}
}

控制器:

public class Controller {
private Model m;
private View v;

public Controller(Model m, View v){
    this.m = m;
    this.v = v;
}

public void handleMouseclick(MouseEvent e){
    m.setValue(m.getValue() + 5);
}
public void init(){
    v.setOnMouseClicked(this::handleMouseclick);
}
}

查看:

public class View extends Region{

private Model m;
private Label label;

public View(Model m)
{
    this.m = m;

    label.textProperty().bind(m.getObsValue());
    label.setLayoutX(200);
    label.setLayoutY(200);
    paint();
}

public void paint(){
    getChildren().clear();        
    getChildren().addAll(label);  
}


@Override
public double computePrefHeight(double width){
    return 800;
}

@Override
public double computePrefWidth(double height){
    return 600;
}
}

您可能已经注意到,我目前仍在学习 JavaFX。所以我可能只是错过了一些愚蠢的事情。任何建议将不胜感激!

【问题讨论】:

    标签: java data-binding javafx


    【解决方案1】:

    让我们从头开始——例外是因为你从未初始化label,所以它为空——就这么简单。使用label = new Label(); 应该可以解决它。

    现在对于绑定 - 你说你不想使用 IntegerPropertyReadOnlyIntegerWrapper,而是使用简单的 int - 这意味着你没有方便的方法知道值何时更改!标签将始终包含整数的初始值,因此您不妨执行以下操作:

    label.setText(Integer.toString(m.getValue()));
    

    相反,我建议你做类似的事情

    public class Model {
    
        private SimpleIntegerProperty value = new SimpleIntegerProperty(this, "value");
    
        public Model() {
            value.set(5);
        }
    
        public int getValue(){
            return value.get();
        }
    
        public void setValue(int value){
            this.value.set(value);
        }
    
        public IntegerProperty valueProperty(){
            return value;
        }
    }
    

    然后你可以使用Bindings.convert绑定标签的文本属性:

    label.textProperty().bind(Bindings.convert(m.valueProperty()));
    

    这样,每当模型的值发生变化时,标签文本都会自动反映这一点。

    如您所见,SimpleIntegerProperty 没什么好怕的!构造函数中的参数是可选的,但建议使用 - 它们是此属性所属的对象 (this),以及属性的名称(在本例中为 "value")。您还可以在构造函数中传递初始值,而不是在 Model 构造函数中显式设置它。

    【讨论】:

    • 非常感谢!我不敢相信我没有初始化标签。但话又说回来,我很快写了这段代码,以使问题尽可能清晰。
    • 好答案。但它仍然困扰着我,SimpleIntegerProperty 不可序列化。为什么??顺便说一句:“值”字段应该是“IntegerProperty”类型。这就是多态性,对吧? :)
    猜你喜欢
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 2013-09-07
    • 1970-01-01
    相关资源
    最近更新 更多