2

I want to load fxml files from an absolute path or a path outside of my jar system.

background: it will be a simple plugin-system that look's in the plugin folder for all fxml files (later jar files) and include it automatically in a TabPane.

String fxmlpath = "C:\\plugin\\pluginfxml.fxml"; try { Parent root = FXMLLoader.load(getClass().getResource(fxmlpath)); //Load root in Tabpane and so on ... } 

enter image description here

1
  • The solution is For fxml / class files ... not for jar Files. Commented Nov 5, 2014 at 15:57

2 Answers 2

7
+50

It should be simple:

Parent root = FXMLLoader.load(Paths.get(fxmlpath).toUri().toURL()); 

FXMLLoader takes in a URL as its argument, so we just use the NIO Paths class to get the Path, then convert it to a URL. The only problem occurs if the program does not have read access to the file's location.'

I've fleshed out the example with the example code from the JavaFX tutorial:

Test application:

package javafx; import java.net.URL; import java.nio.file.Paths; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class FXMLTest extends Application { public static void main(String[] args) { Application.launch(FXMLTest.class, args); } @Override public void start(Stage stage) throws Exception { URL fxmlURL = Paths.get("C:\\test\\fxml_example.fxml").toUri().toURL(); Parent root = FXMLLoader.load(fxmlURL); stage.setTitle("FXML Welcome"); Scene myScene = new Scene(root, 300, 275); stage.setScene(myScene); stage.show(); } } 

Example Controller:

package javafx; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.text.Text; public class FXMLExampleController { @FXML private Text actiontarget; @FXML protected void handleSubmitButtonAction(ActionEvent event) { actiontarget.setText("Sign in button pressed"); } } 

Example FXML:

<?xml version="1.0" encoding="UTF-8"?> <?import java.net.*?> <?import javafx.geometry.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> <GridPane fx:controller="javafx.FXMLExampleController" xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10" styleClass="root"> <padding><Insets top="25" right="25" bottom="25" left="25"/></padding> <Text id="welcome-text" text="Welcome" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2"/> <Label text="User Name:" GridPane.columnIndex="0" GridPane.rowIndex="1"/> <TextField GridPane.columnIndex="1" GridPane.rowIndex="1"/> <Label text="Password:" GridPane.columnIndex="0" GridPane.rowIndex="2"/> <PasswordField fx:id="passwordField" GridPane.columnIndex="1" GridPane.rowIndex="2"/> <HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="1" GridPane.rowIndex="4"> <Button text="Sign In" onAction="#handleSubmitButtonAction"/> </HBox> <Text fx:id="actiontarget" GridPane.columnIndex="1" GridPane.rowIndex="6"/> <stylesheets> <URL value="@Login.css" /> </stylesheets> </GridPane> 
Sign up to request clarification or add additional context in comments.

4 Comments

javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2617)
I've added the example code I used to test my suggestion before I posted it. It runs for me fine in JDK 1.8.0_20. Hopefully it will help.
The constructLoadException means there's probably an error in your FXML or its Controller class.
Thanks alot the problem was, that the Controller classes wasnt loaded.Thats why it didnt work. But Anyway Thanks
3

The call you make to Class.getResource(String) looks on the classpath for the resource (unless you've done something funky with the class-loaders) and therefore will never find an absolute path.

If you want to load a file from an absolute path, just create an java.io.FileInputStream using that path like this:

String fxmlpath = "C:\\plugin\\pluginfxml.fxml"; Parent root = FXMLLoader.load(new FileInputStream(fxmlpath)); 

That said, I'd be careful with absolute paths, they're not very portable - it's more common to create a standard directory structure for your application and then add the necessary directories to the classpath.

For example your application might have a directory structure like this:

My Application + bin + conf + lib + plugins 

Then assuming you run your application from the bin directory, you'd use a classpath like this:

../conf;../plugins;../lib/* 

Which would allow you to do the following in your application:

String fxmlpath = "pluginfxml.fxml"; Parent root = FXMLLoader.load(Class.getResourceAsStream(fxmlpath)); 

4 Comments

Parent root = FXMLLoader.load(Class.getResourceAsStream(fxmlpath)); what is Class ?
'Class.getResourceAsStream' is a static method, see the JavaDoc for a description of which classloader is used - docs.oracle.com/javase/8/docs/api/java/lang/…
But Class need a Type like Class<Object> or something
No, the genetic parameter is irrelevant in a static context. The code will simply create an InputStream from a resource on the classpath (providing that resource exists)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.