Pela documentação, parece que deveria ser possível usar expressões simples ao calcular propriedades de elementos, mas sempre parece haver erros. A sintaxe está correta? Há mais alguma orientação disponível?
Um pequeno exemplo (baseado no javafx-archetype-fxml
link aqui ):
<?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>
O objetivo é atualizar o texto do rótulo com o comprimento do texto no TextField (isso é apenas um exemplo)
Uma única variável ${source.length}
é aceitável, mas uma expressão ${source.length*2}
não. Parece que qualquer expressão binária ou unária é problemática.
O erro que vejo inclui este rastreamento de pilha:
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
No código-fonte com.sun.javafx.binding.ExpressionHelper
(linha 64), parece que addListener
tenta obter o valor do observável (o comentário diz "validar observável"), mas neste ponto o TextField não foi totalmente criado e, portanto, seu comprimento é avaliado como nulo, e a expressão binária null * 2 falha. Pelo que entendi, posso estar errado.
Estou usando Java 23 e JFX 24.0.1.
Acredito que sua análise esteja correta; na minha opinião, isso é um bug.
Você pode contornar isso definindo o campo de texto antes de referenciá-lo no FXML, usando
<fx:define>
and<fx:reference>
: