I am trying to separate all relations between ui-elements (i.e. "disable button if textfield is empty") to fxml.
This works fine in most cases, but it seems to be impossible to bind to java.util.List derived classes.
It always ends in java.lang.NumberFormatException caused by com.sun.javafx.fxml.expression.Expression.get():
public static <T> T get(Object namespace, String key) {
...
if (namespace instanceof List<?>) {
List<Object> list = (List<Object>)namespace;
**value = list.get(Integer.parseInt(key));**
}
...
where key is the property-name I try to bind to (i.e. "empty" if binding to "myListProperty.empty"). FXMLLoader tries to get the value at index "property-name" instead of getting the according property (as it does correctly if the namespace-object does not implement java.util.List).
The attached short example shows how to reproduce the behavior:
Main-class
package test.fxml;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class TestApp extends Application
{
@Override
public void start( Stage primaryStage ) throws Exception
{
Parent root = FXMLLoader.load( getClass().getResource( "./Test.fxml" ) );
Scene scene = new Scene( root,300,250 );
primaryStage.setTitle( "Test App" );
primaryStage.setScene( scene );
primaryStage.show();
}
public static void main( String[] args )
{
Application.launch( args );
}
}
Controller-class (empty)
package test.fxml;
public class Controller
{
public Controller()
{
super();
}
}
FXML-file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.beans.property.SimpleListProperty?>
<?import javafx.scene.control.TextField?>
<VBox xmlns="http://javafx.com/javafx/8.0.92"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="test.fxml.Controller">
<fx:define>
<SimpleListProperty fx:id="myListProperty" />
</fx:define>
<TextField fx:id="myTextField"
text="does not work"
disable="${myListProperty.empty}"/>
</VBox>
Excerpt from the stack-trace
Caused by: java.lang.NumberFormatException: For input string: "empty"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at com.sun.javafx.fxml.expression.Expression.get(Expression.java:623)
at com.sun.javafx.fxml.expression.Expression.get(Expression.java:597)
at com.sun.javafx.fxml.expression.Expression.get(Expression.java:597)
at com.sun.javafx.fxml.expression.Expression.get(Expression.java:576)
at com.sun.javafx.fxml.expression.VariableExpression.evaluate(VariableExpression.java:53)
at com.sun.javafx.fxml.expression.ExpressionValue.getValue(ExpressionValue.java:192)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:54)
at javafx.beans.value.ObservableValueBase.addListener(ObservableValueBase.java:55)
at com.sun.javafx.fxml.expression.ExpressionValue.addListener(ExpressionValue.java:201)
at javafx.beans.binding.BooleanBinding.bind(BooleanBinding.java:107)
at javafx.beans.property.BooleanPropertyBase$1.<init>(BooleanPropertyBase.java:169)
at javafx.beans.property.BooleanPropertyBase.bind(BooleanPropertyBase.java:166)
at javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:319)
at javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:235)
at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:767)
at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2823)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2532)
My questions are:
1. Does anybody know if this is a bug in fxml?
2. If not, can anyone please explain the special handling for java.util.List to me?
3. Is it possible to fulfill the requirement "enable/disable ui-components according list-size or list-state only by fxml"?
Many thanks in advance for your help.