JavaFX Using alternative FXML structure for Title (Stage is root)
Asked Answered
C

1

1

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>
Cohune answered 26/8, 2014 at 16:19 Comment(0)
C
3

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.

Coop answered 26/8, 2014 at 19:43 Comment(1)
Many thx it resolved my problem. The only problem is, and that is not up to us, SceneBuilder who can't opet FXML after adding Stage and Scene tags.Cohune

© 2022 - 2024 — McMap. All rights reserved.