2
votes

I have an FXML Document where I am using a custom control ImageButton it is stored in the package net.aninnovation.baseUtility.view.ImageButton This contains 3 files ImageButton.class, ImageButton.fxml and ImageButton.css. The .class file is the controller, the .fmxl is the FXML document and the .css file is the stylesheet.

Now I am creating an FXML document in the package net.aninnovation.csp.main. The name of the file is Default.fxml. This is basically a VBox as shown below:

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

<?import ...........................?>//Other required Imports
<?import net.aninnovation.baseUtility.view.ImageButton.ImageButton?>

<VBox id="defaultPanel" fx:id="defaultPanel" styleClass="centerBox" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="net.aninnovation.CSP.main.DefaultController">
    <children>
        <FlowPane>
            <children>
                .
                .
                .
                . //Other 
                . //Components
                .
                <ImageButton/>
                .
                . //Other
                . //Components
                .
            </children>
        </FlowPane>
    </children>
   <stylesheets>
      <URL value="@Default.css" />
   </stylesheets>
</VBox>

When I try to load this file in SceneBuilder it gives the following Exception:

Caused by: java.lang.ClassNotFoundException: net.aninnovation.baseUtility.view.ImageButton$ImageButton at java.lang.ClassLoader.findClass(ClassLoader.java:530) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2916) at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2905) at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2846) ... 20 more

Here I find that though I had imported net.aninnovation.baseUtility.view.ImageButton.ImageButton, the Exception states net.aninnovation.baseUtility.view.ImageButton$ImageButton. Now why is the . being replaced by $? Is there something wrong I have done?

The constructor of ImageButton class is loading the FXML document as here:

public ImageButton() {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("ImageButton.fxml"));
    loader.setRoot(this);
    loader.setController(this);
    try {
        loader.load();
    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

ImageButton.fxml

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.SVGPath?>

<fx:root stylesheets="@ImageButton.css" type="Button" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
    <graphic>
        <VBox>
            <children>
                <SVGPath fx:id="svgImage" />
                <Label fx:id="label" />
            </children>
        </VBox>
    </graphic>
</fx:root>

These are located in the package net.aninnovation.baseUtility.view.ImageButton. As stated earlier there are 3 files in the location ImageButton.class, ImageButton.fxml and ImageButton.css

When I moved the ImageButton to package net.aninnovation.csp.main and net.aninnovation.csp.main.imageButton. I have got the error as:

Caused by: java.lang.ClassNotFoundException: net.aninnovation.csp$main$ImageButton at java.lang.ClassLoader.findClass(ClassLoader.java:530) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2916) at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2905) at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2846) ... 20 more

and

Caused by: java.lang.ClassNotFoundException: net.aninnovation.csp$main$imageButton$ImageButton at java.lang.ClassLoader.findClass(ClassLoader.java:530) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2916) at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2905) at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2846) ... 20 more

1
I don't know if this causes the problem, but package names should be lowercase. - Thilo
Typically the $ is used to represent inner classes. Not sure why it thinks it's looking for an inner class. Do you have the same problem if the package is named net.aninnovation.baseUtility.view.imageButton (note lowercase i)? I can't imagine this actually solving it though... - Krease
@Krease I had moved the code for ImageButton around in several packages like net.aninnovation.baseUtility.imageButton and also net.aninnovation.csp.main and net.aninnovation.csp.main.imageButton. I have got very unusual error that I have posted. - Blip
It isn't replaced in the CLASSPATH. It is replaced in the class name. - user207421
@EJP so how can it be corrected? - Blip

1 Answers

0
votes

One of the reason's could be net.aninnovation.baseUtility.view.ImageButton.ImageButton is a NestedClass of net.aninnovation.baseUtility.view.ImageButton

For Example:

public class Number  {
    class NestedNumber {

    }
}

When this code gets compiled, java generates 2 files. Namely:

  1. Number$NestedNumber.class
  2. Number.class

But, when you access in code (for imports) you still use Number.NestedNumber instead of $. However for Reflection you use $.

public static void main(String args[]) throws ClassNotFoundException {
        Class<?> forName = Class.forName("Number$NestedNumber");
        System.out.println(forName);
    }