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();