javajavafxtabpanel

JavaFX TabPane Tab select from foreign Controller


after I changed my code with lead of this helpful post (PASSING PARAMETERS JAVAFX FXML) my setTab function works not really. Its gets called but doesn't do what it's supposed to do.

Main.java

public class Main extends Application {

public static void main(String[] args) {
    launch(args);
}
@Override
public void start(Stage primaryStage){
        Controller1 controller1 = new Controller1();
        controller1.showStage();
  }
}

Controller1.java

public class Controller1{

    private final Stage thisStage;
    private Controller2 controller2 = new Controller2(this);

    public Controller1() {
    thisStage = new Stage();

    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Steuerung.fxml"));
        loader.setController(this);
        thisStage.setScene(new Scene(loader.load()));
        thisStage.setTitle("Steuerung");
    }catch (IOException e){
        e.printStackTrace();
     }
    }

    public void showStage(){ thisStage.show();}

    @FXML private void initialize() {
        b_AnzeigeÖffnen.setOnAction(e -> openAnzeige());
        b_Ecke.setOnMouseClicked(e -> controller2.setTab(2));
    }

    private void openAnzeige(){
        Controller2 controller2 = new Controller2(this);
        controller2.showStage();
    }

    @FXML
    private Label b_Ecke;

    @FXML
    private MenuItem b_AnzeigeÖffnen

}

Controller2.java

public class Controller2 {

private Stage thisStage;

private final Controller1 controller1;

public Controller2(Controller1 controller1) {
    this.controller1 = controller1;
    thisStage = new Stage();
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Anzeige.fxml"));
        loader.setController(this);
        thisStage.setScene(new Scene(loader.load()));
        thisStage.setTitle("Spielstand");

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

public void showStage() { thisStage.show();}


@FXML
private TabPane TP_A;

@FXML
private Tab tA_Home;

@FXML
private Tab tA_EckePreview;

@FXML
private Tab tA_EckVerhältnis;

@FXML
private Tab tA_Spielverlauf;

@FXML
private Tab tA_Spielstatistik;

@FXML
private Tab tA_GelbeKarte;

@FXML
private Tab tA_RoteKarte;

@FXML
private Tab tA_Elfmeter;

@FXML
private Tab tA_Auswechselung;


@FXML public void setTab(Integer i) {
   System.out.println("TABSWITCH");
    switch(i) {
        case 1: TP_A.getSelectionModel().select(tA_Home); break;
        case 2: TP_A.getSelectionModel().select(tA_EckePreview); break;
        case 3: TP_A.getSelectionModel().select(tA_EckVerhältnis); break;
        case 4: TP_A.getSelectionModel().select(tA_Spielverlauf); break;
        case 5: TP_A.getSelectionModel().select(tA_Spielstatistik); break;
        case 6: TP_A.getSelectionModel().select(tA_GelbeKarte); break;
        case 7: TP_A.getSelectionModel().select(tA_RoteKarte); break;
        case 8: TP_A.getSelectionModel().select(tA_Elfmeter); break;
        case 9: TP_A.getSelectionModel().select(tA_Auswechselung); break;
        //case 10: TP_A.getSelectionModel().select(tA_Nachspielzeit/Verlängerung); break; -> TODO
        default: System.out.println("Fehler: Tab in TP_A nicht vorhanden!"); break;
        }
    }
}

!packages and imports are removed bc of Body length!

I know that I have to rewrite the last few functions as they could easy be one.

Steuerung.fxml and Anzeige.fxml would be to long. If u want to see them tho, here is the complete GitLab project. GitLab Project

Sorry for the German comments, function/var names and or objects

Thans for ur advice!

Edit: Grammar


Solution

  • In Controller1 you create a Controller2 instance as an instance variable:

    private Controller2 controller2 = new Controller2(this);
    

    and when the user clicks on the b_Ecke label, you change the tab in that instance:

    b_Ecke.setOnMouseClicked(e -> controller2.setTab(2));
    

    However, there is nowhere in your code where you ever call showStage on that instance of Controller2, so you are changing the tab selection in something that is not displayed.

    When the user selects the b_AnzeigeÖffnen menu item, you create a new Controller2 instance, and display that instance:

    b_AnzeigeÖffnen.setOnAction(e -> openAnzeige());
    
    private void openAnzeige(){
        Controller2 controller2 = new Controller2(this);
        controller2.showStage();
    }
    

    Instead, just display the Controller2 instance you have already created:

    b_AnzeigeÖffnen.setOnAction(e -> openAnzeige());
    
    private void openAnzeige(){
        // Controller2 controller2 = new Controller2(this);
        controller2.showStage();
    }