2016-05-11 68 views
2

我建立使用SceneBuilder一個JavaFX應用程序,問題是,當我指定的FXML文件的相對路徑,它在運行時拋出異常:JavaFX的SceneBuilder 2相對路徑異常

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$launchApplication1$163(Unknown Source) 
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(Unknown Source) 
at com.sun.javafx.application.PlatformImpl.lambda$null$174(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(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$null$149(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(); 
+1

膠子提供更加[SceneBuilder的現代版] (http://gluonhq.com/open-source/scene-builder/)比Oracle提供的SceneBuilder 2,你可能希望使用Gluon版本。 – jewelsea

+0

請編輯您的問題以包含您用於加載FXML文件的代碼。 – jewelsea

+0

@jewelsea謝謝,我會試試 –

回答

1

當您從一個流加載,FXMLLoader不知道如何解決相對路徑,因爲沒有關於流的相對位置的概念。相反,在你FXMLManager loadURL location that you already set on the FXMLLoader instance的FXML:

不要這樣做:

this.root = (Parent) this.fxmlLoader.load(getURL("/fxml/" + stageFXMLName).openStream()); 

相反,這樣做:

this.root = (Parent) this.fxmlLoader.load(); 
+0

大小寫關閉!非常感謝你 –