从文档来看,似乎可以使用简单的表达式来计算元素属性,但总是报错。这里的语法正确吗?还有其他指导吗?
一个小例子(这是基于此处javafx-archetype-fxml
的链接):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.geometry.Insets?>
<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.nowhere.PrimaryController">
<children>
<!-- WORKS -->
<Label text="${source.length}" />
<!-- ERROR -->
<Label text="${source.length*2}" />
<Button fx:id="primaryButton" text="Switch to Secondary View" onAction="#switchToSecondary"/>
<TextField fx:id="source" />
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
这是为了使用 TextField 中的文本长度来更新标签文本(这只是一个例子)
单个变量${source.length}
没问题,但表达式${source.length*2}
不行。看来任何二元或一元表达式都有问题。
我看到的错误包括以下堆栈跟踪:
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Number.longValue()" because "<parameter1>" is null
at [email protected]/com.sun.javafx.fxml.expression.Expression.lambda$multiply$2(Expression.java:932)
at [email protected]/com.sun.javafx.fxml.expression.BinaryExpression.evaluate(BinaryExpression.java:55)
at [email protected]/com.sun.javafx.fxml.expression.ExpressionValue.getValue(ExpressionValue.java:191)
at [email protected]/com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:64)
at [email protected]/javafx.beans.value.ObservableValueBase.addListener(ObservableValueBase.java:57)
at [email protected]/com.sun.javafx.fxml.expression.ExpressionValue.addListener(ExpressionValue.java:200)
at [email protected]/javafx.beans.property.StringPropertyBase.bind(StringPropertyBase.java:171)
at [email protected]/javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:318)
at [email protected]/javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:235)
at [email protected]/javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:767)
at [email protected]/javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2939)
at [email protected]/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2624)
... 11 more
在源代码中com.sun.javafx.binding.ExpressionHelper
(第 64 行),它似乎addListener
尝试获取可观察对象的值(注释中写着“validate observable”),但此时 TextField 尚未完全创建,因此其长度计算结果为 null,二进制表达式 null * 2 失败。这是我的理解,可能存在错误。
我正在使用 Java 23 和 JFX 24.0.1。
我认为你的分析是正确的;在我看来这是一个错误。
您可以通过在 FXML 中引用文本字段之前定义它来解决此问题,使用
<fx:define>
和<fx:reference>
: