简体   繁体   English

JavaFX:将TextProperty(例如Label)绑定到一个简单的Integer

[英]JavaFX: Binding a TextProperty (eg. Label) to a simple Integer

The general question: Is there any way to update a label when the value of a simple integer changes ? 一般问题:当简单整数的值发生变化时,有没有办法更新标签?

I'm talking about simple int's and not stuff like ReadOnlyIntegerWrappers . 我说的是简单的int而不是像ReadOnlyIntegerWrappers这样的东西。 I've tried the following according to Converting Integer to ObservableValue<Integer> in javafx (I had to change the identifier (is that what it's called ?) of ObservableValue from Integer to String because I couldn't find a way to bind it to the TextProperty otherwise) 我根据在javafx中将Converting Integer转换为ObservableValue <Integer> (我不得不将ObservableValue的标识符(就是所谓的名称?)从Integer更改为String来尝试以下内容,因为我找不到将它绑定到的方法否则为TextProperty)

I've included my demo code below which somehow seems to result in a NullPointerException at label.textProperty().bind(m.getObsValue()); 我已经在下面包含了我的演示代码,它似乎在label.textProperty().bind(m.getObsValue());导致了NullPointerException。bind label.textProperty().bind(m.getObsValue()); . The application is written in a MVC-pattern. 该应用程序是以MVC模式编写的。

Model: 模型:

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;
}
}

Controller: 控制器:

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);
}
}

View: 视图:

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;
}
}

As you might've noticed I'm currently still studying JavaFX. 您可能已经注意到我目前仍在学习JavaFX。 So I probably just missed something stupid. 所以我可能只是错过了一些愚蠢的东西。 Any advice would be greatly appreciated ! 任何建议将不胜感激 !

Let's start from the end - the exception is because you never initialize label , so it is null - as simple as that. 让我们从最后开始 - 例外是因为你永远不会初始化label ,所以它是null - 就这么简单。 Using label = new Label(); 使用label = new Label(); should solve it. 应该解决它。

And now for the bindings - you say you don't want to use IntegerProperty or ReadOnlyIntegerWrapper , but rather use a simple int - that means you have no convenient way of knowing when the value is changed! 现在对于绑定 - 你说你不想使用IntegerPropertyReadOnlyIntegerWrapper ,而是使用一个简单的int - 这意味着你没有方便的方法来知道值何时被改变! The label will always contain the initial value of your integer, so you may as well do something like: 标签将始终包含整数的初始值,因此您可以执行以下操作:

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

Instead, I would advise you to do something like 相反,我建议你做一些类似的事情

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;
    }
}

then you can bind the label's text property using Bindings.convert : 然后你可以使用Bindings.convert标签的text属性:

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

this way, whenever the model's value is changed, the label text would automatically reflect this. 这样,只要模型的值发生变化,标签文本就会自动反映出来。

As you can see, SimpleIntegerProperty is nothing to be afraid of! 正如您所看到的, SimpleIntegerProperty无需担心! The arguments in the constructor are optional, but recommended - they are the object this property belongs to ( this ), and the name of the property ( "value" , in this case). 构造函数中的参数是可选的,但建议 - 它们是此属性所属的对象( this ),以及属性的名称(在本例中为"value" )。 You can also pass the initial value in the constructor, instead of explicitly setting it in your Model constructor. 您还可以在构造函数中传递初始值,而不是在Model构造函数中显式设置它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM