简体   繁体   English

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

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

I have an app, which has HomeScene.fxml file with headers and menu.我有一个应用程序,其中包含带有标题和菜单的 HomeScene.fxml 文件。 HomeScene has also dashboardPane, which should be changed dynamically after menu button is being pressed. HomeScene 也有dashboardPane,它应该在按下菜单按钮后动态更改。 Dashboard pane content should be loaded from another fxml file, lets say 'FinancesPane.fxml' or 'SettingsPane.fxml'.仪表板窗格内容应从另一个 fxml 文件加载,例如“FinancesPane.fxml”或“SettingsPane.fxml”。

Im trying to replace content of dashboardPane in HomeController:我试图替换 HomeController 中的dashboardPane 的内容:

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

My FinancesPaneFactory looks like this:我的 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);
        }
    }

}

To be more clear, this is how HomeScene looks like: HomeScene .更清楚地说,这是 HomeScene 的样子: HomeScene This empty space is a dashboardPane, and should be replaced with another content when user press the left menu button.这个空白区域是一个dashboardPane,当用户按下左边的菜单按钮时,应该用另一个内容替换。

How to inject this content dynamically?如何动态注入此内容?

Yes, you should do this to keep scene graph low and you will benefit from better performance , what i do is create dynamic container :是的,您应该这样做以保持场景图较低,并且您将从更好的性能中受益,我所做的是创建动态容器:

@FXML
private ScrollPane dynamicNode;

Scroll pane is a good choice.滚动窗格是一个不错的选择。

This is put to MainController.这被放入 MainController。

I have main controller different from others , main controller is actually the only one i initialize, so in your main program class whatever you call it :我的主控制器与其他控制器不同,主控制器实际上是我唯一初始化的控制器,因此在您的主程序类中,无论您如何称呼它:

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;
    }

Dont forget to create static accessor, other controllers that i have are usually not created this way , i use fx:controller in fxml to specify what controller should be for which fxml , its usually handy to have mainController accessable.不要忘记创建静态访问器,我拥有的其他控制器通常不会以这种方式创建,我在 fxml 中使用 fx:controller 来指定哪个控制器应该用于哪个 fxml ,通常可以方便地访问 mainController 。

So to change your views create in your main controller methods that are connected to your menu with whose you change views因此,要更改您的视图,请在连接到您的菜单的主控制器方法中创建您更改视图的视图

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

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

Currently in dynamicNode is helper to see what exactly is the current selected, its当前在 dynamicNode 中是帮助查看当前选择的到底是什么,它的

private String currentlyInDynamicPane;//not important

Here is setView这是 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;
        }
    }

So when you click left menu you swap FXML files, you can make sure that you have some default FXML shown at the start or when nothing in menu is selected as well.因此,当您单击左侧菜单时,您会交换 FXML 文件,您可以确保在开始时或菜单中未选择任何内容时显示一些默认 FXML。

This is the way i do it, roughly.这就是我做的方式,粗略地。

So think about YOUR DASHBOARD as DynamicPane,因此,将您的仪表板视为 DynamicPane,

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

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