JavaFX Using alternative FXML structure for Title

2019-09-11 02:37发布

I read answer about putting Title in FXML (JavaFx : Set window title in fxml file), but I don't understand how to call this code.

I can't call it in the classic way:

FXMLLoader loader = new FXMLLoader(getClass().getResource("some.fxml"));
Scene scene = new Scene(loader.load());
Stage stage = new Stage();
stage.initOwner(root.getScene().getWindow());
stage.initModality(Modality.WINDOW_MODAL);
stage.setScene(scene);
stage.show();

some.fxml

<?xml version="1.0" encoding="utf-8"?>

<?import javafx.scene.layout.VBox?>
<?import javafx.stage.Stage?>
<?import javafx.scene.Scene?>
<?import javafx.scene.control.Label?>

<Stage title="Some Stage">
  <scene>
    <Scene>
      <VBox xmlns:fx="http://javafx.com/fxml">
        <children>
          <Label text="John Doe"/>
        </children>
      </VBox>
    </Scene>
  </scene>
</Stage>

1条回答
三岁会撩人
2楼-- · 2019-09-11 03:25

Because the fxml is creating a stage, you don't need to create another stage in your Java code, just get a reference to the stage created by FXML and show it directly.

titled stage via fxml

StageLoader.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.*;

import java.io.IOException;

public class StageLoader extends Application {

    private void showDialog(Stage owner) {
        try {
            FXMLLoader loader = new FXMLLoader(
                    getClass().getResource("some.fxml")
            );
            Stage dialog = loader.load();
            dialog.initOwner(owner);
            dialog.initModality(Modality.WINDOW_MODAL);
            dialog.initStyle(StageStyle.UTILITY);
            dialog.show();
        } catch (IOException e) {
            System.out.println("Unable to load dialog FXML");
            e.printStackTrace();
        }
    }

    @Override
    public void start(final Stage stage) throws IOException {
        Button openDialog = new Button("Open Dialog");
        openDialog.setOnAction(event -> showDialog(stage));

        stage.setTitle("Main Window");
        stage.setScene(
                new Scene(
                        new StackPane(openDialog),
                        200, 200
                )
        );
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

I made a couple of minor modifications to the fxml to ensure the resultant stage is large enough to actually see the dialog stage title.

some.fxml

<?xml version="1.0" encoding="utf-8"?>

<?import javafx.scene.layout.VBox?>
<?import javafx.stage.Stage?>
<?import javafx.scene.Scene?>
<?import javafx.scene.control.Label?>

<Stage title="Some Stage" resizable="false" xmlns:fx="http://javafx.com/fxml" >
  <scene>
    <Scene>
      <VBox >
        <children>
          <Label text="John Doe" prefWidth="150"/>
        </children>
      </VBox>
    </Scene>
  </scene>
</Stage>

SceneBuilder who can't open FXML after adding Stage and Scene tags.

You could write the FXML with the stage and scene definitions as an outer shell with an embedded <fx:include..> statement to include an inner FXML document which could be opened edited directly in SceneBuilder. Also, you could create a feature request against SceneBuilder (it is called the "design tool" in the issue tracker), to request direct support for FXML files with stage roots and scenes included in the FXML.

查看更多
登录 后发表回答