JavaFX 8: Changing title of primary stage


Question

How can the title of the primary stage be changed, when the window is already showen?

Stage#setTitle(String) apparently does not the trick.

1
3
10/21/2014 7:36:19 PM

Accepted Answer

setTitle(...) seems to work fine here:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class UpdateStageTitle extends Application {

    @Override
    public void start(Stage primaryStage) {
        TextField titleField = new TextField();
        titleField.textProperty().addListener((obs, oldText, newText) -> 
            primaryStage.setTitle(newText));
        HBox root = new HBox(5, new Label("Window title: "), titleField);
        root.setAlignment(Pos.CENTER);
        Scene scene = new Scene(root, 350, 75);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

Update following comments.

For a more complex example, if you need to set this in the controller's initialize method, you need to arrange for the controller to have a reference to the stage before the FXMLLoader's load() method is invoked. You can do this either by calling setController on the loader, or by calling setControllerFactory. I generally prefer setting the controller factory, as it allows for use of the fx:controller attribute in FXML (setting the controller directly prohibits this).

So:

PrimaryStageAware.java:

package application;

import javafx.stage.Stage;

public interface PrimaryStageAware {
    public void setPrimaryStage(Stage primaryStage);
}

Main.java:

package application;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.fxml.FXMLLoader;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("TitleSetter.fxml"));
            loader.setControllerFactory((Class<?> type) -> {
                try {
                    Object controller = type.newInstance();
                    if (controller instanceof PrimaryStageAware) {
                        ((PrimaryStageAware) controller).setPrimaryStage(primaryStage);
                    }
                    return controller ;
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
            HBox root = loader.load();
            Scene scene = new Scene(root,400,400);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

TitleSetter.fxml:

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

<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>

<HBox alignment="CENTER" xmlns:fx="http://javafx.com/fxml/1" 
    fx:controller="application.TitleSettingController">
    <Label text="Update title: "/>
    <TextField  fx:id="titleField" />
</HBox>

TitleSettingController.java:

package application;

import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class TitleSettingController implements PrimaryStageAware {
    private Stage stage ;

    @FXML
    private TextField titleField ;

    @Override
    public void setPrimaryStage(Stage primaryStage) {
        this.stage = primaryStage ;
    }

    public void initialize()  {
        updateTitle("Initial title");
        titleField.textProperty().addListener((obs, oldTitle, newTitle) -> updateTitle(newTitle));
    }

    private void updateTitle(String title) {
        if (stage != null) {
            stage.setTitle(title);
        } else {
            System.out.println("Warning: null stage");
        }
    }

}

(With the FXML in the same package alongside the Java files).

6
10/21/2014 8:30:29 PM

You can make Main class as singleton and to contact him via Main.getInstance()

For example:

public class Main extends Application {

    private static Main instance;
    public static Main getInstance() {
        return instance;
    }

    private Stage primaryStage;

    @Override
    public void start(Stage primaryStage) throws Exception{
        instance = this;
        this.primaryStage = primaryStage;
        Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
        this.primaryStage.setTitle("Init title");
        this.primaryStage.setScene(new Scene(root, 900, 650));
        this.primaryStage.show();
        FlatterFX.style();
    }

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

    public void updateTitle(String title) {
        primaryStage.setTitle(title);
    }
}

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon