2016-05-11 1 views
2

Ich baue einen JavaFX-App SceneBuilder verwenden, das Problem ist, wenn ich einen relativen Pfad in der fxml-Datei angeben, wirft es eine Ausnahme zur Laufzeit:JavaFX SceneBuilder 2 relativer Pfad Ausnahme

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 

sowieso, wenn ich setze den absoluten weg es funktioniert gut, was mache ich falsch?

mein 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> 

die FXMl Laden

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; 
    } 

} 

und Aufruf mit:

FXMLManager manager = new FXMLManager(FXMLConstants.MAIN_SCREEN); 
//manager.getController(MainScreen.class).setUp(); 
Stage stage = manager.getStage("test"); 
stage.show(); 
+1

Gluon bieten eine [moderne Version von SceneBuilder] (http://gluonhq.com/open-source/scene-builder/) als der von Oracle bereitgestellte SceneBuilder 2, möchten Sie möglicherweise stattdessen die Gluon-Version verwenden. – jewelsea

+0

Bearbeiten Sie Ihre Frage so, dass sie den Code enthält, den Sie zum Laden der FXML-Datei verwenden. – jewelsea

+0

@jewelsea danke, ich werde es versuchen –

Antwort

1

Wenn Sie aus einem Stream geladen werden, FXMLLoader nicht weiß, wie relativ zu beheben Pfade, weil es kein Konzept einer relativen Position in Bezug auf einen Stream gibt. Stattdessen in Ihrem FXMLManager load die FXML von einem URL location that you already set on the FXMLLoader instance:

Tun Sie dies nicht tun:

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

Stattdessen tun:

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

Fall geschlossen! vielen Dank –