【问题标题】:JavaFX TabPane Tab select from foreign ControllerJavaFX TabPane Tab 从外部控制器中选择
【发布时间】:2020-05-14 10:58:49
【问题描述】:

在我用这篇有用的帖子 (PASSING PARAMETERS JAVAFX FXML) 的引导更改我的代码后,我的 setTab 函数并没有真正起作用。它被调用但没有做它应该做的事情。

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;
        }
    }
}

!包和导入在正文长度前被删除!

我知道我必须重写最后几个函数,因为它们很容易成为一个。

Steuerung.fxml 和 Anzeige.fxml 会太长。如果你想看到它们,这里是完整的 GitLab 项目。 GitLab Project

对于德国的 cmets、函数/变量名称和/或对象感到抱歉

感谢您的建议!

编辑:语法

【问题讨论】:

  • minimal reproducible example 请注意M,只是一个最小的用户界面,一个应该被触发并且仍然完整的按钮,必须是可重现的,它包含控制器,fxml ,样板应用程序。并且不相关:请使用 java 命名约定!
  • 您调用setTab()Controller2 实例不是您调用showStage() 的实例,因此您不会看到任何效果。
  • 请告诉我,那我应该改变什么?我是 JavaFX 的新手。
  • *你能告诉我吗
  • 嗯,这取决于你想要什么行为。如果您每次按下b_AnzeigeÖffnen 按钮时都想要一个新的Controller2 实例,那么您需要创建一个新实例(就像您当前所做的那样),但将其保存在实例变量中。如果您只想显示已创建的实例(即每次显示或重新显示相同的实例),则不要在该事件处理程序中创建新实例。

标签: java javafx tabpanel


【解决方案1】:

Controller1 中,您创建一个Controller2 实例作为实例变量:

private Controller2 controller2 = new Controller2(this);

当用户点击b_Ecke 标签时,您会更改该实例中的选项卡:

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

但是,您的代码中没有任何地方您曾在 Controller2 的该实例上调用 showStage,因此您正在更改未显示的选项卡选择。

当用户选择b_AnzeigeÖffnen 菜单项时,您创建一个 Controller2 实例,并显示该实例:

b_AnzeigeÖffnen.setOnAction(e -> openAnzeige());

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

相反,只显示您已经创建的Controller2 实例:

b_AnzeigeÖffnen.setOnAction(e -> openAnzeige());

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

【讨论】:

    猜你喜欢
    • 2015-10-18
    • 2016-01-16
    • 2013-11-22
    • 1970-01-01
    • 2016-10-17
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    • 2014-09-03
    相关资源
    最近更新 更多