在JavaFX中,如何将数据从子JFXDrawer控制器传递到驻留在父控制器中的节点?
我有一个家长控制器说在JavaFX中,如何将数据从子JFXDrawer控制器传递到驻留在父控制器中的节点?,javafx,model-view-controller,jfoenix,Javafx,Model View Controller,Jfoenix,我有一个家长控制器说HomeController 它有一个带有侧面板控制器的节点侧面板(JFXDrawer)和一个带有不同控制器的节点锚定器 HomeController | / \ / \ / \ anchorPane SidePanel (Controller (Controller = SidePanelController) = varies) anchorPane节点应通过从SideP
HomeController
它有一个带有侧面板控制器的节点侧面板
(JFXDrawer)和一个带有不同控制器的节点锚定器
HomeController
|
/ \
/ \
/ \
anchorPane SidePanel
(Controller (Controller = SidePanelController)
= varies)
anchorPane
节点应通过从SidePanelController
单击菜单按钮加载多个fxml视图。
这里的问题在侧面板控制器
中,因为按钮在其内部,我无法直接加载anchorPane
,因为侧面板控制器
节点anchorPane
不存在
此问题似乎与重复,但不是因为父控制器正在等待场景关闭,所以它会将数据回迁到父控制器。但在我的例子中,每次单击菜单按钮,它都会相应地加载一个视图。
任何人都可以提供资源来制作JFXDrawer的控制器(作为子节点)
如果说,我有一个侧面导航抽屉sidepanel.fxml
如下
我有一个像这样的主屏幕
所以,通过使用以下代码,我将抽屉堆叠在homecontroller中
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();
}
最后,我将把它作为组合输出
现在我想要的是,每当我试图点击侧导航面板上的sayLorry Receipt
按钮时,它就会触发驻留在父控制器上的节点。即使在不关闭子节点的情况下将数据传递回父控制器的事件也会起作用。正如@Sedrick所建议的,我在HomeController
(父节点)本身的侧面板控制器
的所有按钮上初始化了事件。起初它返回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;
}
我发现的另一个优点是,我不必单独显示每个场景的ProgressBar/ProgressIndicator。由于子组件的ActionEvent位于ParentNode上,因此可以将ProgressBar/指示器绑定到它并像一个符咒一样工作 这回答了你的问题吗@塞德里克:这种联系有点相关。但它仍然不能回答我的问题。我可以这样简化我的问题。我们如何在子节点按钮上设置事件以触发父变量或节点?如果您使用这些模型思想构建项目,您将不会遇到当前的问题。另一个选项是@Sedrick。您给出的第二个链接是从父控制器向子控制器设置值的示例。我想要的是将值从子控制器提取回父控制器,以便父控制器处理它并相应地执行操作。很抱歉,我无法正确地重新编排我的问题。
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;
}
}
}
}