JavaFX 2.2 Controller initialize() not called when being loaded within JAR file


Question

Background: I've created a JavaFX application, embedded in a Swing frame using JFXPanel. I've been using Eclipse as an IDE. The "Main application" is another class which only serves to create an instance of a class which extends JFXPanel to load my .fxml file when it is instantiated. When executing the main class from Eclipse, all is well, the fx:controller specified in my .fxml file has its initialize() method called (I can tell from changes it makes to the UI on load) and there are no problems.

However, when I package everything into a JAR and try to add my JFXPanel extension class to a Swing JFrame instance, it manages to load the .fxml file just fine-read images, style sheets, etc, and the rest of the code is functioning as expected however the fx:controller's initialize() method is never called. I have no problem accessing the class from other classes inside or outside the jar and I've even tried setting up a ControllerFactory that will return an instance of the Controller as well as trying all sorts of combinations of setting the FXMLLoader's classloader and using both the static and non-static methods of invoking load(). The result is always the same: it will work when launching from the IDE but does not when launching from my packaged jar. I know the jar isn't missing any files because like I said there is no issue finding the class from the Java code and the bundled fxml/css files seem to be loading fine, minus the controller issue.

Anybody ever encounter this before or have any idea what might be going on with the FXMLLoader failing to set the Controller? Could this be a bug of some sort?

1
1
2/15/2013 5:45:54 PM

Accepted Answer

I was unable to solve this problem. While the fxml/css files are loading fine and referencing the right controller class, I was still unable to see the initialize() method of the controller class get invoked once everything was packaged up into a jar.

Since the only thing I needed the controller for was to grab the various UI objects defined in the fxml file so that I could do real programming with them, I opted instead to just create a recursive search to look for these individual widgets by their fxml ID [seems to look up 'id' first then 'fx:id' if an 'id' isn't found] in the Scene tree..

//grabs fxml file relative to root of the jar
FXMLLoader loader = new FXMLLoader(ClassLoader.getSystemClassLoader().getResource("app.fxml"));
Parent javaFXRoot = (Parent) loader.load();

public Node findWidgetByID(String id, Parent javaFXRoot)
{
    return findObject(root, id);
}

private Node findObject(Parent root, String id)
{
    for (Node node : root.getChildrenUnmodifiable())
    {
        if (node.getId() != null && node.getId().equals(id))
        {
            return node; // found the node, return it
        }
        Node retValue = null;
        if (node instanceof Parent)
        {
            retValue = findObject(((Parent) node), id); // recursive search
        }
        if (retValue != null) //if our node was found by the recursive search, return that
        {
            return retValue;
        }
    }
    return null;
}
0
5/1/2013 8:48:39 PM

I had a similar problem when packaging my JavaFX software into a .jar file. Turned out it was a problem regarding relative path. You're IDE has no issues with this, but then when compiled within a jar it is having issues.

This was resolved using following code to call my .fxml file.

getClass().getClassloader().getResource("/my/view/selector.fxml")

To say that this is the "reason" for your bug, I'm not sure, but this sure stumped me for a while and seems to be pretty much the problem I had.

Original question : Executable Jar limited to one window with JavaFX


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon