Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
604 views
in Technique[技术] by (71.8m points)

javafx 2 - Can't import custom components with custom cell factories

In JavaFX 2.2 I've been having trouble importing custom components that have a custom cell factory defined in the FXML. Lets say my custom component is the following

public class CustomComponent extends VBox{

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

}

And the corresponding FXML is

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

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.VBox?>
<?import application.*?>
<?import application.TestFactory?>


<fx:root prefHeight="358.0" prefWidth="260.0" type="VBox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
   <children>
      <TableView prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
        <columns>
          <TableColumn prefWidth="75.0" text="C1" >
            <cellFactory>
                <TestFactory />
            </cellFactory>
          </TableColumn>
          <TableColumn prefWidth="75.0" text="C2" >
          <cellFactory>
            <TestFactory />
          </cellFactory>
          </TableColumn>
        </columns>
         <columnResizePolicy>
            <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
         </columnResizePolicy>
      </TableView>
   </children>
</fx:root>

and TestFactory is defined as

public class TestFactory<S,T> implements Callback<TableColumn<S, T>, TableCell<S, T>>{

    @Override
    public TableCell<S, T> call(TableColumn<S, T> param) {
        return new TableCell<S,T>();
    }

}

And all three of these files are in the same directory / src package.

When I jar these files together and try to import the jar into scenebuilder it will not find CustomComponent. However, if I take out the reference to the cellFactory & TestFactory it will import just fine. Looking at the jar analysis it seems to throw a ClassNotFoundException on TestFactory.

Not a Node: application/Main.class

Not a Node: application/TestFactory.class

Exception for: application/CustomComponent.class
javafx.fxml.LoadException: 
unknown path:2

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2617)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2595)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2425)
    at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.instantiateWithFXMLLoader(JarExplorer.java:105)
    at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.exploreEntry(JarExplorer.java:146)
    at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.explore(JarExplorer.java:65)
    at com.oracle.javafx.scenebuilder.kit.library.user.LibraryFolderWatcher.exploreAndUpdateLibrary(LibraryFolderWatcher.java:298)
    at com.oracle.javafx.scenebuilder.kit.library.user.LibraryFolderWatcher.runDiscovery(LibraryFolderWatcher.java:122)
    at com.oracle.javafx.scenebuilder.kit.library.user.LibraryFolderWatcher.run(LibraryFolderWatcher.java:88)
    at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: 
file:/C:/Users/bthomas/AppData/Roaming/Scene%20Builder/Library/testing.jar!/application/CustomComponent.fxml

    at application.CustomComponent.<init>(CustomComponent.java:17)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at java.lang.Class.newInstance(Class.java:433)
    at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1010)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:740)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2723)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
    ... 8 more
Caused by: javafx.fxml.LoadException: 
file:/C:/Users/bthomas/AppData/Roaming/Scene%20Builder/Library/testing.jar!/application/CustomComponent.fxml

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2617)
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2864)
    at javafx.fxml.FXMLLoader.processImport(FXMLLoader.java:2708)
    at javafx.fxml.FXMLLoader.processProcessingInstruction(FXMLLoader.java:2677)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2517)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at application.CustomComponent.<init>(CustomComponent.java:15)
    ... 18 more
Caused by: java.lang.ClassNotFoundException: application.TestFactory
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2932)
    at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2921)
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2862)
    ... 24 more

I assume this is some classpath issue with scene builder, but i'm at a loss. Has anyone encountered this problem before or know of a solution?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It seems the issue lies within the scenebuilder class loading environment. It is also a known bug / issue with scenebuilder.

A workaround is to propogate the classloader to the FXML loader.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...