JavaFX:如何在没有 5 倍工作的情况下使用 SceneBuilder 在 TabPane 中创建 5 倍相同的标签?

JavaFX: How to create 5x identical Tabs within a TabPane with SceneBuilder, without 5x work?

如何使用 SceneBuilder 创建 5 倍相同的 TabPane,而不需要 5 倍的工作量?

解决方案:

您通常创建一个仅包含单个 TabPane 的 fxml,然后使用 <fx:include>:

多次使用此 fxml

tabpane.fxml

<TabPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="mapackage.TabPaneController">
    ...
</TabPane>

包含布局

<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="mapackage.RootController">
    <children>
        <fx:include fx:id="tabPane1" source="@tabpane.fxml" />
        <fx:include fx:id="tabPane2" source="@tabpane.fxml" />
        ...
    </children>
</VBox>
public class RootController {
    @FXML
    private TabPaneController tabPane1Controller;
    @FXML
    private TabPaneController tabPane2Controller;
    ...
}

当然,您应该确保 TabPaneController 包含适当的方法来访问您需要从 RootController...

访问的功能

解决方案:
谢谢你的帮助。我的解决方案如下所示:
- 我多次使用 TabView.fxml 输入
- 一旦用户点击一个选项卡,每个选项卡都必须分配一个唯一的 tabId
- 以下代码已完成且有效

Main.java

public class Main extends Application { 
    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(new AnchorPane());
        FXMLLoader loader = new FXMLLoader(getClass().getResource("tabPaneRootView.fxml"));
        scene.setRoot(loader.load());
        TabPaneRootController controller = loader.getController();
        controller.myInit(); //my init-Methode 
        primaryStage.setScene(scene);
        primaryStage.setTitle("I'm Tab x"); 
        primaryStage.show();
    }

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

TabPaneRootController.java

public class TabPaneRootController {    
    @FXML private TabPane tabPane;

    //################################# Inject SubController ################################## 
    //Inject tab controller
    @FXML private TabController xxx_tab1_xxxController; //TabPaneRootView.fxml_include_fx:id="xxx_tab_xxx" + "Controller"
    @FXML private TabController xxx_tab2_xxxController;
    //#########################################################################################

    public void myInit() {      
        tabPane.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends Tab> observable,
                Tab oldValue, Tab newValue)->{
                    preparationInitTab(newValue);                   
                });
    }

    public void preparationInitTab(Tab selectedTab) {
        String currentTabId_string = selectedTab.getId();
        String[] parts = currentTabId_string.split("_");
        int currentTabId = Integer.parseInt(parts[1]); 

        switch(currentTabId) {
        case 1:
            xxx_tab1_xxxController.initTab(currentTabId);
            break;
        case 2:
            xxx_tab2_xxxController.initTab(currentTabId);
            break;

        default:
            System.out.println("Warning: Select an unassigned tab='" + currentTabId + "'");
        }
    }       
}

TabController.java

public class TabController {    
    private int tabId = -9; //is the ID of the currently selected tab

    @FXML private TextField tab_textField_currentTabName;
    @FXML private TextField tab_textField01_costPosition1;

    public void initTab(int currentTabId) {
        System.out.println(">TabController::initTab() with currentTabId=" + currentTabId);
        this.tabId = currentTabId;      
        tab_textField_currentTabName.setText(String.valueOf(tabId));
    }

    //----------------- FXML-Methoden --------------------------    
    @FXML
    private void handleTabTextFieldCostPosition1() {
        System.out.println("costPosition1[" + tabId + "]=" + tab_textField01_costPosition1.getText());
    }

    @FXML
    private void handleExit() {     
        Platform.exit();
    }
}

tabPaneRootView.fxml

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

<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.myapp.TabPaneRootController">
   <children>
      <TabPane fx:id="tabPane" tabClosingPolicy="UNAVAILABLE">
        <tabs>
            <Tab fx:id="tabId_0" text="Tab0">
               <content>
                  <AnchorPane prefHeight="200.0" prefWidth="200.0">
                     <children>
                        <Label layoutX="10.0" layoutY="30.0" text="general information ..." />
                     </children>
                  </AnchorPane>
               </content>
            </Tab>
            <Tab fx:id="tabId_1" text="Tab1">
               <content>
                  <fx:include source="tabView.fxml" fx:id="xxx_tab1_xxx" />
               </content>
            </Tab>
            <Tab fx:id="tabId_2" text="Tab2">
               <content>
                  <fx:include source="tabView.fxml" fx:id="xxx_tab2_xxx" />             
               </content>
            </Tab>
        </tabs>
      </TabPane>
   </children>
</AnchorPane>

tabView.fxml

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="200.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.myapp.TabController">
   <children>
      <Label layoutX="10.0" layoutY="40.0" text="I'm Tab Index:"> </Label>
      <TextField fx:id="tab_textField_currentTabName" editable="false" layoutX="107.0" layoutY="35.0" prefWidth="30.0" />
      <Button alignment="CENTER" contentDisplay="CENTER" layoutX="185.0" mnemonicParsing="false" onAction="#handleExit" text="Exit" AnchorPane.bottomAnchor="10.0"> </Button>
      <Label layoutX="10.0" layoutY="90.0" text="costPosition1 in € =" />
      <TextField fx:id="tab_textField01_costPosition1" alignment="CENTER_RIGHT" layoutX="150.0" layoutY="85.0" onKeyReleased="#handleTabTextFieldCostPosition1" prefWidth="150.0" promptText="input an int value" />
   </children>
</AnchorPane>

- Directory structure
- Example started