2015-02-01 2 views
9

Sto provando a caricare il file FXML e mostrarlo come finestra dell'applicazione, ma ottengo un'eccezione. Il file FXML è stato creato da FXML Scene Builder."Posizione richiesta" eccezione durante il caricamento del file FXML

Qui ci sono i codici per la classe

public class Main extends Application { 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     primaryStage.setScene(FXMLLoader.load(getClass().getResource("sample.fxml"))); 
     primaryStage.show(); 
    } 
} 

e file di FXML

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.Button?> 
<?import javafx.scene.control.TitledPane?> 
<?import javafx.scene.layout.AnchorPane?> 
<TitledPane animated="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" 
      prefHeight="400.0" prefWidth="600.0" text="Pass4D" xmlns:fx="http://javafx.com/fxml/1" 
      xmlns="http://javafx.com/javafx/8"> 
    <content> 
     <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0"> 
      <children> 
       <Button layoutX="211.0" layoutY="134.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="177.0" 
         text="Log in"/> 
       <Button layoutX="212.0" layoutY="170.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="175.0" 
         text="Exit"/> 
      </children> 
     </AnchorPane> 
    </content> 
</TitledPane> 

E qui è l'eccezione che ottengo

Exception in Application start method 
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method 
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875) 
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157) 
    at com.sun.javafx.application.LauncherImpl$$Lambda$1/2074407503.run(Unknown Source) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.NullPointerException: Location is required. 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3201) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3169) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3142) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3118) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3098) 
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3091) 
    at Pass4D.start(Pass4D.java:19) 
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821) 
    at com.sun.javafx.application.LauncherImpl$$Lambda$51/317090070.run(Unknown Source) 
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323) 
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/1833150059.run(Unknown Source) 
    at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292) 
    at com.sun.javafx.application.PlatformImpl$$Lambda$49/2115863517.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291) 
    at com.sun.javafx.application.PlatformImpl$$Lambda$48/1436737924.run(Unknown Source) 
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) 

Che cosa sto facendo di sbagliato?

p.s. qui è la struttura del progetto

enter image description here

+0

Qual è la struttura del progetto? In particolare, dov'è 'sample.fxml' in relazione alla tua classe' Main'? –

+0

eccolo, ho aggiornato il post – Carmine

risposta

10

La risposta breve è getClass().getResource("sample.fxml") rendimenti null in silenzio se la risorsa non può essere trovato sul runtime classpath, non la directory corrente eccetera.

Quindi questo dipende dalla configurazione del progetto IDE, se si sta utilizzando eclipse provare ad aggiungere la cartella che sample.fxml risiede nella configurazione di esecuzione.

Alcune idee ...

  • provare getClass().getResource("/sample.fxml") invece ...
  • provare a spostare sample.fxml nella cartella risorse. Non so molto del tuo IDE, ma sospetto che la cartella sia usata solo per i file .java ... questo è certamente vero per i progetti gradle in eclipse - le risorse devono essere nell'albero src/main/resources come solo quelle aggiunte al runtime classpath ...
+0

moving ha aiutato la cartella delle risorse, no ho capito cosa c'era di sbagliato, grazie mille!) – Carmine

+6

In Intellij, la combinazione di 'moving sample.fxml nella cartella risorse' e' getClass(). getResource ("/ sample.fxml ")" ha funzionato per me. Ho dovuto creare una directory "risorse" allo stesso livello della cartella principale. –

1

Prova questo esempio da Oracle:

@Override 
public void start(Stage stage) throws Exception { 
    Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml")); 

    Scene scene = new Scene(root, 300, 275); 

    stage.setTitle("FXML Welcome"); 
    stage.setScene(scene); 
    stage.show(); 
} 
+1

Sto ottenendo la stessa eccezione – Carmine

+0

Forse mi manca qualcosa nelle configurazioni del progetto? Inizialmente il progetto non doveva essere un programma JavaFX, quindi è stato creato come un'applicazione vuota, quindi forse mi manca qualcosa lì? – Carmine

+0

Ok perché ha funzionato per me quindi non so scusa – Johan

2

Ho già postato questo oggi, ecco di nuovo, spero che ti aiuta.

Ecco una soluzione che funziona nell'ambiente di sviluppo, in Scene Builder e in un pacchetto JAR.

La struttura delle cartelle:

enter image description here

Main.java:

package application; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Scene; 
import javafx.scene.layout.AnchorPane; 
import javafx.stage.Stage; 


public class Main extends Application { 
    @Override 
    public void start(Stage primaryStage) { 
     try { 

      FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/RootLayout.fxml")); 
      AnchorPane rootLayout = (AnchorPane) loader.load(); 

      Scene scene = new Scene(rootLayout, 400, 400); 
      scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm()); 

      primaryStage.setScene(scene); 
      primaryStage.show(); 

     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

RootLayout.fxml:

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 
<?import javafx.scene.layout.AnchorPane?> 

<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.view.RootLayoutController"> 
    <children> 
     <Pane layoutX="0.0" layoutY="0.0" prefHeight="200.0" prefWidth="200.0"> 
     <children> 
      <Button fx:id="sunButton" layoutX="74.0" layoutY="88.0" mnemonicParsing="false" onAction="#handleSunButtonClick" styleClass="sun-button" stylesheets="@../css/toolbar.css" text="Button" /> 
     </children> 
     </Pane> 
    </children> 
</AnchorPane> 

RootLayoutController.java:

package application.view; 

import javafx.fxml.FXML; 
import javafx.scene.control.Button; 

public class RootLayoutController { 


    @FXML 
    Button sunButton; 

    @FXML 
    public void handleSunButtonClick() { 
     System.out.println("Button clicked"); 
    } 
} 

toolbar.css:

.sun-button { 
    -fx-graphic: url('./icons/sun.png'); 
} 

application.css:

.root { 
    -fx-background-color:lightgray; 
} 

sun.png:

enter image description here

Questo funziona sia in ambiente di sviluppo e quando il pacchetto il JAR (scegliere "Estrai librerie richieste in JAR generato" in Eclipse).

Schermata (solo un pulsante con l'icona caricata tramite CSS)

enter image description here