Elemente auf vorheriger Stage, nach Wechsel der Stage ansprechen

Tintenfisch

Bekanntes Mitglied
Hallo allerseits,
Zur Lege: Ich greife aus ControllerClassA auf eine Methode in einer ControllerClassB zu, welche ein Pop-Up Öffnet. Mit dem Pup-Up kann durch einen Button wieder auf eine Methode in der ControllerClassA zugegriffen werden. Dies Funktioniert auch alles reibungslos, jedoch musste ich feststellen, dass nun zurück in der ControllerClassA, keine Elemente in dieser Klasse, wie Textfelder mehr geändert werden können. Quasi als wäre die "Sitzung", nach dem Öffnen einer neuen Stage (dem Pop-Up), dort abgelaufen.
Würde mich freuen, wenn jemand eine Idee hätte, wie man die Elemente wieder wie gewohnt ändern kann.
 
Y

yfons123

Gast
meinst du dass das haupt fenster nicht "benutztbar" ist solange b offen ist ? das wäre die window modality .. das ist das bekannte wenn ein pop up aufkommt und du in den hintergrund klickst und dann der windows fehler sound kommt, dh das hauptfesnter ist immun gegen user input aber nicht von code änderungen

zb du änderst durch code den text dann kann der text im hauptfenster geändert werden, aber nicht durch eingabe von maus oder tastatur

( das alles gilt wenn du javafx hernimmst )
 

Tintenfisch

Bekanntes Mitglied
meinst du dass das haupt fenster nicht "benutztbar" ist solange b offen ist ? das wäre die window modality .. das ist das bekannte wenn ein pop up aufkommt und du in den hintergrund klickst und dann der windows fehler sound kommt, dh das hauptfesnter ist immun gegen user input aber nicht von code änderungen

zb du änderst durch code den text dann kann der text im hauptfenster geändert werden, aber nicht durch eingabe von maus oder tastatur

( das alles gilt wenn du javafx hernimmst )
Vorab vielen dank für die Antwort.
Klicken tue ich nur im Pop-Up, jedoch wird durch den Klick auf eine Methode in der Klasse vor dem Pop-Up zugegriffen. Die Logik in der Methode funktioniert auch, nur soll zuletzt noch der Inhalt der Felder (nicht im Pop-Up, sondern in der vorherigen Stage) entfernt werden mit textfield.clear();.
Da dies bisher ohne Pop-Up keinerlei Probleme dargestellt hat, stehe ich dabei bisschen auf dem Schlauch.

Zudem scheint es unabhängig davon zu sein, ob das Pop-Up beim Methodenzugriff bereits geschlossen ist oder nicht, da beides das selbe Ergebnis zeigt.
 
Y

yfons123

Gast
vllt zeigst du mal code und erklärst anhand vom code woran du denkst dass es nicht passt.. das texfeld.clear muss funktionieren das kann nicht nicht funtkionieren
 

Tintenfisch

Bekanntes Mitglied
vllt zeigst du mal code und erklärst anhand vom code woran du denkst dass es nicht passt.. das texfeld.clear muss funktionieren das kann nicht nicht funtkionieren
bis auf das clear(); funktioniert alles in der Methode und die fx:id ist in der FXML ist auch okay.

Java:
public class ControllerClassA {
   
    @FXML private TextField isinTFInput;
   
    public void deleteOrderItem () throws SQLException, IOException {
        String isin = tempItemDelete;
        String tableType = tempTableDelete;
               
        DBStatement dbStatement = new DBStatement();
       
        if (tableType == "Buy") {
            dbStatement.deleteItemFromDB("buyData", "isin", isin);
        } else if (tableType == "Sell") {
            dbStatement.deleteItemFromDB("sellData", "isin", isin);
        } else if (tableType == "") {

        }
       
        isinTFInput.clear();
    }
}
 
Y

yfons123

Gast
kannst du ein system out println for das clear setzen ob du überhaupt da hin kommst

und wer ruft die methode auf und wie ?
 

KonradN

Super-Moderator
Mitarbeiter
Woher kommt denn der Wert in tempTableDelete? Du macht String Vergleiche mit == was nur funktioniert, wenn die Strings die gleiche Referenz haben und die sind nur gleich, wenn diese per String.intern() auf einer String-Liste des Systems stehen (was nur der Fall ist für Literale und so).

Die Chance ist also groß, dass es einfach nur an den Vergleichen liegt, dass Deine Methode deleteOrderItem nichts macht, da einfach keine Bedingung wahr ist.

Ein Vergleich wie: (tableType == "Buy") sollte also etwas sein wie:
("Buy".equals(tableType))
oder
(Objects.equals(tableType, "Buy"))
oder wenn sicher ist, dass tableType nicht null sein kann:
(tableType.equals("Buy"))

Und das Gleiche gilt halt für alle Bedingungen, die Du abprüfen willst.

Alternativ kann man hier natürlich auch mit einem Switch Statement arbeiten.
 

Tintenfisch

Bekanntes Mitglied
kannst du ein system out println for das clear setzen ob du überhaupt da hin kommst

und wer ruft die methode auf und wie ?
Bis dahin kommt es, der Code zuvor wird auch ausgeführt.
Aufrufen tut die Methode das Pop-Up mit einer separaten Klasse. Das Funktionier auch alles soweit.

Ich habe eben das TextField an sich in ein Sys.out gesetzt, es wird an sich auch erkannt, zeigt die korrekte id und so.
Java:
public class ControllerClassB {
    
    public void confirmOderOptionDelition (ActionEvent event) throws IOException, SQLException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlString));
        root = loader.load();
        if (fxmlString.equals("Options.fxml")) {
            FXMLOptionsController optionsController = loader.getController();
            optionsController.getListViewItemAndDelete();
        } else if (fxmlString.equals("Input.fxml")) {
            FXMLInputController inputController = loader.getController();
            inputController.deleteOrderItem();
            
        }
        stage = (Stage)((Node)event.getSource()).getScene().getWindow();
        stage.close();
    }
}
 

Tintenfisch

Bekanntes Mitglied
Woher kommt denn der Wert in tempTableDelete? Du macht String Vergleiche mit == was nur funktioniert, wenn die Strings die gleiche Referenz haben und die sind nur gleich, wenn diese per String.intern() auf einer String-Liste des Systems stehen (was nur der Fall ist für Literale und so).

Die Chance ist also groß, dass es einfach nur an den Vergleichen liegt, dass Deine Methode deleteOrderItem nichts macht, da einfach keine Bedingung wahr ist.

Ein Vergleich wie: (tableType == "Buy") sollte also etwas sein wie:
("Buy".equals(tableType))
oder
(Objects.equals(tableType, "Buy"))
oder wenn sicher ist, dass tableType nicht null sein kann:
(tableType.equals("Buy"))

Und das Gleiche gilt halt für alle Bedingungen, die Du abprüfen willst.

Alternativ kann man hier natürlich auch mit einem Switch Statement arbeiten.
tempDeleteItem kommt ursprünglich aus dem TextField isinTFInput und wird in einer vorherigen Methode zwischengespeichert. Gut zu wissen, danke, dann sollte ich mir das mit dem equals echt mal angewöhnen.
An sich funktioniert der Code in der Methode allerdings. Es hängt irgendwie nur am isinTFInput.clear();
 
Y

yfons123

Gast
isinTFInput.setText("");
du kannst das probieren da .clear() versucht das caret und den fokus zu korrigieren aber dein window kann keinen fokus haben vllt hängts daran
Java:
    /**
     * Clears the text.
     */
    public void clear() {
        deselect();
        if (!text.isBound()) {
            setText("");
        }
    }
... oracle docs vom feinsten ( ich gehe davon aus dass das wirklich dein ganzer code ist und kein ausgeschnipsle )
 

KonradN

Super-Moderator
Mitarbeiter
tempDeleteItem kommt ursprünglich aus dem TextField
Dann sollte es eigentlich nie funktionieren, denn die Strings aus dem TextField sollten nie Referenzgleich zu irgendwelchen Literalen sein.

Ein einfacher schneller Test nur für Dich:
Java:
package application;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.event.ActionEvent;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

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

    private TextField textField;
    @Override
    public void start(Stage primaryStage) {

        Pane pane = new Pane();
        textField = new TextField();
        pane.getChildren().add(textField);
        Scene scene = new Scene(pane);
        primaryStage.setScene(scene);
        primaryStage.show();

        textField.textProperty().addListener(this::textFieldAction);
    }

    private void textFieldAction(Observable observable) {
        String text = textField.getText();
        if (text == "Hallo") {
            System.out.println("Hallo gefunden!");
        } else {
            System.out.println("'" + text + "' is not 'Hallo'");
        }
    }

}

Und siehe da - wenn Du da Hallo eingibst, bekommst Du die Ausgabe:
Code:
'H' is not 'Hallo'
'Ha' is not 'Hallo'
'Hal' is not 'Hallo'
'Hall' is not 'Hallo'
'Hallo' is not 'Hallo'
 

Tintenfisch

Bekanntes Mitglied
du kannst das probieren da .clear() versucht das caret und den fokus zu korrigieren aber dein window kann keinen fokus haben vllt hängts daran
Java:
    /**
     * Clears the text.
     */
cs vom feinsten ( ich gehe davon aus dass das wirklich dein ganzer code ist und kein ausgeschnipsle )
[/QUOTE]
leider auch ohne Erfolg. Wenn ich get.text(); in einem System.out. versuche, wird ebenso nichts ausgegeben.
 
Y

yfons123

Gast
kann es sein dass du einen zweiten controller erstellt hast und nicht den echten referenzierst sondern den zweiten
 

Tintenfisch

Bekanntes Mitglied
Aber dann weiß ich schonmal, dass das an sich kein Problem sein dürfte und es einfach nur an dem Fehler meinerseits liegt. Dann mach ich mich mal nach und nach auf die Suche danach.

Vielen dank beiderseits :)

Ich muss tatsächlich nochmal auf das Thema zurückkommen, denn leider hat sich noch keinerlei Lösung gefunden. Allerdings ist es nun an anderer Stelle zu dem gleichen Problem gekommen. Diesmal ist es eine TableView, welche nicht auf Änderungen reagiert.
Allgemein lässt sich sagen, dass wenn eine onAction Methode in einer anderen Klasse, als die, die für die angezeigte Oberfläche zuständig ist, aufgerufen wird, die Oberfläche keine Veränderungen anzeigt. Egal ob Text Änderungen im Textfeld, auf Buttons oder Tables, Änderungen werden nicht angezeigt, jedoch auch kein Fehler gemeldet.
Leider erklärt sich dies für mich ganz und gar nicht, daher bitte ich nochmals um eure Unterstützung.
 

Tintenfisch

