JavaFX/SceneBuilder - Changing only PART of a Scen

2019-05-17 08:39发布

I'm a total newbie in JavaFX and I haven't found any tutorial/answer about this matter.

So basically what I'd like to do is change only part of my Scene. I want to keep a static menu bar at the top and only change the bottom part according to which menu button is being clicked. Which means I need different FXML files and Controller classes for every "page".

Looking at the available JavaFX features I thought SubScene would do the job. But after further investigation it seems that SubScenes are made for 3D stuff? So I really have no clue what I should do.

Any help would be greatly appreciated!

1条回答
走好不送
2楼-- · 2019-05-17 09:04

Changing parts of the scene is easy. In the main scene, you put a container in which you dynamically load different views. Here's an example following your description for a general "static" menu:

This is the basic view. In mainView, the different views are loaded (default is view_a.fxml) and are changed from the View > Show View X menu. The IDs I have assigned to the individual MenuItem are the names of the FXML files to load.

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
    <top>
        <MenuBar BorderPane.alignment="CENTER">
            <menus>
                <Menu mnemonicParsing="false" text="File">
                    <items>
                        <MenuItem mnemonicParsing="false" text="Close" />
                    </items>
                </Menu>
                <Menu mnemonicParsing="false" text="View">
                    <items>
                        <MenuItem fx:id="view_a" mnemonicParsing="false" text="Show View A" onAction="#handleChangeView"/>
                        <MenuItem fx:id="view_b" mnemonicParsing="false" text="Show View B" onAction="#handleChangeView"/>
                    </items>
                </Menu>
            </menus>
        </MenuBar>
    </top>
    <center>
        <BorderPane fx:id="mainView">
            <center>
                <fx:include source="view_a.fxml"/>
            </center>
        </BorderPane>
    </center>
</BorderPane>

This is one of the views (view_a.fxml). The other is the same, so I will not show it. In these views, it's interesting that I do not specify a controller because I later use the controller on the main frame (this is good for small things, but for big projects it is nice to use different controllers).

<AnchorPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml">
    <children>
        <Label text="View A"/>
    </children>
</AnchorPane>

The controller itself is nothing special. It just adds one ".fxml" to the ID of the option that is selected, loads the FXML file with the resulting name, and puts it in the mainView center

public class Controller {
    @FXML
    private BorderPane mainView;

    @FXML
    private void handleChangeView(ActionEvent event) {
        try {
            String menuItemID = ((MenuItem) event.getSource()).getId();

            FXMLLoader loader = new FXMLLoader(getClass().getResource(menuItemID + ".fxml"));
            loader.setController(this);

            mainView.setCenter(loader.load());
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}
查看更多
登录 后发表回答