JavaFX 两个FXML中其中一个包含TabPane的互相通信

问题描述:

在JavaFX中实现两个FXML公用同一个控制器,其中第一个FXML包含一个TabPane其中包含一个按钮,第二个FXML只包含一个按钮,我要实现的是第一个FXML中TabPane中的按钮被按下后,在TabPane新建一个Tab,其中加载内容为第二个FXML的内容,第二个FXML中的按钮被按下后,再在第一个FXML中的TabPane放置一个新的Tab,其中新的Tab加载的内容为第二个FXML的内容为第二个Tab。

解决方法

传统写法将会导致空指针异常,可以这样写:
首先,创建一个控制器类(例如 Controller.java),用于处理两个FXML文件中的逻辑。在控制器类中,您需要定义一个 TabPane 和一个方法来处理第一个FXML中的按钮点击事件,用于创建新的 Tab 并加载第二个FXML的内容。

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.AnchorPane;

import java.io.IOException;

public class Controller {
    @FXML
    private TabPane tabPane;

    @FXML
    private Button addButton;

    @FXML
    public void initialize() {
        addButton.setOnAction(event -> createNewTab());
    }

    private void createNewTab() {
        try {
            Tab tab = new Tab();
            FXMLLoader loader = new FXMLLoader(getClass().getResource("second.fxml"));
            AnchorPane content = loader.load();
            tab.setContent(content);
            tabPane.getTabs().add(tab);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void handleSecondButton() {
        Tab tab = new Tab();
        FXMLLoader loader = new FXMLLoader(getClass().getResource("second.fxml"));
        try {
            AnchorPane content = loader.load();
            tab.setContent(content);
            tabPane.getTabs().add(tab);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

接下来,创建第一个FXML文件(例如 first.fxml)并定义一个包含一个 TabPane 和一个按钮的布局。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
    <TabPane fx:id="tabPane">
        <!-- TabPane内容 -->
    </TabPane>

    <Button fx:id="addButton" text="新建Tab"/>
</VBox>

然后,创建第二个FXML文件(例如 second.fxml),其中只包含一个按钮。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
    <Button text="第二个FXML中的按钮" onAction="#handleSecondButton"/>
</VBox>

最后,在主应用程序类(例如 Main.java)中加载第一个FXML文件,并将控制器与其关联。

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("first.fxml"));
        Parent root = loader.load();
        Controller controller = loader.getController(); // 获取控制器实例

        Scene scene = new Scene(root, 400, 300);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

现在,当您在第一个FXML的 TabPane 中的按钮被按下时,将创建一个新的 Tab,其中包含第二个FXML的内容。同样,当第二个FXML中的按钮被按下时,将在第一个FXML的 TabPane 中添加一个新的 Tab,其中内容为第二个FXML。

注意,为了实现这个功能,您需要在第一个FXML中的 TabPane 位置添加一些默认内容。您可能还需要适当地调整布局和界面元素的样式。

你可能感兴趣的:(前端,java,ui)