Bekanntes Mitglied
dann poste deinen code und mach kein rate spiel draus
onAction funktioniert soweit und die Methode im Controller wird auch erreicht. Das Problem stellt sich ähnlich dar, wie das zuerst gezeigte in diesem Thema, mit fehlender Reaktion der GUI.

Java:
// Klasse für Daten der TableView
public class Order {
    private int id;

    public Order (int id) {
        this.idEx = id;
 
        this.editBtEx = new Button("Edit");
        this.deleteBtEx = new Button("Delete");
        this.optionHBEx = new HBox(this.editBtEx, this.deleteBtEx);
     
        this.deleteBtEx.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                DBStatement dbStatement = new DBStatement();
                try {
                    dbStatement.deleteItemFromDB("id", id);
                    try {
                        FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
                        Parent root = loader.load();
                        FXMLViewController controller = loader.getController();
                        controller.existingAssetsTab.setText("test");
                        controller.removeItemFromTableView (int tableViewIndex);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}


Java:
    // In Controller Class der betroffenen Scene
    public void  removeItemFromTableView (int tableViewIndex) {

        exTableView.getItems().clear();
        setDataExistingAssetsTableView();
        exTableView.refresh();
        existingAssetsTab.setText("test"); // nur als Test, funktioniert nicht, genau wie getText, zeigt jedoch keinerlei Fehler
        System.out.println("Test"); // funktioniert
    }
public void setDataBuyTableView () {
        DBStatement dbStatement = new DBStatement();
        try {
            buyTableView.setItems(dbStatement.getBuyOrders());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
 
Zuletzt bearbeitet:

Tintenfisch

Bekanntes Mitglied
Theoretisch erscheint es mir so, als würde auf die Attribute einer anderen Instanz zugegriffen werden, da der Zugriff auf die jeweiligen Methoden reibungslos funktioniert, jedoch die Attribute zwar angesprochen werden können, also keinen Fehler zeigen, aber in der GUI nicht reagieren.
Vom Code her dürfte das zwar meines Erachtens zwar nicht sein, aber war so ein Gedanke.
 
Y

yfons123

Gast
die GUI kann nicht nicht reagieren... ich denke mal wie auch oben schon erwähnt setzt du 1e gui auf den bildschirm und mit der tust du nix, und eine GUI hast du nur als objekt ohne szene graph am laufen dh du setzt vom falschen die werte.. du wirst 2 objekte haben

existingAssetsTab.setText("test"); // nur als Test, funktioniert nicht, genau wie getText, zeigt jedoch keinerlei Fehler

könntest du vllt das ganze teil wo hochladen oder ein teilbares paket geben ? ( zb in git )

EDIT: möchte nurmal auf #13 verweisen.. .hust hust..

Java:
                        FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
                        Parent root = loader.load();
                        FXMLViewController controller = loader.getController();
                        controller.existingAssetsTab.setText("test");
                        controller.removeItemFromTableView (int tableViewIndex);
zb hier setzt du root niemals in den szene graphen ein vllt im controller dass er sich selber einsetzt aber das bezweifle ich gerade mal weil du sonst nicht root geholt hättest

und da es hier passiert ist denke ich mal dass es auch woanders passiert sein könnte
 
Zuletzt bearbeitet von einem Moderator:

Tintenfisch

Bekanntes Mitglied
die GUI kann nicht nicht reagieren... ich denke mal wie auch oben schon erwähnt setzt du 1e gui auf den bildschirm und mit der tust du nix, und eine GUI hast du nur als objekt ohne szene graph am laufen dh du setzt vom falschen die werte.. du wirst 2 objekte haben



könntest du vllt das ganze teil wo hochladen oder ein teilbares paket geben ? ( zb in git )

EDIT: möchte nurmal auf #13 verweisen.. .hust hust..

Java:
                        FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
                        Parent root = loader.load();
                        FXMLViewController controller = loader.getController();
                        controller.existingAssetsTab.setText("test");
                        controller.removeItemFromTableView (int tableViewIndex);
zb hier setzt du root niemals in den szene graphen ein vllt im controller dass er sich selber einsetzt aber das bezweifle ich gerade mal weil du sonst nicht root geholt hättest

und da es hier passiert ist denke ich mal dass es auch woanders passiert sein könnte
Inwieweit root in den Scene Graphen setzen, tatsächlich habe ich das überall so. Später hatte ich das "Parent root" weggelassen, da es mit "loader.load(); genau so funktionierte (oder eben auch nicht). Die Scene kommt bei mir an sich nur dann, wenn ich eine neue erstellen muss, für eine andere Seite.
Java:
FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
loader.load();
FXMLViewController controller = loader.getController();
controller.existingAssetsTab.setText("test");
 
Y

yfons123

Gast
mich wundert es gerade dass du irgendwas auf den bildschirm hast

1. du musst eine scene haben die ein root element hat was auch immer das ist
2. wenn du ein FXML lädst musst du das auch einklinken in die szene/node baum um das auch sehen zu können

das ist was du tust
FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
du richtest dir einen großen eimer her um sachen rein zu tun
du sammelst dir paar buttons und tust sie dir in deinen eimer
FXMLViewController controller = loader.getController();
holst dir den könig der sachen die du in den eimer gepackt hast
controller.existingAssetsTab.setText("test");
sagst dem könig dass er den text von seinen leuten ändern soll

und dann wirfst du den eimer mit einer beeindruckenden geschwindigkeit vom fenster raus weil du ihn niemals speicherst.. und das fenster wäre in java der garbage collector der alles aufsammelt was du nicht mehr benutzen kannst

Java:
                        FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
                        Parent root = loader.load();
                        FXMLViewController controller = loader.getController();
                        controller.existingAssetsTab.setText("test");
                        controller.removeItemFromTableView (int tableViewIndex);
alle diese objekte sind nach dem durchlauf nicht mehr benutzbar weil du sie in eine geschweifte klammer geschrieben hast und nirgendswo außerhalb gespeichert oder referenziert hast ( was ansich das gleiche ist )
 

Tintenfisch

Bekanntes Mitglied
mich wundert es gerade dass du irgendwas auf den bildschirm hast

1. du musst eine scene haben die ein root element hat was auch immer das ist
2. wenn du ein FXML lädst musst du das auch einklinken in die szene/node baum um das auch sehen zu können

das ist was du tust

du richtest dir einen großen eimer her um sachen rein zu tun

du sammelst dir paar buttons und tust sie dir in deinen eimer

holst dir den könig der sachen die du in den eimer gepackt hast

sagst dem könig dass er den text von seinen leuten ändern soll

und dann wirfst du den eimer mit einer beeindruckenden geschwindigkeit vom fenster raus weil du ihn niemals speicherst.. und das fenster wäre in java der garbage collector der alles aufsammelt was du nicht mehr benutzen kannst

Java:
                        FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
                        Parent root = loader.load();
                        FXMLViewController controller = loader.getController();
                        controller.existingAssetsTab.setText("test");
                        controller.removeItemFromTableView (int tableViewIndex);
alle diese objekte sind nach dem durchlauf nicht mehr benutzbar weil du sie in eine geschweifte klammer geschrieben hast und nirgendswo außerhalb gespeichert oder referenziert hast ( was ansich das gleiche ist )
Bei jedem Wechsel der Scene erstelle ich eine neue Scene.
Java:
@FXML
private void toViewScene (ActionEvent event) throws IOException {
    root = FXMLLoader.load(getClass().getResource("View.fxml"));
    stage = (Stage)((Node)event.getSource()).getScene().getWindow();
    scene = new Scene(root, 800, 600);
    stage.setScene(scene);
    stage.show();
}

Die werden so quasi in jedem Controller für die jeweiligen Scenen erstellt.
Wie setze ich die Scene denn, ich habe mal mit dem probiert, was ich so dachte, aber leider ohne Erfolg, da die Scene als null gezeigt wird.

Java:
FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
Parent root = loader.load();
FXMLViewController controller = loader.getController();                   
Scene scene = controller.viewBorderPane.getScene();
scene.setRoot(root);
controller.existingAssetsTab.setText("test");
 

mihe7

Top Contributor
@Tintenfisch, sorry, wenn ich mich kurz einmische, aber dieses Rumgerate führt doch zu nichts.

In #17 zeigst Du Code, der eine View lädt (wobei ein Controller erzeugt wird) und im Controller irgendwelche Einstellungen vornimmt. Die View wird nirgends verwendet. In #22 erklärst Du, dass Du den Szenenwechsel anders vornimmst: Du lädst (vermutlich) wieder eine View. Insofern hast Du zwei Views und zwei Controller, was @yfons123 in #13 und #19 bereits angesprochen hat. Aber anhand von ein paar Schnipseln ist es kaum möglich, definitive Aussagen zu treffen.

Bau doch mal eine kleine JavaFX-Anwendung zusammen, die das Problem zeigt, damit man dieses auch wirklich nachvollziehen kann.
 

temi

Top Contributor
Ich persönlich halte es für unschön, wenn sich unterschiedliche Controller gegenseitig kennen müssen. Um Abhängigkeiten zu vermeiden, verwende ich gerne Messaging, d.h. Jeder, der am Messaging teilnehmen soll, erhält (per Konstruktorinjektion) eine Instanz auf einen "MessageBus" und kann sich für den Empfang von bestimmten Nachrichten registrieren oder selbst Nachrichten an andere senden. In den jeweiligen Controllern müssen demnach Handlermethoden für die unterschiedlichen Nachrichten implementiert werden.
Ich hab "meinen" MessageBus selbst geschrieben. Es gibt auch fertige Lösungen, z. B. Guava
 

Tintenfisch

Bekanntes Mitglied
Ich habe mal eine Beispielanwendung geschrieben, in welcher das Problem deutlich wird.
Das Öffnen der neuen Stage funktioniert., sowie auch der Zugriff auf die Methoden des jeweils anderen Controllers. Lediglich die Veränderung von z.B. dem Label oder TextField.getText() funktioniert nicht.

Java:
public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("One.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}
Java:
public class ControllerOne {
   
    @FXML private Label label;
    @FXML private TextField textField;
    // ruft Methode in ControllerTwo auf
    @FXML
    private void toControllerTwo () throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Two.fxml"));
        loader.load();
        ControllerTwo controller = loader.getController();
        controller.createPopUp();
    }
    // wird von Methode im ControllerTwo aufgerufen
    public void changeLable () {
        System.out.println("Text Lable: " + label.getText()); // funktioniert
        label.setText(textField.getText()); // funktioniert nicht
        System.out.println("TF: " + textField.getText()); // getText() funktioniert nicht
    }
}
Java:
public class ControllerTwo {
    // wird von Methode in ControllerOne aufgerufen
    public void createPopUp () throws IOException {
        Stage stageTwo = new Stage();
        Parent root = FXMLLoader.load(getClass().getResource("Two.fxml"));
        Scene sceneTwo = new Scene(root);
        sceneTwo.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
        stageTwo.setScene(sceneTwo);
        stageTwo.show();
    }
    // ruft Methode in ControllerOne auf
    @FXML
    private void toControllerOne (ActionEvent event) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("One.fxml"));
        loader.load();
        ControllerOne controller = loader.getController();
        controller.changeLable();
       
        Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
        stage.close();
    }
}
 
Y

yfons123

Gast
wie viele controller ones brauchst du denn ?
Code:
 public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("One.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
Java:
    private void toControllerOne (ActionEvent event) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("One.fxml"));
        loader.load();
        ControllerOne controller = loader.getController();
        controller.changeLable();
      
        Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
        stage.close();
    }
würde es nicht reichen den aus der start methode herzunehmen ?
und es passiert exakt das was ich gesagt habe...
Code:
        FXMLLoader loader = new FXMLLoader(getClass().getResource("One.fxml"));
        loader.load();
        ControllerOne controller = loader.getController();
        controller.changeLable();
du baust dir einen NAGELNEUEN controller der nichts mit dem in start zu tun hat , wirfst die view sofort wieder weg

und schon klar ... das textfeld des gerade erzeugten controllers ist leer, hast du auch so eignestelllt in deiner fxml, nur du denkst du greifst auf den controller in der start methode zu, wo du den text rei ngeschrieben hast

aber das tust du nicht ... du machst einen nagelneuen controller wo du die view aus dem fenster wirfst

ich würde dir mal "empfehlen" sowas zu machen
Code:
    private void toControllerTwo () throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Two.fxml"));
        loader.load();
        ControllerTwo controller = loader.getController();
        // übergib dich selbst dem anderen controller dass der dich kennt
        controller.fuegeExternenControllerEin(this)
        controller.createPopUp();
    }
das fügst du in deinen controllertwo ein, somit kennt der auch den one jetzt... und auch den der ihn erzeugt hat
Java:
public class controllertwo...
    
