JavaFX Zugriff auf FXML-Variablen eines anderen Controllers

Juhini19

Mitglied
Hallo zusammen,

ich möchte von einem Controller auf FXML-Variablen eines anderen Controllers zugreifen. Dazu habe ich schon viel recherchiert, aber leider immer noch keine Lösung gefunden.
Und zwar habe ich eine Hauptanwendung, bei der mit einem Klick auf ein TextField ein weiteres Fenster geöffnet werden soll. Auf diesem befinden sich ein TextField und ein Button zur Bestätigung der Eingabe. Bei einem Klick auf den Button soll der eingegebene Text des TextFields in das TextField der Hauptanwendung übertragen werden.
Anbei noch Auszüge meines Quelltextes von dem Controller der Hauptanwendung (MainController) und des weiteren Fensters (DialogInsertOrderNoController), sowie den zugehörigen FXML-Dateien.

Ich würde mich freuen, wenn ihr mir eine Empfehlung für die Lösung dieses Problems geben könnt. Vielen Dank im Voraus.


Main-Controller:

Java:
public class MainController implements Initializable {

    @FXML public TextField textFieldOrderNo;
   
    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        try
        {
            //Initialization of table Color
            tblColorColColorCode.setCellValueFactory(new PropertyValueFactory<Color,String>("colorCode"));
            tblColorColColorName.setCellValueFactory(new PropertyValueFactory<Color,String>("colorName"));
            tblColorColExtColorNo.setCellValueFactory(new PropertyValueFactory<Color,String>("externalColorNo"));
            ...
        }
        catch(Exception e)
        {
            DialogTools.showExpandableExceptionDialog(e, Main.primayStage);
        }
    }

    public void handleClickOnTextFieldOrderNo()
    {
        //Start des zweiten Fensters
        new DialogInsertOrderNo().start(new Stage());
    }
}


Main-FXML:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.effect.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>

<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1300.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<fx:define>
      <fx:include fx:id="dialogInsertOrderNo" source="DialogInsertOrderNo.fxml"/>
   </fx:define>
      <VBox prefHeight="200.0" prefWidth="100.0" spacing="5.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
         <children>
            <TextField fx:id="textFieldOrderNo" editable="false" onMouseClicked="#handleClickOnTextFieldOrderNo" text="Add a new Order-No.">
               <cursor>
                  <Cursor fx:constant="DISAPPEAR" />
               </cursor>
            </TextField>
         </children>
         <GridPane.margin>
            <Insets top="22.0" />
         </GridPane.margin>
      </VBox>
      <VBox prefHeight="200.0" prefWidth="100.0" spacing="10.0" GridPane.columnIndex="4" GridPane.rowIndex="1">
</GridPane>



Controller des zweiten Fensters:
Java:
public class DialogInsertOrderNoController {

    @FXML public TextField dialogTextFieldOrderNo;
    @FXML public Button btnConfirm;

    @FXML public void handleBtnConfirm()
    {
        try
        {
            //Hier soll nun das Textfeld "textFieldOrderNo" des Main-Controllers den Text
            //von "dialogTextFieldOrderNo" erhalten

            DialogInsertOrderNo.primaryStage.hide();
        }
        catch(Exception e)
        {
            DialogTools.showExpandableExceptionDialog(e, DialogInsertOrderNo.primaryStage);
        }
    }
}

FXML des zweiten Fensters:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>

<GridPane fx:id="dialogInsertOrderNo" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="110.0" prefWidth="250.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.DialogInsertOrderNoController">
         <children>
            <Label text="Order-No." GridPane.halignment="RIGHT">
               <GridPane.margin>
                  <Insets right="10.0" />
               </GridPane.margin>
            </Label>
            <TextField fx:id="dialogTextFieldOrderNo" maxWidth="-Infinity" prefWidth="100.0" GridPane.columnIndex="1" />
            <Button fx:id="btnConfirm" mnemonicParsing="false" onAction="#handleBtnConfirm" prefHeight="30.0" prefWidth="70.0" text="Confirm" GridPane.columnIndex="1" GridPane.rowIndex="1" GridPane.valignment="TOP" />
         </children>
</GridPane>
 
new DialogInsertOrderNo().start(new Stage());

Ja und wo steckt DialogInsertOrderNo.java?
Code:
//So Dialog starten in MainController
DialogInsertOrderNoController controller = new DialogInsertOrderNoController(this);
FXMLLoader loader = new FXMLLoader("dialoginsertorderno.fxml");
loader.setController(controller);
Scene scene = new Scene(loader.load());
Stage stage = new Stage();
stage.setScene(scene);
stage.show();

//Erweiterungen in MainController um das Ergebnis zu erhalten. Am Besten in ein Interface extrahieren
public void insertOrderNumber(String orderNumber) {
  textFieldOrderNo.setText(orderNumber);
}

//Erweiterung DialogInsertOrderNoController
//Constructor mit Main Controller, bzw. genanntes Interface als Parameter als orderNumberCallback
//Code in OnAction-Methode
orderNumberCallback.insertOrderNumber(dialogTextFieldOrderNo.getText());

Die erste Regel ist, man greift nicht auf die View oder Felder einer anderen View direkt drauf zu. Das ist wie Fremdvögeln. Verlockend birgt aber jede Menge Ärger.
 

Zurück
Oben