如何使用不同的fxml文件创建多个javafx控制器?

我一直在看一些博客和其他stackoverflow问题,我没有看到我的问题的直接答案。 我正在创建一个javafx gui客户端,我希望我的菜单栏在一个fxml中是一个控制器,然后我希望内容区域是额外的fxml文件。 登录屏幕将是一个fxml,登录屏幕将是应用程序的主要内容,并将在一个fxml中。 我该怎么做呢?

我只是不想在我的登录,菜单栏和主要内容的同一个文件中拥有我的所有代码。 这是我正在做的工作的图像:

在此处输入图像描述

使用FXML作为组件,使用自定义java类作为fx:root和FXML文件的fx:controller: http : //docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm

为此,您需要调用自定义java类FXMLLoader的构造函数,它将加载您的FXML。 优点是改变FXML加载组件的方式。

通过FXMLLoader与嵌套控制器实现组件实现组件的经典方法是:首先是FXML,然后是每个部件的控制器。

使用这种技术,首先是控制器,然后是每个组件的FXML。 并且您不会直接在FXML中加载FXML,您将在FXML中导入自定义Java类。

这是一个更好的抽象(无需知道在FXML中导入组件时如何实现组件)并帮助重用代码,就像实现具有FXML支持的自定义小部件一样。 要使组件可重用,请确保您的实现与其他部分没有紧密耦合,或使用IOC这样做(例如,使用Spring与JavaFX集成)。 这样,您就可以在应用程序的任何部分导入组件(就像DateInput小部件一样)而不用担心,您也不会重复代码。

在您的情况下,您将拥有:

public class MenuBox extends VBox { @FXML private LoginBox loginBox; @FXML private ProfilesBox profilesBox; public MenuBox() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("menu.fxml")); fxmlLoader.setRoot(this); fxmlLoader.setController(this); try { fxmlLoader.load(); } catch (IOException exception) { throw new RuntimeException(exception); } } public class LoginBox extends VBox { public LoginBox() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("login.fxml")); fxmlLoader.setRoot(this); fxmlLoader.setController(this); try { fxmlLoader.load(); } catch (IOException exception) { throw new RuntimeException(exception); } } public class ProfilesBox extends VBox { public ProfilesBox() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("profiles.fxml")); fxmlLoader.setRoot(this); fxmlLoader.setController(this); try { fxmlLoader.load(); } catch (IOException exception) { throw new RuntimeException(exception); } } 

您将在menu.fxml中导入LoginBox和ProfilesBox,以管理页面的全局布局:

          

login.fxml和profiles.fxml只包含基本组件。

  1. 您可以将FXML文档包含在另一个中 – 这可以帮助您分离设计逻辑

  2. 这意味着您可以拥有嵌套控制器 – 每个文档一个。

从文档中,您现在可以设置代码,以便逻辑可以分离,也可以从根控制器调用(如果需要)。

希望有所帮助。

我需要一个具有类似要求的弹出窗口(对节点和布​​局的更多控制)。

在完成建议后,我找到了一个可能有用的解决方案。

首先,我创建了第二个fxml文档和第二个控制器(在NetBeans中,New – > Empty FXML … – > Use Java Controller – > Create New …)。

有点挑战性的是弄清楚如何在主控制器中构建舞台并将其连接到弹出控制器。

链接传递参数JavaFX FXML提供了一些真正的好的见解和技术。

最终的代码看起来像这样(我希望它可以帮助某人):

 // Anchor Pane from the popup @FXML AnchorPane anchorPanePopup; @FXML private void soneButtonAction(ActionEvent event) throws IOException { Stage newStage = new Stage(); AnchorPane anchorPanePopup = (AnchorPane) FXMLLoader.load(getClass().getResource("Popup_FXML.fxml")); Scene scene = new Scene(anchorPanePopup); newStage.setScene(scene); newStage.initModality(Modality.APPLICATION_MODAL); newStage.setTitle("Dialog Window"); newStage.showAndWait(); } 
 package javafxapplication11; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.stage.Stage; public class FXMLDocumentController implements Initializable { @FXML private CheckBox c1; @FXML private CheckBox c2; public void clicked1(ActionEvent e) throws IOException { Parent home_page_parent =FXMLLoader.load(getClass().getResource("AddDcuFXML.fxml")); Scene home_page_scene = new Scene(home_page_parent); Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow(); app_stage.hide(); //optional app_stage.setScene(home_page_scene); app_stage.show(); } public void clicked2(ActionEvent e) throws IOException { Parent home_page_parent =FXMLLoader.load(getClass().getResource("ViewDCU.fxml")); Scene home_page_scene = new Scene(home_page_parent); Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow(); app_stage.hide(); //optional app_stage.setScene(home_page_scene); app_stage.show(); } public void clicked3(ActionEvent e) throws IOException { Parent home_page_parent =FXMLLoader.load(getClass().getResource("ViewDCU.fxml")); Scene home_page_scene = new Scene(home_page_parent); Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow(); app_stage.hide(); //optional app_stage.setScene(home_page_scene); app_stage.show(); } @Override public void initialize(URL arg0, ResourceBundle arg1) { // TODO Auto-generated method stub } }