Nullpointer Exception beim übertragen von Daten von Scene zu Scene

wolfin96

Mitglied
Hallo miteinander. Ich stehe gerade vor folgendem Problem: Ich habe ein Hauptfenster, diese hat verschiedene Funktionen, bei einer davon öffnet sich ein Popup Fenster indem man Daten eingeben kann. Diese Daten sollen mittels einer Methode die im HauptfensterController steht und im PopupfensterController aufgerufen wird zum Hauptfenster übertragen werden, wenn im Popupfenster auf einen Button geklickt wird. Im Hauptfenster soll mit der aufgerufenen Methode dann auch direkt mit den Daten ein Objekt erstellt werden. Wenn ich nun im Popupfenster in das Textfield etwas eingebe und auf den Button klicke erhalte ich eine Nullpointerexception die auf die Zeile im Controller verweist in der die Methode aus dem Hauptfenstercontroller steht. Kann mir da jemand weiterhelfen? Oder hat jemand einen anderen Ansatz das Problem zu lösen? Vielen Dank schon mal für eure Hilfe!

Hier der Code vom Hauptfenstercontroller:
Java:
    //Methode zum Übertragen der Daten und erstellen des Objekts
    public void qErstellen(String laenge) {
        Quadratisch quadratisch = new Quadratisch(Double.parseDouble(laenge));
        //hier wird das erstellte Objekt in einer ArrayList gespeichert
        haufen.add(quadratisch);
    }

    //Methode mit der das Popupfenster aufgerufen wird
    public void erstelleQStein(ActionEvent event) throws Exception{

        //Laden des FXML Dokuments, welches das nächste Fenster darstellt
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("Quadratisch.fxml"));
        Parent qParent = loader.load();
      
        QuadratischController controller = loader.getController();
      
        //Erstellen einer neuen Stage
        Stage stage = new Stage();
        stage.initModality(Modality.APPLICATION_MODAL);
      
        //aufrufen der Stage mit neuer Scene
        stage.setScene(new Scene(qParent));     
        stage.show(); 
  
    }

Und hier der Code vom Popupfenstercontroller:
Java:
    @FXML public TextField kantenlaengeT;
    private HauptfensterController hController;

    //wird beim Klicken auf den Button aufgerufen
    public void changeScreen(ActionEvent event) throws Exception {
      
        //aufrufen der Methode aus dem Hauptfenstercontroller
        hController.qErstellen(kantenlaengeT.getText());             
                            
    }
 
Wenn du die Instanzvariable nicht setzt, dann ist sie null.
Also noch ein Setter definieren und den dann aufrufen ehe du show aufrufst.
 
Wenn du die Instanzvariable nicht setzt, dann ist sie null.
Also noch ein Setter definieren und den dann aufrufen ehe du show aufrufst.
Du meinst einen Setter im HauptfensterController und den dann in der erstelleQStein Methode aufrufen? Ich verstehe nicht ganz wie ich dadurch an die Eingabe aus dem anderen Fenster herankomme? Danke schon mal für deine Antwort!
 
Zuletzt bearbeitet:
Nein, da wo Du die Instanzvariable hast, da brauchst Du auch den Setter ...

Und im Hauptfenster öffnest Du ja das andere Fenster:

[CODE lang="java" highlight="8,9"] //Laden des FXML Dokuments, welches das nächste Fenster darstellt
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("Quadratisch.fxml"));
Parent qParent = loader.load();

QuadratischController controller = loader.getController();

// Hier könntest Du dann doch etwas machen wie
controller.setHauptfensterController(this);

//Erstellen einer neuen Stage
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);

//aufrufen der Stage mit neuer Scene
stage.setScene(new Scene(qParent));
stage.show();
[/CODE]

Das wäre eine Möglichkeit. Generell sollte man da sich aber überlegen, wie man die Bindung zwischen den Klassen geringer halten kann. Statt da also in dem einen Contoller den anderen zu referenzieren könnte man gegen ein Interface entwickeln. Oder wenn es da nur um die Verarbeitung von Strings geht, dann kann man dem Controller evtl. einfach ein Consumer<String> geben und der würde dann gesetzt. Dann gibt es da keine Abhängigkeit zu dem ersten Controller.
Aber das kannst Du am Anfang erst einmal ignorieren, bis Du Zeit hattest, Objektorientiertes Design etwas zu vertiefen.
 
Entschuldige bitte die vielen, vermutlich offensichtlichen Nachfragen, aber mir erschließt sich nicht wie und wo ich den Setter reinschreiben soll. So wie du das hier geschrieben hast, verstehe ich es so, dass der Setter im HauptfensterController aufgerufen wird, aber da hat er doch noch keine Eingabe aus dem Popupfenster zum verarbeiten bekommen?
Ich habe unten mal einen Screenshot angehängt um mal die gewünschte Funktionalität darzustellen, vielleicht bin ich auch einfach nur zu blöd um es zu verstehen (was definitiv nicht auszuschließen ist... 😅) bin noch sehr neu in der Materie.
Nein, da wo Du die Instanzvariable hast, da brauchst Du auch den Setter ...

Und im Hauptfenster öffnest Du ja das andere Fenster:

[CODE lang="java" highlight="8,9"] //Laden des FXML Dokuments, welches das nächste Fenster darstellt
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("Quadratisch.fxml"));
Parent qParent = loader.load();

QuadratischController controller = loader.getController();

// Hier könntest Du dann doch etwas machen wie
controller.setHauptfensterController(this);

//Erstellen einer neuen Stage
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);

//aufrufen der Stage mit neuer Scene
stage.setScene(new Scene(qParent));
stage.show();
[/CODE]

Das wäre eine Möglichkeit. Generell sollte man da sich aber überlegen, wie man die Bindung zwischen den Klassen geringer halten kann. Statt da also in dem einen Contoller den anderen zu referenzieren könnte man gegen ein Interface entwickeln. Oder wenn es da nur um die Verarbeitung von Strings geht, dann kann man dem Controller evtl. einfach ein Consumer<String> geben und der würde dann gesetzt. Dann gibt es da keine Abhängigkeit zu dem ersten Controller.
Aber das kannst Du am Anfang erst einmal ignorieren, bis Du Zeit hattest, Objektorientiertes Design etwas zu vertiefen.
 

Anhänge

  • Screenshot 2021-03-23 210804.jpg
    Screenshot 2021-03-23 210804.jpg
    168,8 KB · Aufrufe: 20
Referenzen sind wie Adressen, die auf ein Objekt verweisen.

Also wenn man sich das jetzt wie Häuser vorstellt, dann habe ich ein Haus, das nach einem bestimmten Bauplan gebaut ist. Davon kann es aber beliebig viele geben: 0, wenn danach noch kein Haus gebaut wurde aber auch hunderte, so entsprechend viele Häuser davon gebaut wurden.

Was Du da jetzt hast ist ein leerer Zettel, auf dem eine Adresse zu einem Haus vom Bauplan HauptfensterController stehen könnte. So lange, wie da aber keine Adresse steht, wird jeder Versuch, da etwas in dem Haus zu machen, mit einem "Du Depp - mit einem leeren Zettel kann ich das Haus nicht finden" quittiert. (NullPointerException).

Also hinterlegst Du die Adresse. Nichts anderes ist dieser Setter. Du gibt dem PopupController die Adresse (Referenz im Java Sprachgebrauch), denn dann kann der PopupController da etwas mit machen.


Oder wie es damals bei Smalltalk gesagt wurde: Die Objekte senden sich Nachrichten. Der Hauptcontroller schickt dem PopupController eine Nachricht mit seiner Adresse. Denn dann kann der PopupController auch Nachrichten an den HauptController senden ...

Also egal, wie Du Dir das auch immer vorstellst: Das ist das, was dahinter steckt und was Du verstehen musst.
 
Referenzen sind wie Adressen, die auf ein Objekt verweisen.

Also wenn man sich das jetzt wie Häuser vorstellt, dann habe ich ein Haus, das nach einem bestimmten Bauplan gebaut ist. Davon kann es aber beliebig viele geben: 0, wenn danach noch kein Haus gebaut wurde aber auch hunderte, so entsprechend viele Häuser davon gebaut wurden.

Was Du da jetzt hast ist ein leerer Zettel, auf dem eine Adresse zu einem Haus vom Bauplan HauptfensterController stehen könnte. So lange, wie da aber keine Adresse steht, wird jeder Versuch, da etwas in dem Haus zu machen, mit einem "Du Depp - mit einem leeren Zettel kann ich das Haus nicht finden" quittiert. (NullPointerException).

Also hinterlegst Du die Adresse. Nichts anderes ist dieser Setter. Du gibt dem PopupController die Adresse (Referenz im Java Sprachgebrauch), denn dann kann der PopupController da etwas mit machen.


Oder wie es damals bei Smalltalk gesagt wurde: Die Objekte senden sich Nachrichten. Der Hauptcontroller schickt dem PopupController eine Nachricht mit seiner Adresse. Denn dann kann der PopupController auch Nachrichten an den HauptController senden ...

Also egal, wie Du Dir das auch immer vorstellst: Das ist das, was dahinter steckt und was Du verstehen musst.
Jetzt hat es bei mir Klick gemacht und es läuft! Vielen Dank für deine Geduld und deine Hilfe!
 

Zurück
Oben