    ControllerOne controllerOne;
public void fuegeExternenControllerEin(ControllerOne one)
{
    this.controllerOne = one;
}
so und das baust du dir selber die methode in controllerone rein dass das funtkioniert
Code:
    private void toControllerOne (ActionEvent event) throws IOException {
        this.controllerOne.ChangeLable();
    }
( deine toControllerone brauchst du nicht mehr dann )
 

Tintenfisch

Bekanntes Mitglied
wie viele controller ones brauchst du denn ?
Code:
 public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("One.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
Java:
    private void toControllerOne (ActionEvent event) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("One.fxml"));
        loader.load();
        ControllerOne controller = loader.getController();
        controller.changeLable();
     
        Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
        stage.close();
    }
würde es nicht reichen den aus der start methode herzunehmen ?
und es passiert exakt das was ich gesagt habe...
Code:
        FXMLLoader loader = new FXMLLoader(getClass().getResource("One.fxml"));
        loader.load();
        ControllerOne controller = loader.getController();
        controller.changeLable();
du baust dir einen NAGELNEUEN controller der nichts mit dem in start zu tun hat , wirfst die view sofort wieder weg

und schon klar ... das textfeld des gerade erzeugten controllers ist leer, hast du auch so eignestelllt in deiner fxml, nur du denkst du greifst auf den controller in der start methode zu, wo du den text rei ngeschrieben hast

