如何将数据从子 JFXDrawer 控制器传递到驻留在 JavaFX 父控制器中的节点?

How to pass data from child JFXDrawer controller to a node residing in parent controller in JavaFX?

我有一个父控制器说 HomeController 它有一个节点 SidePanel (JFXDrawer) 和 SidePanelController 以及一个节点 anchorPanecontroller.

     HomeController
          |
         / \
        /   \
       /     \
 anchorPane  SidePanel
(Controller   (Controller = SidePanelController)
 = varies)

anchorPane 节点应加载多个带有从 SidePanelController 单击菜单按钮的 fxml 视图。 这里的问题是在SidePanelController因为按钮在里面,所以我不能直接加载anchorPane至于SidePanelController节点anchorPane不存在

这个问题似乎与 重复,但不是因为父控制器正在等待场景关闭,所以它会将数据取回父控制器。但就我而言,每次单击菜单按钮时,它都会相应地加载一个视图。
谁能提供为 JFXDrawer(作为子节点)制作控制器的资源。

如果说,我有一个像这样的侧边导航抽屉sidepanel.fxml

我有一个像这样的 HomeScreen

因此,通过使用以下代码,我将抽屉堆叠在我的家庭控制器中

try {
            SidePanelController controller = new SidePanelController();
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/sidepanel.fxml"));
            loader.setController(controller);
            Parent root = loader.load();
            drawer.setSidePane(root);
        } catch (IOException err) {
            err.printStackTrace();
        }

最后,我将把它作为组合输出

现在我想要的是每当我尝试单击侧导航面板上的 Lorry Receipt 按钮时,它应该触发驻留在父控制器上的节点。即使在不关闭子节点的情况下将数据传回父控制器的事件也将起作用。

正如@Sedrick 所建议的,我在 HomeController(父级)本身的 SidePanelController 的所有按钮上初始化了事件。起初它返回 NPE,但后来我让按钮初始化,然后将其取回父控制器。 所以这是解决方案。这可能是不道德的,所以其他替代方案仍然值得赞赏。

public class SidePanelController implements Initializable {
    @FXML
    private JFXButton btn_lr;
    @FXML
    private JFXButton btn_shipment;
    @FXML
    private JFXButton btn_add_inward;
}

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
   //Your other activities when sidedrawer/pane initializes
}

//After I initialize, I would like all of these buttons to be fetched to my Parent controller. So instead of me passing each button separately, I made a list to save my time.
public ObservableList<JFXButton> fetchAllButtons(){
        ObservableList<JFXButton> allbuttons = FXCollections.observableArrayList(btn_lr, btn_add_inward, btn_shipment);
        return allbuttons;
}

现在 HomeControllerParentController,我获取所有这些按钮并分别为其创建事件。所以这里是代码。

public class HomeController implements Initializable {
    @FXML
    private JFXHamburger hamburger;
    @FXML
    private JFXDrawer drawer;
    //Creating Hamburger Task to toggle sidebar
    HamburgerBackArrowBasicTransition burgerTask;

    //Declaring sidepanelcontroller globally because I need it in multiple methods.
    SidePanelController controller = new SidePanelController();

    //Finally a list to fetch the list of all buttons from SidePanelController
    ObservableList<JFXButton> sidebuttons;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
    //Using hamburger to toggle my side drawer
    burgerTask = new HamburgerBackArrowBasicTransition(hamburger);

    //Initializing the scene of drawer/SidePanel FXML file on Home.fxml or parent fxml itself 
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/sidepanel.fxml"));
        loader.setController(controller);
        Parent root = loader.load();
        drawer.setSidePane(root);
        sidebuttons = controller.fetchAllButtons();
        //Make sure not to declare this before initializing or else it returns NPE 
        } catch (Exception err) {
            err.printStackTrace();
        }

        //Finally you can declare your tasks for each button by declaring events on each of those buttons. I thought only common but different thing you can between buttons is the name of it. So I used switch statement just to point out each button separately. (I know this might be unethical, but works for me though)
    for (JFXButton button: sidebuttons) {
         switch (button.getText()){
             case "Lorry Receipt":
             button.setOnAction(actionEvent -> {
                       //Your actions here when button with name Lorry Receipt is pressed
             });
             break;
             case "Shipment Memo":
             button.setOnAction(actionEvent -> {
                    //Your actions when button with name shipment memo is pressed
             });
             break;
             case "Inward Challan":
             button.setOnAction(actionEvent -> {
                   //Your actions when button with name Inward Challan is pressed
             });
             break;
             }
       }
   }
}

我发现的其他优点是,我不必单独显示每个场景的 ProgressBar/ProgressIndicator。由于 Child Component 的 ActionEvent 在 ParentNode 上,因此 ProgressBar/Indicator 可以绑定到它并且像魅力一样工作。