gpt4 book ai didi

java - 将 Label 的文本属性(在 FXML 文件中)绑定(bind)到 IntegerProperty(在 Controller 中)

转载 作者:搜寻专家 更新时间:2023-10-30 20:58:04 25 4
gpt4 key购买 nike

我已经在 FXML 文件中的 Label 和关联 Controller 中的 IntegerProperty 之间设置了数据绑定(bind)。问题是,虽然标签在初始化时设置为正确的值,但当属性值更改时它不会更新。

FXML 文件

<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<GridPane xmlns:fx="http://javafx.com/fxml"
fx:controller="application.PaneController" minWidth="200">
<Label id="counterLabel" text="${controller.counter}" />
<Button translateX="50" text="Subtract 1"
onAction="#handleStartButtonAction" />
</GridPane>

Controller

package application;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;

public class PaneController implements Initializable
{
private IntegerProperty counter;

public int getCounter()
{
return counter.get();
}

public void setCounter(int value)
{
counter.set(value);
}

public PaneController()
{
counter = new SimpleIntegerProperty(15);
}

@Override
public void initialize(URL url, ResourceBundle resources)
{
}

@FXML
private void handleStartButtonAction(ActionEvent event)
{
setCounter(getCounter() - 1);
System.out.println(getCounter());
}
}

期待

每次我按下“减 1”按钮,计数器都会减 1,并且 counterLabel 会自动更新。

现实

计数器减 1,但 counterLabel 仍停留在 15(初始值)。

问题

我的印象是(例如,来自 this forum post )我所做的应该有效。我错过了什么?

最佳答案

您需要将特定于 JavaFX 的访问器 variableNameProperty 添加到 Controller :

public IntegerProperty counterProperty() {
return counter;
}

编辑:更多细节。
API 文档并未过多提及此 JavaFX 的 JavaBeans 体系结构。这里只是介绍一下 (Using JavaFX Properties and Binding),但同样没有说明它的必要性。

那么让我们挖掘一些源代码吧! :)
简单地说,我们开始研究 FXMLLoader code第一的。我们注意到绑定(bind)表达式的前缀为

public static final String BINDING_EXPRESSION_PREFIX = "${";

进一步在第 279 行 FXMLLoader 确定 if (isBindingExpression(value))然后创建绑定(bind),实例化 BeanAdapter并获取 propertyModel:

BeanAdapter targetAdapter = new BeanAdapter(this.value);
ObservableValue<Object> propertyModel = targetAdapter.getPropertyModel(attribute.name);

如果我们查看 BeanAdapter #getPropertyModel() ,

public <T> ObservableValue<T> getPropertyModel(String key) {
if (key == null) {
throw new NullPointerException();
}
return (ObservableValue<T>)get(key + BeanAdapter.PROPERTY_SUFFIX);
}

它委托(delegate)给BeanAdapter#get()附加 String PROPERTY_SUFFIX = "Property";
在 get() 方法中,只是反射调用的 getter(counterProperty 或 getCounter 或 isCounter),返回结果。如果 getter 不存在则返回 null。换句话说,如果 JavaBean 中不存在“counterProperty()”,则在我们的例子中返回 null。在这种情况下,由于语句 if (propertyModel instanceof Property<?>) 未执行绑定(bind)在 FXMLLoader 中。结果,没有“counterProperty()”方法没有绑定(bind)。

如果在 bean 中没有定义 getter 会发生什么?再次来自 BeanAdapter#get()代码我们可以说,如果找不到“getCounter()”,则返回 null 并且调用者只是忽略它作为无操作 imo。

关于java - 将 Label 的文本属性(在 FXML 文件中)绑定(bind)到 IntegerProperty(在 Controller 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19822717/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com