java JavaFX:将 TextProperty(例如标签)绑定到一个简单的整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34546433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaFX: Binding a TextProperty (eg. Label) to a simple Integer
提问by Onon
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. 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)
我说的是简单的 int 而不是ReadOnlyIntegerWrappers 之类的东西。我根据在 javafx 中将 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());
. The application is written in a MVC-pattern.
我在下面包含了我的演示代码,它似乎以某种方式导致了 NullPointerException at label.textProperty().bind(m.getObsValue());
。该应用程序以 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. So I probably just missed something stupid. Any advice would be greatly appreciated !
您可能已经注意到,我目前仍在学习 JavaFX。所以我可能只是错过了一些愚蠢的事情。任何建议将不胜感激 !
回答by Itai
Let's start from the end - the exception is because you never initialize label
, so it is null - as simple as that. Using label = new Label();
should solve it.
让我们从最后开始——例外是因为你从来没有 initialize label
,所以它是空的——就这么简单。使用label = new Label();
应该可以解决。
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! The label will always contain the initial value of your integer, so you may as well do something like:
现在对于绑定 - 你说你不想使用IntegerProperty
or ReadOnlyIntegerWrapper
,而是使用一个简单的int
- 这意味着你没有方便的方法来知道值何时改变!标签将始终包含整数的初始值,因此您也可以执行以下操作:
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
以下方法绑定标签的文本属性:
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! 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). You can also pass the initial value in the constructor, instead of explicitly setting it in your Model
constructor.
如您所见,SimpleIntegerProperty
没什么好害怕的!构造函数中的参数是可选的,但建议使用 - 它们是此属性所属的对象 ( this
) 和属性的名称 ("value"
在本例中为 )。您还可以在构造函数中传递初始值,而不是在构造函数中显式设置它Model
。