aber das tust du nicht ... du machst einen nagelneuen controller wo du die view aus dem fenster wirfst

ich würde dir mal "empfehlen" sowas zu machen
Code:
    private void toControllerTwo () throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Two.fxml"));
        loader.load();
        ControllerTwo controller = loader.getController();
        // übergib dich selbst dem anderen controller dass der dich kennt
        controller.fuegeExternenControllerEin(this)
        controller.createPopUp();
    }
das fügst du in deinen controllertwo ein, somit kennt der auch den one jetzt... und auch den der ihn erzeugt hat
Java:
public class controllertwo...
   
    ControllerOne controllerOne;
public void fuegeExternenControllerEin(ControllerOne one)
{
    this.controllerOne = one;
}
so und das baust du dir selber die methode in controllerone rein dass das funtkioniert
Code:
    private void toControllerOne (ActionEvent event) throws IOException {
        this.controllerOne.ChangeLable();
    }
( deine toControllerone brauchst du nicht mehr dann )
Ist eine Gute Idee, habe es mal soweit umgesetzt, jedoch wird der ControllerOne in der Valiable nicht zwischengespeichert und gibt beim Aufruf in der Methode toControllerOne(); null zurück.
 

Tintenfisch

Bekanntes Mitglied
dürfte eig nicht sein ... zeig mal den code
Java:
public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("One.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}
Java:
public class ControllerOne {
   
    @FXML private Label label;
    @FXML private TextField textField;
   
    @FXML
    private void toControllerTwo () throws IOException {
       
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Two.fxml"));
        loader.load();
        ControllerTwo controller = loader.getController();
        controller.exController(this);
        controller.createPopUp();
        System.out.println(this);
    }
    @FXML
    public void changeLable () {
        System.out.println("Text Lable: " + label.getText()); 
        label.setText(textField.getText()); 
        System.out.println("TF: " + textField.getText());
    }
}
Java:
public class ControllerTwo {
   
    private ControllerOne ControllerOne;
   
   
    @FXML
    public void createPopUp () throws IOException {
        Stage stageTwo = new Stage();
        Parent root = FXMLLoader.load(getClass().getResource("Two.fxml"));
        Scene sceneTwo = new Scene(root);
        sceneTwo.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
        stageTwo.setScene(sceneTwo);
        stageTwo.show();
    }
   
    public void exController (ControllerOne one) {
        this.ControllerOne = one;
        System.out.println(one);
        System.out.println(this.ControllerOne); // funktioniert
    }
    @FXML
    private void toControllerOne () {
        System.out.println(this.ControllerOne); // funktioniert nicht

        this.ControllerOne.changeLable(); // hier: NullPointerEx. ControllerOne
    }
}
 
Zuletzt bearbeitet:
Y

yfons123

Gast
unter create pop up lädst du wieder einen neuen controllertwo der komplett neu ist und bei dem du niemals dne controllerone gesetzt hast... lass einfach das create popup

so zb wenn du ein neues fesnter willst
Java:
    @FXML
    private void toControllerTwo () throws IOException {
      
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Two.fxml"));
        ControllerTwo controller = loader.getController();
        controller.exController(this);

        Parent controllerTwoFxmlGuiRootElement = loader.load();
        
        // hier stage und scene bauen
        // new Scene(controllerTwoFxmlGuiRootElement);
        // stage.show
    }
lass den controller one eine stage und scene bauen, und in diese szene setzt du controllertwo ein

somit gehören "teile" aus create pop up einfach in controller one

du verstehst noch nicht was fxml macht denke ich...

du hast deine hierarchie von nodes
und fxml.load macht 2 sachen
die wandelt das xml zeug in javafx objekte um und baut einen teil des hierarchie baumes von nodes
diesen "teil baum" musst du in ein layout(hbox oder sonst was ) einsetzen oder in eine szene ansonsten siehst das nicht
das zweite was fxml tut ist es erzeugt das controller objekt was du in der fxml angegeben hast und übergibt den controller das @FXML zeug dass das funktioniert

wenn du nur fxml.load() machst dann hast du die aus fxm gebaute node hierarchie weggeworfen ( das wäre Parent rückgabe wert.. parent ist ein node der irgend ein javafx objekt ist ) und den controller raus genommen.. nur dir hilft der controller halt nix ohne die node hierarchie weil du schlichtweg das zeug nicht siehst...

es gibt momente wo man es braucht deswegen kannst du das parent root auch weglassen aber du brauchst es hier

meines wissens nach sollte fxmlload auch generisch sein udn du soltlest das root objekt angeben können wie zb hbox... aber javafx hat mich heute dezent angepisst ... um genau zu sein hat maven dann das fass zum überlaufen gebracht mit java 17.. von daher werd ich nicht nachschauen ob es generisch ist ...
var root = fxml.load<VBox>();
könnte es aussehen ... aber bin nicht sicher
 

Tintenfisch

Bekanntes Mitglied
unter create pop up lädst du wieder einen neuen controllertwo der komplett neu ist und bei dem du niemals dne controllerone gesetzt hast... lass einfach das create popup

so zb wenn du ein neues fesnter willst
Java:
    @FXML
    private void toControllerTwo () throws IOException {
     
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Two.fxml"));
        ControllerTwo controller = loader.getController();
        controller.exController(this);

        Parent controllerTwoFxmlGuiRootElement = loader.load();
       
        // hier stage und scene bauen
        // new Scene(controllerTwoFxmlGuiRootElement);
        // stage.show
    }
lass den controller one eine stage und scene bauen, und in diese szene setzt du controllertwo ein

somit gehören "teile" aus create pop up einfach in controller one

du verstehst noch nicht was fxml macht denke ich...

du hast deine hierarchie von nodes
und fxml.load macht 2 sachen
die wandelt das xml zeug in javafx objekte um und baut einen teil des hierarchie baumes von nodes
diesen "teil baum" musst du in ein layout(hbox oder sonst was ) einsetzen oder in eine szene ansonsten siehst das nicht
das zweite was fxml tut ist es erzeugt das controller objekt was du in der fxml angegeben hast und übergibt den controller das @FXML zeug dass das funktioniert

wenn du nur fxml.load() machst dann hast du die aus fxm gebaute node hierarchie weggeworfen ( das wäre Parent rückgabe wert.. parent ist ein node der irgend ein javafx objekt ist ) und den controller raus genommen.. nur dir hilft der controller halt nix ohne die node hierarchie weil du schlichtweg das zeug nicht siehst...

es gibt momente wo man es braucht deswegen kannst du das parent root auch weglassen aber du brauchst es hier

meines wissens nach sollte fxmlload auch generisch sein udn du soltlest das root objekt angeben können wie zb hbox... aber javafx hat mich heute dezent angepisst ... um genau zu sein hat maven dann das fass zum überlaufen gebracht mit java 17.. von daher werd ich nicht nachschauen ob es generisch ist ...

könnte es aussehen ... aber bin nicht sicher
Ja klasse, so funktioniert es. Auf jeden Fall vielen Dank für die ausführlichen Erklärungen. Und genau, ich hatte vor kurzem erst mit FXML gestartet, aber konnte aus diesem Beitrag wieder einiges Interessantes mitnehmen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Elemente statisch anordnen AWT, Swing, JavaFX & SWT 4
_user_q ChoiceBox Elemente: Sprache ändern AWT, Swing, JavaFX & SWT 7
Lunar Swing JFrame erstellt; weitere Elemente werden nicht eingefügt/sind nicht zu sehen AWT, Swing, JavaFX & SWT 4
J JavaFX JavaFX Splitpane - Zugriff auf die Controller der Elemente AWT, Swing, JavaFX & SWT 8
G Swing Variable Elemente für GroupLayout AWT, Swing, JavaFX & SWT 18
F JFrame zeigt nicht alle Elemente auf anhieb an AWT, Swing, JavaFX & SWT 4
J JavaFX Elemente werden nicht zu TableView hinzugefügt AWT, Swing, JavaFX & SWT 3
J JavaFX JavaFX Elemente an Fenstergröße skalieren AWT, Swing, JavaFX & SWT 5
M Schnittpunkte zwischen zwei Graphics2D Elemente ermitteln. AWT, Swing, JavaFX & SWT 5
T LayoutManager Anordnen der Elemente im GridBagLayout AWT, Swing, JavaFX & SWT 11
T AWT Grafik"Array" einzelne Elemente verschieben AWT, Swing, JavaFX & SWT 1
sandaime Swing 3 JComboBoxen ausgelesen Elemente einzel ausgeben AWT, Swing, JavaFX & SWT 6
M JavaFX GUI-Elemente erstellen, nachdem die GUI geladen hat AWT, Swing, JavaFX & SWT 4
TheJavaKid JavaFX Elemente positionieren AWT, Swing, JavaFX & SWT 2
B Swing Auf JList-Elemente aus einer anderen Klasse zugreifen AWT, Swing, JavaFX & SWT 1
N JavaFX GUI Elemente einer anderen (FXML)Klasse ansprechen AWT, Swing, JavaFX & SWT 16
D JavaFX Elemente aus VBox unterscheiden AWT, Swing, JavaFX & SWT 1
K Kann nicht auf GUI Elemente zugreifen, mit einer Methode im Controller klappts, mit der anderen nich AWT, Swing, JavaFX & SWT 10
R Swing Elemente verschieben sich im GBL beim Ein/Ausblenden AWT, Swing, JavaFX & SWT 0
Z Swing Swing: Elemente werden doppel/verschoben gezeichnet, sind teils unsichtbar etc... AWT, Swing, JavaFX & SWT 10
wolfgang63 JavaFX Elemente einer Group entfernen AWT, Swing, JavaFX & SWT 1
D SWT SWT Elemente aus anderen Klassen aufrufen - Invalid thread access AWT, Swing, JavaFX & SWT 6
O Ähnliche GUI Elemente - vererbung?! AWT, Swing, JavaFX & SWT 0
M AWT Gui anzeige Probes - Elemente erscheinen nicht regelmäßig AWT, Swing, JavaFX & SWT 2
M Swing JTabbedPane: Tab-Elemente anpassen AWT, Swing, JavaFX & SWT 3
T Swing Elemente der JList überlappend darstellen AWT, Swing, JavaFX & SWT 5
K GUI Elemente über eine separate Textdatei beschriften? AWT, Swing, JavaFX & SWT 4
T Alle Swing-Elemente anzeigen AWT, Swing, JavaFX & SWT 9
M Swing Elemente im Dialog neu "laden". AWT, Swing, JavaFX & SWT 6
T JTree - Elemente mit Doppelklick auswählen AWT, Swing, JavaFX & SWT 6
L Swing ActionListener zugriff auf bestimmte Elemente AWT, Swing, JavaFX & SWT 3
S Elemente im Panel in richtige Ausgangsstellung bringen AWT, Swing, JavaFX & SWT 10
K LayoutManager Wieso verschwinden Elemente? AWT, Swing, JavaFX & SWT 20
M JFrame + JNA/aero modul - GUI Elemente so möglich? AWT, Swing, JavaFX & SWT 28
P Elemente einer JList ausgeben AWT, Swing, JavaFX & SWT 11
B JList zeigt Elemente nicht an AWT, Swing, JavaFX & SWT 3
R Größe/Anordnung der Gui-Elemente automatisch? AWT, Swing, JavaFX & SWT 6
S JVM von Oracle/Sun soll für AWT/SWING Elemente die die Optimierungen der NVidia Treiber verwenden AWT, Swing, JavaFX & SWT 3
C Swing JFrame nimmt keine anderen Elemente auf AWT, Swing, JavaFX & SWT 13
R JApplet, Elemente unsichtbar AWT, Swing, JavaFX & SWT 2
1 JList - Elemente mit rechter Maustaste wählen AWT, Swing, JavaFX & SWT 6
L ID für GUI Elemente generieren AWT, Swing, JavaFX & SWT 11
C SWT-Elemente an View-Fenster angleichen und automatisch resizen AWT, Swing, JavaFX & SWT 3
U Elemente im Panel zentrieren mit GridLayout AWT, Swing, JavaFX & SWT 3
P Elemente im Kreis aufstellen AWT, Swing, JavaFX & SWT 5
G Swing Elemente aus Arraylist auf JFrame anzeigen AWT, Swing, JavaFX & SWT 9
G GUI Elemente aus NetBeans verwenden AWT, Swing, JavaFX & SWT 8
L SWT tree elemente markieren AWT, Swing, JavaFX & SWT 4
C Swing Elemente in JList sortieren AWT, Swing, JavaFX & SWT 2
T Elemente zu JList dynamisch hinzufügen AWT, Swing, JavaFX & SWT 4
S JTree Elemente nach BaumLevel abspeichern AWT, Swing, JavaFX & SWT 2
S JTree & JComboBox - Elemente übers Fenster hinaus anzeigen AWT, Swing, JavaFX & SWT 9
F JScrollPane überlagert andere Elemente AWT, Swing, JavaFX & SWT 5
S Swing UI-Elemente ordnen sich ungewollt in einer Reihe (ohne Layout) AWT, Swing, JavaFX & SWT 5
K Swing Elemente auf Zeichenfeld verschieben AWT, Swing, JavaFX & SWT 8
S Mit eigener Klasse auf GUI-Elemente zugreifen AWT, Swing, JavaFX & SWT 3
E Swing JComboBox als CellEditor in JTable zeigt Elemente nicht sofort an AWT, Swing, JavaFX & SWT 5
R In JFrame oder in Canvas mit grafischen Elemente zeichnen AWT, Swing, JavaFX & SWT 2
E Swing JList zur Laufzeit hinzugefügt elemente nicht sichtbar?! AWT, Swing, JavaFX & SWT 2
S Swing Elemente einer JList Farbig hinterlegen AWT, Swing, JavaFX & SWT 6
B Swing Dynamisch Elemente in JScrollPane hinzufügen AWT, Swing, JavaFX & SWT 6
M Swing Von einem Controller aus View-Elemente ändern AWT, Swing, JavaFX & SWT 11
T DND mit JList Elemente nicht am Ende einfügen AWT, Swing, JavaFX & SWT 3
Tobse Swing JList elemente hinzufügen AWT, Swing, JavaFX & SWT 4
K JLayeredPane Elemente auf gleicher Position AWT, Swing, JavaFX & SWT 7
D Elemente werden nicht angezeigt AWT, Swing, JavaFX & SWT 2
W jComboBox unterschiedlich selectable elemente AWT, Swing, JavaFX & SWT 7
M Elemente in JTabbedPane platzieren AWT, Swing, JavaFX & SWT 7
N Swing JList Elemente ausgeben fehlerhaft AWT, Swing, JavaFX & SWT 4
M Swing Alle Elemente eines Panels? AWT, Swing, JavaFX & SWT 9
S Eigene GUI Elemente erstellen AWT, Swing, JavaFX & SWT 6
M.F.G. Fehler bei der Anzeige Grafischer Elemente AWT, Swing, JavaFX & SWT 13
B Swing Problem beim Elemente zu JList hinzufügen AWT, Swing, JavaFX & SWT 5
C (Swing)GUI-Elemente werden nicht aktualisiert. AWT, Swing, JavaFX & SWT 2
P JList: Reihenfolge der Elemente per Drag'n'Drop ändern. AWT, Swing, JavaFX & SWT 9
M Swing JList - Elemente umbenennen? AWT, Swing, JavaFX & SWT 4
MrMilti Gezeichnete Java2D Elemente mit Events versehen AWT, Swing, JavaFX & SWT 3
H [gelöst] Swing Elemente verdecken AWT, Swing, JavaFX & SWT 14
B In externer Eventhandlerklasse auf GUI-Elemente zugreifen AWT, Swing, JavaFX & SWT 3
K BoxLayout skaliert die "falschen" Elemente AWT, Swing, JavaFX & SWT 5
A SWT - Elemente zur Laufzeit ändern AWT, Swing, JavaFX & SWT 6
S Andere Elemente in JComboBox anzeigen AWT, Swing, JavaFX & SWT 2
T Elemente werden nicht direkt angezeigt AWT, Swing, JavaFX & SWT 3
S Nachträglich Swing-Elemente in JFrame erzeugen AWT, Swing, JavaFX & SWT 18
K Titel für eingebundene Elemente wie JPanel AWT, Swing, JavaFX & SWT 3
F Dynamische Swing Elemente AWT, Swing, JavaFX & SWT 10
B Grafische Anordnung der Elemente AWT, Swing, JavaFX & SWT 2
S JComboBox zeigt beim 1. öffnen nur 2 Elemente ? AWT, Swing, JavaFX & SWT 9
J LayoutManager der Elemente untereinander anordnet. AWT, Swing, JavaFX & SWT 11
S Zugriff auf Elemente funktioniert mit SWING nicht mehr AWT, Swing, JavaFX & SWT 5
G JButton und andere J-Elemente: Markierung ausblenden AWT, Swing, JavaFX & SWT 6
Paule alle Elemente eines SWT Trees AWT, Swing, JavaFX & SWT 8
S List Elemente AWT, Swing, JavaFX & SWT 4
G Elemente erst da wenn mit Maus drüber gefahren bin AWT, Swing, JavaFX & SWT 2
E GUI-Elemente aus txt- oder xml-File erstellen? AWT, Swing, JavaFX & SWT 5
J FAQ programmieren, welche Swing-Elemente AWT, Swing, JavaFX & SWT 7
M Elemente hängen dicht aufeinander AWT, Swing, JavaFX & SWT 2
S Falsche Position, Elemente erscheinen nicht, Flackern AWT, Swing, JavaFX & SWT 6
DEvent Je nach Auswahl in Liste entsprechende Input-Elemente anzeig AWT, Swing, JavaFX & SWT 2
W Elemente aus JPanel bzw. GridBag löschen und ersetzen AWT, Swing, JavaFX & SWT 18

Ähnliche Java Themen

Neue Themen


Oben