JavaFX 8 - Tabpanes 和选项卡,每个选项卡都有单独的 FXML 和 Controller

标签 java model-view-controller javafx fxml fxmlloader

我希望得到一些关于在选项卡 Pane 中为每个选项卡添加 fx:include 语句的答案。我已经设法轻松地获取内容来显示,但是无论我如何构造它,相关 Controller 类的引用方法只会给我一个 nullpointerreference 异常。包含的 FXML 布局的 Controller 既没有构造函数也没有 initialize() 方法,是否需要它们?我尝试了一些不同的东西,但总是遇到相同的异常。

我所做的只是向选项卡 Pane 添加一个更改监听器,当按下选项卡时,我想用从全局可访问的数组列表中获取的一些值填充一些文本字段。注意:arraylist 不是问题,使用主 Controller 执行此操作工作正常。

我将很快添加一个代码示例,但现在还不能。如果您需要更多信息,请告诉我,否则我会在今天晚些时候发布代码。

*编辑,这是我的代码示例,取自 StackOverflow 上的另一个线程。 JavaFX TabPane - One controller for each tab

测试应用程序.java:

public class TestApp extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(new StackPane());

        FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/MainTestWindow.fxml"));
        scene.setRoot(loader.load());
        MainTestController controller = loader.getController();
        controller.init();

        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

主 Controller ,我想在其中引用子 Controller 。

public class MainTestController {

    @FXML private TabPane tabPane;
    // Inject tab content.
    @FXML private Tab fooTabPage;
    // Inject controller
    @FXML private FooTabController fooTabPageController;

    // Inject tab content.
    @FXML private Tab barTabPage;
    // Inject controller
    @FXML private BarTabController barTabPageController;

    public void init() {
        tabPane.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends Tab> observable,
                                                                        Tab oldValue, Tab newValue) -> {
            if (newValue == barTabPage) {
                System.out.println("Bar Tab page");
                barTabPageController.handleButton();
            } else if (newValue == fooTabPage) {
                System.out.println("Foo Tab page");
                fooTabPageController.handleButton();
            }
        });
    }
}

主视图的.fxml

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

<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.Tab?>

<TabPane fx:id="tabPane" fx:controller="controller.MainTestController" xmlns="http://javafx.com/javafx/8.0.40"
         xmlns:fx="http://www.w3.org/2001/XInclude">
    <tabs>
        <Tab fx:id="fooTabPage" text="FooTab">
            <fx:include source="fooTabPage.fxml"/>
        </Tab>
        <Tab fx:id="barTabPage" text="BarTab">
            <fx:include source="barTabPage.fxml"/>
        </Tab>
    </tabs>
</TabPane>

FooTab:

public class FooTabController {
    @FXML private Label lblText;

    public void handleButton() {
        lblText.setText("Byebye!");
    }
}

FooTab 的 .fxml:

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

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

<?import javafx.scene.control.Button?>
<VBox xmlns:fx="http://www.w3.org/2001/XInclude" fx:controller="controller.FooTabController">
    <Label fx:id="lblText" text="Helllo"/>
    <Button fx:id="btnFooTab" onAction="#handleButton" text="Change text"/>
</VBox>

条形标签:

public class BarTabController {
    @FXML private Label lblText;

    public void handleButton() {
        lblText.setText("Byebye!");
    }
}

BarTab 的 .fxml

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

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

<?import javafx.scene.control.Button?>
<VBox xmlns:fx="http://www.w3.org/2001/XInclude" fx:controller="controller.BarTabController">
    <Label fx:id="lblText" text="Helllo" />
    <Button fx:id="btnBarTab" onAction="#handleButton" text="Change text"/>
</VBox>

上面的 FooTab 和 BarTab 的 onAction 与它们各自的按钮一起工作。当此方法 (handleButton) 是来自主 Controller 的引用时,这就是我遇到异常的时候。

最佳答案

要为包含的 FMXL 文件注入(inject) Controller ,您需要 fx:id <fx:include> 上的属性元素。 Controller 将被注入(inject)到带有 "Controller" 的字段中附加到 fx:id值(value)。

如果你想注入(inject)实际的Tab同样,你需要一个单独的 fx:id为此。

所以:

<tabs>
    <Tab fx:id="fooTab" text="FooTab">
        <fx:include fx:id="fooTabPage" source="fooTabPage.fxml"/>
    </Tab>
    <Tab fx:id="barTab" text="BarTab">
        <fx:include fx:id="barTabPage" source="barTabPage.fxml"/>
    </Tab>
</tabs>

@FXML private TabPane tabPane;
// Inject tab content.
@FXML private Tab fooTab;
// Inject controller
@FXML private FooTabController fooTabPageController;

// Inject tab content.
@FXML private Tab barTab;
// Inject controller
@FXML private BarTabController barTabPageController;

关于JavaFX 8 - Tabpanes 和选项卡,每个选项卡都有单独的 FXML 和 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39164050/

相关文章:

Java的replaceAll()非数字和负数?

java - 如何从 java 请求采样器代码中的用户属性获取值

angularjs - 如何让 ng-init 触发 ng-change?

java - 如何计算 JavaFX TableView 中依赖于其他行的单元格的值?

java - 使用 Google App Engine 时如何关闭 DataNucleus Enhancer

php - 构建良好的 php 应用程序可以学习吗?

cocoa - Cocoa 中类之间的协调

java - 更改 JavaFX 文本区域中所选内容的前景色

java - 如何在JavaFx中删除TableRow

java - 使用 Java API 从事件网格 azure 函数访问 Blob