I've been toying with JavaFX for a while now and now I wanted to share some of the components I have built. For ease of use, I would like to be able to distribute the components as libraries, so another user can just import my libraries into JavFX project. However, building a a library file to import into SceneBuilder (SB) proved to be much harder than I had expected. I tried following this blog post but I must be doing something wrong. I want to create my own custom component, using a .fxml file and a .jar file.
I tried building this component:
TestPane.java
package pack;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;
import java.io.IOException;
public class TestPane extends AnchorPane {
public TestPane(){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("TestPane.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
@FXML protected void onClick(ActionEvent ae){
System.out.println("Click");
}
}
TestPane.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<fx:root type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<Button fx:id="button" layoutX="6.0" layoutY="10.0" mnemonicParsing="false" text="Button" onAction="#onClick" />
</fx:root>
I use Eclipse Mars, created a new JavaFX Library project, created a new package called pack. In that package, I created the two components from above. I then right-clicked the project and selected "Export... ->
Jar-file", and made no changes in the export dialogue.
I then created a new FXML project. I opened the .fxml file in SB and imported my exported .jar file, using the Import JAR/FXML File...
" dialogue, and then dragged it into my view.
Here is the code for the test project I've created.
LibTest.java package test;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class LibTest extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load( getClass().getResource("LibTest.fxml") );
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
LibTest.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import pack.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="199.0" prefWidth="126.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.40">
<children>
<TestPane layoutX="34.0" layoutY="82.0" />
</children>
</AnchorPane>
I thought I had followed all the online guides and tutorials by now but there is something I must be missing. When I then try to launch my test project, I get the error bellow. I understand that Caused by: javafx.fxml.LoadException: TestPane is not a valid type.
is the "key message", but what does it mean, and how do I fix this problem?
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$152(LauncherImpl.java:182)
at com.sun.javafx.application.LauncherImpl$$Lambda$50/1645995473.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException: TestPane is not a valid type.
/D:/WorkspaceDir/ProjectDir/bin/test/LibTest.fxml:11
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.createElement(FXMLLoader.java:2778)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2708)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2531)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3218)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3128)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3108)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3101)
at test.LibTest.start(LibTest.java:15)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
at com.sun.javafx.application.LauncherImpl$$Lambda$53/198061478.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl$$Lambda$45/186276003.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1079803749.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/237061348.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/2117255219.run(Unknown Source)
... 1 more
Exception running application test.LibTest
What is it that I am missing? What causes this problem and how do I fix it?