JavaFX SceneBuilder 2 相对路径异常
JavaFX SceneBuilder 2 relative path exception
我正在使用 SceneBuilder 构建 javaFX 应用程序,问题是,当我在 fxml 文件中指定相对路径时,它会在运行时抛出异常:
null/../images/text_formal.png
javafx.fxml.LoadException:
unknown path:13
at javafx.fxml.FXMLLoader.constructLoadException(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at com.graduation.project.fxml.manager.FXMLManager.<init>(FXMLManager.java:26)
at com.graduation.project.Main.start(Main.java:14)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication13(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait6(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null4(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater5(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null9(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Invalid URL: Invalid URL or resource not found
at javafx.scene.image.Image.validateUrl(Unknown Source)
at javafx.scene.image.Image.<init>(Unknown Source)
at com.sun.javafx.fxml.builder.JavaFXImageBuilder.build(Unknown Source)
at com.sun.javafx.fxml.builder.JavaFXImageBuilder.build(Unknown Source)
at javafx.fxml.FXMLLoader$ValueElement.processEndElement(Unknown Source)
at javafx.fxml.FXMLLoader.processEndElement(Unknown Source)
... 13 more
无论如何,当我设置绝对路径时它工作正常,我做错了什么?
我的 fxml :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="427.0" prefWidth="482.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.graduation.project.main.gui.MainScreen">
<children>
<Pane layoutX="77.0" prefHeight="73.0" prefWidth="482.0" style="-fx- background-color: #5475ba;" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<ImageView fitHeight="150.0" fitWidth="200.0" layoutX="77.0" layoutY="52.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0">
<image>
<Image url="@../images/text_formal.png" />
</image>
</ImageView>
</children>
</AnchorPane>
加载 FXMl
public class FXMLManager{
FXMLLoader fxmlLoader;
Parent root;
String stageFXMLName;
public FXMLManager(String stageFXMLName){
try {
this.stageFXMLName = stageFXMLName;
this.fxmlLoader = constructFXMLLoader(stageFXMLName);
this.root = (Parent) this.fxmlLoader.load(getURL("/fxml/" + stageFXMLName).openStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private FXMLLoader constructFXMLLoader(String stageFXMLName) {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getURL(stageFXMLName));
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
return fxmlLoader;
}
public <T> T getController(Class<T> controllerType) {
// this.root = (Parent) this.fxmlLoader.load(getURL("/fxml/" + this.stageFXMLName).openStream());
T controller = controllerType.cast(this.fxmlLoader.getController());
return controller;
}
public URL getURL(String url) {
return FXMLManager.class.getResource(url);
}
public Stage getStage(String title) {
Scene scene =new Scene(this.root);
Stage stage = new Stage();
// scene.getStylesheets().add("/styles/" + TerminalUtilsDataModel.instance.getTheme() + ".css");
stage.setScene(scene);
stage.setTitle(title);
// stage.getIcons().add(new Image("/images/stage_logo.png"));
return stage;
}
}
并调用 :
FXMLManager manager = new FXMLManager(FXMLConstants.MAIN_SCREEN);
//manager.getController(MainScreen.class).setUp();
Stage stage = manager.getStage("test");
stage.show();
当您从流中加载时,FXMLLoader 不知道如何解析相对路径,因为没有相对于流的相对位置的概念。相反,在您的 FXMLManager load the FXML from a URL location that you already set on the FXMLLoader instance:
不要这样做:
this.root = (Parent) this.fxmlLoader.load(getURL("/fxml/" + stageFXMLName).openStream());
相反,这样做:
this.root = (Parent) this.fxmlLoader.load();
我正在使用 SceneBuilder 构建 javaFX 应用程序,问题是,当我在 fxml 文件中指定相对路径时,它会在运行时抛出异常:
null/../images/text_formal.png
javafx.fxml.LoadException:
unknown path:13
at javafx.fxml.FXMLLoader.constructLoadException(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at com.graduation.project.fxml.manager.FXMLManager.<init>(FXMLManager.java:26)
at com.graduation.project.Main.start(Main.java:14)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication13(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait6(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null4(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater5(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null9(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Invalid URL: Invalid URL or resource not found
at javafx.scene.image.Image.validateUrl(Unknown Source)
at javafx.scene.image.Image.<init>(Unknown Source)
at com.sun.javafx.fxml.builder.JavaFXImageBuilder.build(Unknown Source)
at com.sun.javafx.fxml.builder.JavaFXImageBuilder.build(Unknown Source)
at javafx.fxml.FXMLLoader$ValueElement.processEndElement(Unknown Source)
at javafx.fxml.FXMLLoader.processEndElement(Unknown Source)
... 13 more
无论如何,当我设置绝对路径时它工作正常,我做错了什么?
我的 fxml :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="427.0" prefWidth="482.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.graduation.project.main.gui.MainScreen">
<children>
<Pane layoutX="77.0" prefHeight="73.0" prefWidth="482.0" style="-fx- background-color: #5475ba;" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<ImageView fitHeight="150.0" fitWidth="200.0" layoutX="77.0" layoutY="52.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0">
<image>
<Image url="@../images/text_formal.png" />
</image>
</ImageView>
</children>
</AnchorPane>
加载 FXMl
public class FXMLManager{
FXMLLoader fxmlLoader;
Parent root;
String stageFXMLName;
public FXMLManager(String stageFXMLName){
try {
this.stageFXMLName = stageFXMLName;
this.fxmlLoader = constructFXMLLoader(stageFXMLName);
this.root = (Parent) this.fxmlLoader.load(getURL("/fxml/" + stageFXMLName).openStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private FXMLLoader constructFXMLLoader(String stageFXMLName) {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getURL(stageFXMLName));
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
return fxmlLoader;
}
public <T> T getController(Class<T> controllerType) {
// this.root = (Parent) this.fxmlLoader.load(getURL("/fxml/" + this.stageFXMLName).openStream());
T controller = controllerType.cast(this.fxmlLoader.getController());
return controller;
}
public URL getURL(String url) {
return FXMLManager.class.getResource(url);
}
public Stage getStage(String title) {
Scene scene =new Scene(this.root);
Stage stage = new Stage();
// scene.getStylesheets().add("/styles/" + TerminalUtilsDataModel.instance.getTheme() + ".css");
stage.setScene(scene);
stage.setTitle(title);
// stage.getIcons().add(new Image("/images/stage_logo.png"));
return stage;
}
}
并调用 :
FXMLManager manager = new FXMLManager(FXMLConstants.MAIN_SCREEN);
//manager.getController(MainScreen.class).setUp();
Stage stage = manager.getStage("test");
stage.show();
当您从流中加载时,FXMLLoader 不知道如何解析相对路径,因为没有相对于流的相对位置的概念。相反,在您的 FXMLManager load the FXML from a URL location that you already set on the FXMLLoader instance:
不要这样做:
this.root = (Parent) this.fxmlLoader.load(getURL("/fxml/" + stageFXMLName).openStream());
相反,这样做:
this.root = (Parent) this.fxmlLoader.load();