JDK-8094318 : FXMLLoader fails to load attribute styleClass on Spinner
  • Type: Bug
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: 8u40
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-03-23
  • Updated: 2016-10-14
  • Resolved: 2015-03-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8u60Fixed
Related Reports
Relates :  
Description
When loading a Spinner from an FXML, FXMLLoader ignored attribute styleClass.

Take the following FXML:

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

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<VBox id="AnchorPane" style="-fx-spacing: 6;"  prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.TestFXMLController">
    <Button fx:id="button" styleClass="my-button"/>
    <ComboBox fx:id="combo" styleClass="my-combo"/>
    <Spinner fx:id="spinner" styleClass="my-spinner"/>
</VBox>

And the following controller:

package test;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Spinner;

public class TestFXMLController implements Initializable {
    @FXML
    private Button button;
    @FXML
    private ComboBox combo;
    @FXML
    private Spinner spinner;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        System.out.println("> Button");
        button.getStyleClass().forEach(System.out::println);
        System.out.println("> ComboBox");
        combo.getStyleClass().forEach(System.out::println);
        System.out.println("> Spinner");
        spinner.getStyleClass().forEach(System.out::println);
    }
}

And the following app class:
package test;

import java.io.IOException;
import java.net.URL;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
    
    @Override
    public void start(Stage primaryStage) throws IOException {
        final URL fxmlURL = getClass().getResource("test.fxml");
        final FXMLLoader fxmlLoader = new FXMLLoader(fxmlURL);
        final Parent root = fxmlLoader.load();
        Scene scene = new Scene(root);        
        primaryStage.setTitle("test");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }    
}

The output of this app is:

> Button
button
my-button
> ComboBox
combo-box-base
combo-box
my-combo
> Spinner
spinner

The Spinner object created by the FXMLLoader is missing the style "my-spinner"

Comments
Changeset: http://hg.openjdk.java.net/openjfx/8u-dev/rt/rev/b06d15751d1f Unit test: javafx.fxml.RT_40335Test.test_rt_40335()
24-03-2015

I have a fix locally, but I need to test it more first before I push.
24-03-2015

Thanks!
24-03-2015

The issue is in the FXML loading code. In JavaFXBuilderFactory, there is a getBuilder(Class) method. Because the Spinner class has annotations on some of its constructors, the code branches into the condition where scanForConstructorAnnotations(type) returns true. In the case of Button and ComboBox, this branch is not entered and the control is reflectively instantiated. For some reason that I have not yet determined, the ProxyBuilder code that is returned for Spinner results in an exception, and this is why the spinner style classes are not set. I'll keep digging as time permits.
24-03-2015

I can see where this is failing (in FXMLLoader), but it isn't clear to me why it is failing. Will keep digging....
24-03-2015

Quite bizarre - I'm not sure why this is happening. Will investigate further.
24-03-2015