2017-08-24 8 views
0

Ich hoffe, dass jemand mir entweder erklären kann, was ich falsch mache, oder mich auf die Antwort zeigen, wenn diese vorher beantwortet worden ist (ich habe 2 Tage lang herumgesucht und nach einer Antwort gesucht).Warum wird mein JavaFX-Controller nicht geladen?

Ich versuche, eine Demo-Anwendung zu erstellen, die eine JavaFX-GUI startet. Wenn mein app ist bereit, die GUI zu starten (die App hat die Dinge im Hintergrund kümmern zuerst), nenne ich:

Application.launch(StarFXDemo.class, ""); 

Hier ist StarFXDemo.java:

package standalonedemo; 

import java.io.IOException; 
import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class StarFXDemo extends Application 
{ 

    @Override 
    public void start(Stage stage) throws Exception 
    { 
     Parent root = null; 
     try 
     { 
      root = FXMLLoader.load(getClass().getResource("StarFXDemoDoc.fxml")); 
     } catch (IOException ioe) 
     { 
      ioe.printStackTrace(System.out); 
     } 

     Scene scene = new Scene(root); 
     stage.setScene(scene); 
     stage.show(); 
    } 
} 

StarFXDemoDoc.fxml ist in der JAR-Datei & ist das gleiche Paket wie StarFXDemo (anstatt in einem anderen Paket oder in einem Unterpaket). So

getClass().getResource("/standalonedemo/resources/StarFXDemoDoc.fxml") 

kommt zurück mit einer URL in die Datei.

StarFXDemoDoc.fxml ist dies:

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

<?import standalonedemo.*?> 
<?import javafx.geometry.*?> 
<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<TitledPane animated="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" text="FX Sim Demo" 
      xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" 
      fx:controller="standalonedemo.StarFXDemoDocController"> 
    <content> 
    <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0"> 
     <children> 
      <VBox prefHeight="85.0" prefWidth="322.0" spacing="5.0" style="-fx-background-color: coral;"> 
       <children> 
        <Label text="Sim Title" /> 
        <TextField fx:id="SimNameField" onMouseDragExited="#setSimulationName" /> 
       </children> 
       <padding> 
        <Insets left="25.0" top="15.0" /> 
       </padding> 
      </VBox> 
      <Button fx:id="BuildSphereButton" layoutX="14.0" layoutY="100.0" mnemonicParsing="false" onAction="#buildSphereAction" text="Build Sphere" /> 
     </children></AnchorPane> 
    </content> 
</TitledPane> 

Und StarFXDemoDocController.java ist dies:

package standalonedemo; 

import java.net.URL; 
import java.util.ResourceBundle; 
import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.Button; 
import javafx.scene.control.TextField; 

public class StarFXDemoDocController implements Initializable 
{ 
    @FXML 
    private TextField SimNameField; 
    @FXML 
    private Button BuildSphereButton; 

    /** 
    * RequiredConstructor 
    */ 
    public StarFXDemoDocController() {} 

    @Override 
    public void initialize(URL url, ResourceBundle rb) 
    { 

    } 

    @FXML 
    private void buildSphereAction(ActionEvent event) 
    { 

    } 

    @FXML 
    private void setSimulationName() 
    { 

    } 
} 

Es gibt nichts wirklich in den Methoden noch, weil ich gerade bin versucht, die GUI zu bekommen erscheinen zu dieser Zeit. Ich habe den leeren Konstruktor und die @ FXML-Tags auf den GUI-Elementen mit fx: id -Tags (sowie ihre entsprechenden Methoden).

Wenn ich das Programm laufen, an der Stelle nenne ich

FXMLLoader.load(getClass().getResource("/standalonedemo/resources/StarFXDemoDoc.fxml")); 

es wirft die folgende Ausnahme (diese Ausnahme nicht mehr relevant ist, finden Sie in der Ausnahme unten):

Ich gehe davon aus ich habe etwas falsch formatiert, aber ich habe keine Ahnung was es ist.

Kann mir hier jemand helfen?

EDIT/UPDATE:

Per James_D Kommentare (danke James, offensichtlich hatte ich zu lange für Art und Weise an, dass starrend ...), feste ich die offensichtlichen Fehler in meinem Controller und machte SimNameField eine TextField- , anstatt einer Beschriftung (und aktualisiert den Code-Block oben, um dies zu reflektieren). Ich änderte auch die Ausnahmebehandlung, um printStackTrace zu verwenden. Die Änderungen hol mir jetzt folgenden Stack-Trace:

javafx.fxml.LoadException: file:<properPathTo>/StandAloneDemo/dist/StandAloneDemo.jar!/standalonedemo/resources/StarFXDemoDoc.fxml:11 
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601) 
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)    
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:922) 
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971) 
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)     
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)   
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)      
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)         
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)         
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)         
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)         
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)         
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)         
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)         
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)          
at standalonedemo.StarFXDemo.start(StarFXDemo.java:35)          
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863) 
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)   
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)    
at java.security.AccessController.doPrivileged(Native Method)         
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)   
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)    
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)         
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)     
at java.lang.Thread.run(Thread.java:745)              
Caused by: java.lang.ClassNotFoundException: standalonedemo.StarFXDemoDocController starting from SystemClassLoader[55 modules] with possible defining loaders null and declared parents [[email protected], [email protected][org.netbeans.api.annotations.common], [email protected][org.openide.awt], [email protected][org.netbeans.api.progress], [email protected][org.netbeans.swing.plaf], [email protected][org.openide.dialogs], [email protected][org.openide.nodes], [email protected][org.openide.windows], [email protected][org.netbeans.swing.tabcontrol], [email protected][org.netbeans.swing.outline], ...40 more]             
at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:224)                                       
at org.netbeans.ModuleManager$SystemClassLoader.loadClass(ModuleManager.java:722)                                    
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)                                          
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:920)                                     
... 22 more                                                     
Caused by: java.lang.ClassNotFoundException: standalonedemo.StarFXDemoDocController                                     
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)                                         
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)                                          
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)                                        
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)                                          
at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:222)                                       
... 25 more             

So sehe ich das ClassNotFoundException, die mich bekam an meiner Controller-Klasse zu beginnen, einige mehr, und ich bemerkte, dass Scene Builder alles hat aber entschieden, dass meine TextField- doesn Wenn ich die fx: id von simNameField dem TextField in Scene Builder zuweiße, erhalte ich die Warnung "Kein injizierbares Feld ..." und klicke mit der rechten Maustaste auf das Feld fx: id für das Steuerelement zeigt das buildSphereButton-Tag). Also habe ich das simNameField aus der Controller-Klasse entfernt, mit der rechten Maustaste auf die FXML-Datei in NetBeans geklickt und es zu Make Controller gebracht. Es fügte das TextField mit dem richtigen fx: id und @FXML-Tag zurück. Scene Builder denkt immer noch, dass es eine fx: id ohne ein injizierbares Feld ist.

Also habe ich offensichtlich eine Art der Trennung zwischen dem FXML und dem Controller, aber ich habe keine Ahnung, was es sein könnte?

UPDATE2:

Nahm den ersten Stack-Trace aus, da es nicht mehr relevant und aktualisierte ein paar Zeilen Code (wie das Hinzufügen des Imports für das Paket zu dem FXML).

Spielend damit gespielt. Wenn ich die Controller-Referenz entferne, startet die GUI wie erwartet (wir wissen also, dass die FXML-Datei geladen wird). Wenn ich ein Controller-Objekt instanziiere (bevor ich FXMLLoader.load (< ...>)), instanziiert es wie erwartet, und ich kann überprüfen, dass es über den NetBeans-Debugger nicht null ist, also weiß ich, dass die Controller-Klasse kompiliert wird und auf dem Klassenpfad.

Warum kann der FXMLLoader das nicht finden? Sollte ich eine alternative Methode verwenden, um es zu laden? Ich habe darüber nachgedacht, das Controller-Objekt im Code zu erstellen und es auf diese Weise zu setzen, aber das scheint NetBeans zu stören, wenn es um die fx: controller-Anweisung geht (dh wenn Sie Elemente in der FXML haben, die einen Controller erfordern) Anweisung ist nicht da, NetBeans kennzeichnet es als falsch).

+1

Das sieht nicht wie die komplette Stack-Trace aus. Normalerweise gibt es dort "Caused by" -Abschnitte (und es hat normalerweise verschiedene Formatierungen, etc.) –

+2

Eigentlich sollten die "cause by" -Abschnitte, die Sie nicht gepostet haben, ziemlich klar sagen, dass Sie versuchen, ein 'TextField' zuzuweisen 'Label' ... –

+0

Das war der gesamte Stack-Trace, den ich von der IOException bekommen habe (ich habe dem catch-Block eine Schleife hinzugefügt, um den vollständigen Stack-Trace zu erhalten). Gibt es noch eine Ausnahme, die ich hätte suchen müssen, um mehr auszugeben? – sngillis

Antwort

4

Im FXML haben Sie

<TextField fx:id="SimNameField" onMouseDragExited="#setSimulationName" /> 

aber in der Steuerung haben Sie

@FXML 
private Label SimNameField ; 

Dieser versucht, ein Textfeld in ein Feld vom Typ Label, zuweisen, die einen Fehler bei Laufe verursachen Zeit.

+0

Verdammte Hölle, wie habe ich das vermisst? – sngillis

+1

@sngillis Durch nicht anzeigen und Lesen der kompletten Stack-Trace ... :) –

0

FYI für jeden, der über diese läuft, habe ich das Problem nach einer Mode gelöst. Ich habe immer noch keine Ahnung, warum das gepostete Setup nicht funktioniert hat, ich denke, es hat etwas mit Pfaden und Paketreferenzen zu tun.

Wie dem auch sei, ich konnte es so funktioniert:

URL fxmlFile = getClass().getResource("/standalonedemo/resources/StarFXDemoDoc.fxml"); 
StarFXDemoDocController sdCon = new StarFXDemoDocController(); 
FXMLLoader loader = new FXMLLoader(fxmlFile); 
loader.setController(sdCon); 
root = (TitledPane) loader.load(); 

Jetzt funktioniert es wie erwartet.

Verwandte Themen