如何从子组件访问父组件的控制器? JavaFX 8

问题描述 投票:-1回答:1

我正在尝试使用FXML在JavaFX中构建GUI。为此,我有一个FXML主页面,该页面包含3个自定义组件,这些组件也是我使用FXML创建的。这是我的代码目录:

src
   App.java
   ui
      MainView.java
      CustomHeader.java
      CustomBody.java
   fxml
      MainView.fxml
      CustomHeader.fxml
      CustomBody.fxml
   controller
      MainViewController.java
      CustomHeaderController.java
      CustomBodyController.java

App.java

package ui;

import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import model.main.TaskItem;

import java.time.LocalDateTime;
import java.util.ArrayList;

public class ProductivityTrackerApp extends Application {
    public static Stage primaryStage;
    public static final String TITLE = "App";
    public static final double WIDTH = 520;
    public static final double HEIGHT = 800;

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

    public void setPrimaryStage(Stage primaryStage) {
        this.primaryStage = primaryStage;
    }

    public static void setScene(Parent root) {
        try {
            Scene scene = new Scene(root, WIDTH, HEIGHT);
            primaryStage.setTitle(TITLE);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            System.out.println("Failed to load new Scene!");
        }
    }
    @Override
    public void start(Stage primaryStage) throws Exception {
        setPrimaryStage(primaryStage);
        setScene(new MainView());
    }
}

Main.fxml

<fx:root xmlns="http://javafx.com/javafx"
         xmlns:fx="http://javafx.com/fxml"
         fx:controller="controllers.MainController"
         fx:id="root"
         type="VBox">

    <children>
         <CustomHeader> </CustomHeader>
         <CustomBody> </CustomBody>
    </children>
</fx:root>

MainView.java

package ui;

import javafx.fxml.FXMLLoader;
import javafx.scene.layout.VBox;

import java.io.File;
import java.io.IOException;

public class MainView extends VBox {

    private static final String FXML = "src/fxml/MainView.fxml";
    private File fxmlFile = new File(FXML);

    public MainView() {
        this.load();
    };

    private void load() {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(fxmlFile.toURI().toURL());
            fxmlLoader.setRoot(this);
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }
}

CustomHeader.fxml

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

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<fx:root xmlns="http://javafx.com/javafx"
         xmlns:fx="http://javafx.com/fxml"
         fx:controller="controllers.CustomHeaderController"
         minHeight="80.0" prefWidth="520.0" type="StackPane">

<BorderPane>
    <left>

    </left>

    <center>
        <Label text="App"/>
    </center>

    <right>
       <Button text="Click here" onMouseClicked="#colorBody"/>
    </right>
</BorderPane>
</fx:root>

CustomHeader.java

package ui;

import javafx.fxml.FXMLLoader;
import javafx.scene.layout.StackPane;

import java.io.File;
import java.io.IOException;

public class MainView extends StackPane {

    private static final String FXML = "src/fxml/CustomHeader.fxml";
    private File fxmlFile = new File(FXML);

    public CustomHeader() {
        this.load();
    };

    private void load() {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(fxmlFile.toURI().toURL());
            fxmlLoader.setRoot(this);
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }
}

CustomBody.fxml


<fx:root xmlns="http://javafx.com/javafx"
         xmlns:fx="http://javafx.com/fxml"
         fx:controller="controllers.CustomBodyController"
         type="StackPane">

   <Rectangle width="240" height="240" StackPane.alignment = "CENTER"/>
</fx:root>

CustomBody.java

package ui;

import javafx.fxml.FXMLLoader;
import javafx.scene.layout.StackPane;

import java.io.File;
import java.io.IOException;

public class MainView extends StackPane {

    private static final String FXML = "src/fxml/CustomBody.fxml";
    private File fxmlFile = new File(FXML);

    public CustomBody() {
        this.load();
    };

    private void load() {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(fxmlFile.toURI().toURL());
            fxmlLoader.setRoot(this);
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }
}

控制器尚无功能。因此,我没有包括它们。

我想引入一种功能,以便对CustomHeader组件中的按钮执行onClick操作可更改CustomBody组件中矩形的颜色。但是,由于这些组件具有单独的控制器,所以我想知道是否有一种方法可以使我从MainController(父组件的控制器)访问这两个控制器。此外,如果可能,是否有更好的建议来调解两个同级组件的通信?

user-interface javafx javafx-8
1个回答
0
投票
<CustomHeader fx:id="customHead"> </CustomHeader>

在fxm文件中并添加变量

public CustomHead customHead;

在MainController中。

© www.soinside.com 2019 - 2024. All rights reserved.