5 Replies Latest reply: Apr 29, 2013 8:55 AM by 993317 RSS

    ClassCastException when trying to cast an object loaded from fxml

    993317
      I am getting a ClassCastException when trying to cast the root element loaded from an fxml(see below) to a class extending the root element.
      <StackPane prefHeight="56.0" prefWidth="560.0" xmlns:fx="http://javafx.com/fxml">
        <children>
          <HBox alignment="CENTER" prefHeight="56.0" prefWidth="619.0">
            <children>
              <Label text="Label1:" />
              <TextField prefHeight="24.0" prefWidth="310.9998779296875" />
              <Label text="Label2:" />
              <TextField prefHeight="24.0" prefWidth="85.0" />
            </children>
          </HBox>
        </children>
      </StackPane>
      StackPane stackPane = FXMLLoader.load(getClass().getResource("trial.fxml"));
      MyStackPane myStackPane = (MyStackPane) stackPane; // ClassCastException
      public class MyStackPane extends StackPane {
      
          public MyStackPane() {
              super();
          }
          
      }
      Is this not supported in JavaFX ???
        • 1. Re: ClassCastException when trying to cast an object loaded from fxml
          James_D
          It's not so much that it's not supported in JavaFX; the object returned is simply not an instance of MyStackPane:
          <StackPane prefHeight="56.0" prefWidth="560.0" xmlns:fx="http://javafx.com/fxml">
          ...
          </StackPane>
          instructs the FXMLLoader to instantiate a StackPane (not a MyStackPane) and return it from the load(...) method. So the downcast fails.

          You get the same in plain Java:
          StackPane stackPane = new StackPane();
          stackPane.setPrefWidth(560);
          stackPane.setPrefHeight(56);
          ...
          MyStackPane myStackPane = (MyStackPane) stackPane ; //Still gives a ClassCastException
          Since your subclass has a no-arg constructor, you should be able to do
          <MyStackPane prefHeight="56.0" prefWidth="560.0" xmlns:fx="http://javafx.com/fxml">
          ...
          </MyStackPane>
          and it should work. You can use the Java code you have, or simply do
          MyStackPane myStackPane = FXMLLoader.load(getClass().getResource("trial.fxml"));
          • 2. Re: ClassCastException when trying to cast an object loaded from fxml
            993317
            Thanks James, i was aware of this technique before but the reason i was trying to do it programmatically is because Scene Buider fails to start-up.
            <?xml version="1.0" encoding="UTF-8"?>
            
            <?import java.lang.*?>
            <?import java.util.*?>
            <?import javafx.scene.*?>
            <?import javafx.scene.control.*?>
            <?import javafx.scene.layout.*?>
            <?import titledborder.MyStackPane?>
            
            <MyStackPane fx:id="sp" prefHeight="56.0" prefWidth="560.0" xmlns:fx="http://javafx.com/fxml">
              <children>
                <HBox alignment="CENTER" prefHeight="56.0" prefWidth="619.0">
                  <children>
                    <Label text="Label1:" />
                    <TextField prefHeight="24.0" prefWidth="310.9998779296875" />
                    <Label text="Label2:" />
                    <TextField prefHeight="24.0" prefWidth="85.0" />
                  </children>
                </HBox>
              </children>
            </MyStackPane>
            It shows this Exception:
            Error loading file 'D:/NetBeansProjects/TitledBorder/src/titledborder/trial.fxml'.
            D:\NetBeansProjects\TitledBorder\src\titledborder\trial.fxml:0: error:
                 java.lang.ClassNotFoundException: titledborder.MyStackPane
            • 3. Re: ClassCastException when trying to cast an object loaded from fxml
              ArtemAnaniev
              990314 wrote:
              Thanks James, i was aware of this technique before but the reason i was trying to do it programmatically is because Scene Buider fails to start-up.
              When you open such FXML file in SceneBuilder, it should prompt you to specify the jar file where titledborder.MyStackPane can be found, at least in recent versions of SceneBuilder.
              990314 wrote:
              It shows this Exception:
              Error loading file 'D:/NetBeansProjects/TitledBorder/src/titledborder/trial.fxml'.
              D:\NetBeansProjects\TitledBorder\src\titledborder\trial.fxml:0: error:
                   java.lang.ClassNotFoundException: titledborder.MyStackPane
              Do you have a full stack of this exception?

              It seems that FXMLLoader cannot load titledborder.MyStackPane. Is it available in the classpath? You could also try to play with FXMLLoader.setDefaultClassLoader().
              • 4. Re: ClassCastException when trying to cast an object loaded from fxml
                daniel
                Hi,

                There should be a workaround for this. instead of doing:
                <?import titledborder.MyStackPane?>
                try with:
                <?import titledborder.*?>
                When you load your FXML file in SceneBuilder, SceneBuilder should display a Classpath dialog,
                asking you to enter a classpath.
                Enter the appropriate classpath so that titledborder.MyStackPane can be resolved, and your file
                should load.

                Hope this helps,

                -- daniel
                • 5. Re: ClassCastException when trying to cast an object loaded from fxml
                  993317
                  Thanks Artem & Daniel,
                  Scene Builder successfully loads the fxml if I launch it separately and open the fxml. It prompts for the classpath and i have do the required.
                  But on double click it fails without the classpath prompt. I am using v1.0 . I will try v1.1 .