Impossible d'importer des composants personnalisés avec des usines de cellules personnalisées
-
21-12-2019 - |
Question
Dans JavaFX 2.2 J'ai eu du mal à importer des composants personnalisés qui ont une usine de cellule personnalisée définie dans la FXML.Disons que mon composant personnalisé est le suivant
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);
}
}
}
et le FXML correspondant est
<?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>
et testFactory est défini comme
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>();
}
}
et tous les trois de ces fichiers sont dans le même package répertoire / SRC.
Lorsque je jarre ces fichiers ensemble et essayez d'importer le bocal dans SceneBuilder, il ne trouvera pas sur mesureComponce.Toutefois, si je sors la référence à la CELLFFACTORY & TESTFINGORY, il importera simplement.En regardant l'analyse de la JAR, il semble lancer une parfaite note de classe sur des testsFactory.
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
Je suppose que c'est un problème de classe de classe avec le constructeur de scène, mais je suis à perte.Quelqu'un a-t-il rencontré ce problème avant ou de connaître une solution?
La solution
Il semble que la question se situe dans l'environnement de chargement de la classe SceauBuilder.C'est aussi un bug / problème connu avec SceneBuilder.
Une solution de contournement est de propoger le chargeur de classes au chargeur FXML.
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);
}