繁体   English   中英

JavaFX 如何将新的 FXML 内容注入当前场景

[英]JavaFX how to inject new FXML content to current Scene

我有一个应用程序,其中包含带有标题和菜单的 HomeScene.fxml 文件。 HomeScene 也有dashboardPane,它应该在按下菜单按钮后动态更改。 仪表板窗格内容应从另一个 fxml 文件加载,例如“FinancesPane.fxml”或“SettingsPane.fxml”。

我试图替换 HomeController 中的dashboardPane 的内容:

@FXML
public void handleFinancesButtonAction() {
    FinancesPaneFactory paneFactory = new FinancesPaneFactory();
    dashBoardPane.getChildren().clear();
    dashBoardPane.getChildren().add(paneFactory.createPane());
}

我的 FinancesPaneFactory 看起来像这样:

public class FinancesPaneFactory extends PaneFactory {

    private static final String PANE_TEMPLATE_PATH = "/sceneTemplates/FinancesPane.fxml";

    public FinancesPaneFactory() {
        super(PANE_TEMPLATE_PATH );
    }

    @Override
    protected Pane generatePane(FXMLLoader loader) {
        try {
            return (Pane) loader.load();
        } catch (IOException e) {
            throw new FatBirdRuntimeException("Unable to load FinancesPane", e);
        }
    }

}

更清楚地说,这是 HomeScene 的样子: HomeScene 这个空白区域是一个dashboardPane,当用户按下左边的菜单按钮时,应该用另一个内容替换。

如何动态注入此内容?

是的,您应该这样做以保持场景图较低,并且您将从更好的性能中受益,我所做的是创建动态容器:

@FXML
private ScrollPane dynamicNode;

滚动窗格是一个不错的选择。

这被放入 MainController。

我的主控制器与其他控制器不同,主控制器实际上是我唯一初始化的控制器,因此在您的主程序类中,无论您如何称呼它:

private static MainViewController mainViewController;

...

 private static BorderPane loadMainPane() throws IOException {

        FXMLLoader loader = new FXMLLoader();
        loader.setController(mainViewController);
        BorderPane mainPane = (BorderPane) loader.load(
                CsgoRr.class
                .getResourceAsStream(Info.Resource.FXML_FILE_MAIN));
        mainPane.getStylesheets().add(CsgoRr.class.getResource("path...style.css").toString());

        return mainPane;
    }

不要忘记创建静态访问器,我拥有的其他控制器通常不会以这种方式创建,我在 fxml 中使用 fx:controller 来指定哪个控制器应该用于哪个 fxml ,通常可以方便地访问 mainController 。

因此,要更改您的视图,请在连接到您的菜单的主控制器方法中创建您更改视图的视图

@FXML
private void setViewPreferences() {
    setView(Info.Resource.FXML_FILE_PREFERENCES);
}

@FXML
private void setViewProductPage() {
    setView(Info.Resource.FXML_FILE_PRODUCT_PAGE);
}

当前在 dynamicNode 中是帮助查看当前选择的到底是什么,它的

private String currentlyInDynamicPane;//not important

这是 setView

   public void setView(String fxmlPath) {
         dynamicNode.setContent(getView(fxmlPath));
            currentlyInDynamicPane = fxmlPath;
   }


  public Node getView(String fxmlPath) {
        try {
            return new FXMLLoader(getClass().getResource(fxmlPath)).load();
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        }
    }

因此,当您单击左侧菜单时,您会交换 FXML 文件,您可以确保在开始时或菜单中未选择任何内容时显示一些默认 FXML。

这就是我做的方式,粗略地。

因此,将您的仪表板视为 DynamicPane,

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM