如何从JavaFX应用程序类中检索舞台(Stage)

3
我正在编写一个应用程序,其中包含两个不同的BorderPane,BorderPane A和BorderPane B。 该应用程序有两个菜单项,当单击时必须显示BorderPane A或BorderPane B。
这是Application类,其中包含我想要使用的舞台。
public class SampleApp extends Application {
private Stage primaryStage;

public static void main(final String[] args) {
    launch(args);
}    
@Override
public void start(final Stage stage)
        throws Exception {
    final AnnotationConfigApplicationContext context = new  AnnotationConfigApplicationContext(SampleAppFactory.class);
    final SpringFxmlLoader loader = new SpringFxmlLoader(context);      
    final Parent root = (Parent) loader.load("Main.fxml", Main.class);
    final Scene scene = new Scene(root, 600, 480, Color.ALICEBLUE);
    this.primaryStage = stage;
    scene.getStylesheets().add("fxmlapp.css");
    stage.setScene(scene);
    stage.show();
}
}

Main.java类有两个BorderPanes,当选择menuItem时,我想在应用程序中显示borderpane。

有人知道如何从这个方法(showBorderPane)显示Borderpane(设置舞台上的场景)吗? 我想检索Stage并使用borderpane设置场景:

public class Main extends BorderPane implements Initializable {

@FXML
private Verbinding verbindingContent; // BORDERPANE A
@FXML
private Beheer beheerContent;// BORDERPANE A
@FXML
private MenuBar menuContent;

@Override
public void initialize(final URL url, final ResourceBundle rb) {
    System.out.println(url);
    menuContent.setFocusTraversable(true);
}

@FXML
private void showBorderPane(final ActionEvent event) {
    final MenuItem menuItem = (MenuItem) event.getSource();
}


@FXML
private void handleCloseAction(final ActionEvent event) {
    System.exit(0);
}

我的Main.xml

<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.effect.*?>
<?import nl.mamaloe.tab.view.Main?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="nl.mamaloe.tab.view.Main">
<fx:define>     
    <fx:include source="scene/Beheer.fxml" fx:id="beheerContent" />
    <!-- fx:include source="Menu.fxml" fx:id="menuContent" / -->
</fx:define>
<top>
    <MenuBar fx:id="menuContent" onMouseClicked="#handleKeyInput">
        <menus>
            <Menu text="Systeem">
                <items>
                    <MenuItem text="Verbinding maken" onAction="#handleVerbindingAction"/>
                    <SeparatorMenuItem />
                    <MenuItem text="Afsluiten"  onAction="#handleCloseAction"/>
                </items>
            </Menu>

            <Menu text="TAB">
                <items>
                    <MenuItem text="Script toevoegen" onAction="#handleAboutAction"/>
                    <SeparatorMenuItem />
                    <MenuItem text="Script draaien" />                      
                </items>
            </Menu>
            <Menu text="About" onAction="#handleAboutAction">
                <items>
                    <MenuItem text="Op basis van wizard" />
                </items>
            </Menu>
        </menus>
    </MenuBar>
</top> 
<center>   <Label text="Add New Dock of Home" />

</center>

我看到可以在应用程序的start方法中实现这一点。 但是由于结构和我主要使用FXML来声明GUI,我想在Main.java中实现它。

1个回答

1
当FXMLLoader加载“Main.fxml”文件时,会创建一个新的BorderPane(在Main.fxml中定义)。加载器还会创建/初始化其控制器类,该类是另一个BorderPane派生类,并具有自己的实例。因此,存在两个不同的BorderPane实例。尽管您的设计与一般方法略有不同,但为了实现您的目标,我建议在FXML文件中向中心添加一个容器,如下所示:
<center>
    <StackPane fx:id="pane">
        <children>
              <Label text="Add New Dock of Home" />
        </children>
    </StackPane>
</center>

您可以将StackPane更改为任何您想要的面板/布局。 接下来,在控制器类中创建一个链接:

@FXML
private StackPane pane;

你应该移除 "extends BorderPane",因为它已经没有意义了。最后,

@FXML
private void showBorderPane(final ActionEvent event) {
    final MenuItem menuItem = (MenuItem) event.getSource();
    pane.getChildren().clear(); // Clear old content.
    switch (menuItem.getText()) {
        case "Borderpane A":
            pane.getChildren().add(borderPaneA);
            break;
        case "Borderpane B":
            pane.getChildren().add(borderPaneB);
            break;
       default:
            pane.getChildren().add(new Label("Add New Dock of Home"));
    }
}

我实际上只想像你第一个例子中那样切换BorderPane的中心部分。但是这似乎不起作用。 因为当我从showBorderPane方法中调用this.getScene();时,我会得到一个Nullpointer异常。我之前尝试过这个,因为我也认为主Borderpane应该有一个场景。或者我做错了什么吗? - Firebird
我不明白。子BorderPane已经在主BorderPane中了,为什么您还要尝试将它们再次放置到中心位置?而且在您的情况下,使用this.setCenter()就足够了,不需要使用this.getScene()。 - Uluk Biy
我认为你混淆了概念。如果你在main.fxml中将BorderPane作为根节点,那么它的控制器Main.java就不应该扩展BorderPane。如果这样做了,那么这两个BorderPane就是两个不相关的面板。移除"extends BorderPane"并重试。 - Uluk Biy
如果我删除了“extends BorderPane”,我将无法从Java类(Main.java)更改边框(布局)。 顺便说一下,我已经添加了Main.fxml。 - Firebird
请注意我的回答。在Main.fxml文件中,将StackPane的**fx:id="pane"**设置为<StackPane fx:id="pane"> - Uluk Biy
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接