2016-04-11 18 views
0

Das hat schlage ich meinen Kopf gegen die Wand !!!! Hoffe, jemand kann mich in die richtige Richtung weisen. Ich bin mir sicher, dass ich etwas komplett DUMM UND DUMB mache. Ich habe gesucht und gesucht, aber kann nicht herausfinden, warum das nicht funktioniert !! (Verwenden von JDK8.x mit Scenebuilder auf IntelliJ IDE 15.x). Ich versuche, Daten auf dem GUI anzuzeigen, aber will Zugang haben, um diese Daten von anderen Klassen/Methoden programmatisch zu senden .... hier ist ein einfaches Konzept, das ich versuche, Arbeit zu machen, bevor ich an meinem größeren Projekt arbeite:JavaFX Zugriffsfunktion in Controller-Klasse von Haupt

Main Class: 

package sample; 

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 Main extends Application { 

Controller myController = new Controller(); 

@Override 
public void start(Stage primaryStage) throws Exception{ 
    Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); 
    primaryStage.setTitle("Hello World"); 
    primaryStage.setScene(new Scene(root, 345, 200)); 
    primaryStage.show(); 
    myController.pushBtn(); 
} 

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

Meine einfache GUI, definiert in FXML mit Scenebuilder Controller-Klasse:

package sample; 

import java.net.URL; 
import java.util.ResourceBundle; 

import javafx.application.Platform; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.fxml.FXML; 
import javafx.scene.control.Button; 
import javafx.scene.control.TextField; 

public class Controller { 

@FXML // ResourceBundle that was given to the FXMLLoader 
private ResourceBundle resources; 

@FXML // URL location of the FXML file that was given to the FXMLLoader 
private URL location; 

@FXML // fx:id="txtBox" 
private TextField txtBox; // Value injected by FXMLLoader 

@FXML // fx:id="myButton" 
private Button myButton; // Value injected by FXMLLoader 

@FXML // This method is called by the FXMLLoader when initialization is complete 
void initialize() { 
    assert txtBox != null : "fx:id=\"txtBox\" was not injected: check your FXML file 'sample.fxml'."; 
    assert myButton != null : "fx:id=\"myButton\" was not injected: check  our FXML file 'sample.fxml'."; 
} 
@FXML 
private void pressBtn(ActionEvent event){ 
    txtBox.setText("Btn was pushed..."); 
} 

@FXML 
public void pushBtn(){ 
    txtBox.appendText("Sample from Main"); 
} 

} 

..und Finaly meine sehr einfache FXML Datei, zusammen mit den IDs und Event-Handler-Tags:

<GridPane alignment="center" hgap="10" vgap="10"  xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65"  fx:controller="sample.Controller"> 
    <columnConstraints> 
    <ColumnConstraints /> 
    </columnConstraints> 
    <rowConstraints> 
    <RowConstraints /> 
</rowConstraints> 
<children> 
    <Pane prefHeight="200.0" prefWidth="345.0" style="-fx-background-color: GRAY;"> 
     <children> 
     <TextField fx:id="txtBox" layoutX="63.0" layoutY="28.0"  prefHeight="53.0" prefWidth="224.0" style="-fx-background-color: LIGHTGRAY;" /> 
      <Button fx:id="myButton" layoutX="140.0" layoutY="100.0" mnemonicParsing="false" onAction="#pressBtn" text="Button" /> 
     </children> 
     </Pane> 
    </children> 
</GridPane> 

Alles, was ich zu tun versuche, ist eine Funktion aufzurufen, die Öffentlichkeit über die Controller-Klasse deklariert wurde, und haben diese Funktion Ort Text in meinem txtBox, die mit FXML definiert wurde, wie man sehen kann. Ich erstelle eine Instanz dieser Controller-Klasse in main und verwende dann diese Instanz, um auf diese Methode zuzugreifen. Alles, was ich hier gelesen und gesucht habe, weist darauf hin, dass dies der richtige Weg ist. Dies ist jedoch nie funktioniert, und alles, was ich bekommen, ist ein Fehler als solche:

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:917) 
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImp l.java:182) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.NullPointerException 
    at sample.Controller.pushBtn(Controller.java:43) 
at sample.Main.start(Main.java:20) 
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherIm pl.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.win.WinApplication._runLoop(Native Method) 
at  com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) 
... 1 more ` 

Was zum Teufel bin ich dabei? Gibt es eine andere Möglichkeit, dies zu nennen, initialisiere ich etwas nicht? WIRKLICH schätzen irgendein Rückgespräch !!!

+0

Es scheint, Ihr 'txtBox' im' PushBtn' Aufruf null ist. Vielleicht ist die Initialisierung noch nicht abgeschlossen, wenn Sie versuchen, sie manuell aufzurufen. –

+0

* "Ich erstelle eine Instanz dieser Controller-Klasse in main" *. Nun, das ist das Problem. Diese Instanz ist nicht der Controller. –

Antwort

1

Sie eine zweite Controller Instanz erstellen, wenn Sie new Controller() nennen. Dies ist natürlich nicht die Controller Instanz, die von der FXMLLoader erstellt wurde, wenn Sie die FXML-Datei geladen haben, so dass keine der @FXML -injizierten Felder initialisiert werden.

Sie benötigen die Controller Instanz aus dem FXMLLoader zu bekommen:

package sample ; 

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 Main extends Application { 


    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml")); 
     Parent root = loader.load(); 

     Controller myController = loader.getController(); 

     primaryStage.setTitle("Hello World"); 
     primaryStage.setScene(new Scene(root, 345, 200)); 
     primaryStage.show(); 
     myController.pushBtn(); 

    } 

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

SIE SIND EIN GENIUS !!! Vielen Dank für das Auswählen! Das war genau mein dummes Problem .... Danke nochmal! – CYBORGCNC