JavaFX Stage Example
This is a JavaFXStage Example. AStage in JavaFX is a top-level container that hosts aScene, which consists of visual elements. TheStage class in thejavafx.stage package represents a stage in a JavaFX application. The primary stage is created by the platform and passed to thestart(Stage s) method of the Application class. You can create additional stages as needed.
AStage object must be created and modified on the JavaFXApplication Thread. Recall that thestart() method of theApplication class is called on the JavaFXApplication Thread, and a primaryStage is created and passed to this method.
Note that the primary stage that is passed thestart() method is not shown. You need to call theshow() method to show it.
The following table shows an overview of the whole article:
Table Of Contents
The following examples use Java SE 7 and JavaFX 2.2.
1. Knowing the Details of Your Screens
1.1 The Code
FxStageExample1.java
import javafx.application.Application;import javafx.application.Platform;import javafx.collections.ObservableList;import javafx.geometry.Rectangle2D;import javafx.stage.Screen;import javafx.stage.Stage;public class FxStageExample1 extends Application{public static void main(String[] args) {Application.launch(args);}public void start(Stage stage) {// Create the ScreenListObservableList<Screen> screenList = Screen.getScreens();System.out.println("Screens Count: " + screenList.size());// Print the details of all screensfor(Screen screen: screenList) {print(screen);}// Exit the ProgramPlatform.exit();}public void print(Screen s) {// Print the DPISystem.out.println("DPI: " + s.getDpi());// Print the BoundsSystem.out.print("Screen Bounds: ");Rectangle2D bounds = s.getBounds();print(bounds);// Print the Visual BoundsSystem.out.print("Screen Visual Bounds: ");Rectangle2D visualBounds = s.getVisualBounds();print(visualBounds);}public void print(Rectangle2D r) {// Format the OutputSystem.out.format("minX=%.2f, minY=%.2f, width=%.2f, height=%.2f%n",r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());}}TheScreen class in thejavafx.stage package is used to get the details, for example, dots-per-inch (DPI) setting and dimensions of user screens (or monitors). If multiple screens are hooked up to a computer, one of the screens is known as the primary screen and others as nonprimary screens. You can get the reference of theScreen object for the primary monitor using the staticgetPrimary() method of theScreen class with the following code:
// Get the reference to the primary screenScreen primaryScreen = Screen.getPrimary();
The staticgetScreens() method returns anObservableList of Screen objects:
ObservableList screenList = Screen.getScreens();
You can get the resolution of a screen in DPI using thegetDpi() method of theScreen class as follows:
Screen primaryScreen = Screen.getPrimary();double dpi = primaryScreen.getDpi();
You can use thegetBounds() andgetVisualBounds() methods to get the bounds and visual bounds, respectively. Both methods return aRectangle2D object, which encapsulates the (x, y) coordinates of the upper-left and the lower-right corners, the width, and the height of a rectangle.
ThegetMinX() andgetMinY() methods return the x and y coordinates of the upper-left corner of the rectangle, respectively.
ThegetMaxX() andgetMaxY() methods return the x and y coordinates of the lower-right corner of the rectangle, respectively.
ThegetWidth() andgetHeight() methods return the width and height of the rectangle, respectively.
// Format the OutputSystem.out.format("minX=%.2f, minY=%.2f, width=%.2f, height=%.2f%n",r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());The bounds of a screen cover the area that is available on the screen. The visual bounds represent the area on the screen that is available for use, after taking into account the area used by the native windowing system such as task bars and menus. Typically, but not necessarily, the visual bounds of a screen represents a smaller area than its bounds.
If a desktop spans multiple screens, the bounds of the nonprimary screens are relative to the primary screen.
1.2 The Output
Screens Count: 1DPI: 100.0Screen Bounds: minX=0,00, minY=0,00, width=1366,00, height=768,00Screen Visual Bounds: minX=0,00, minY=0,00, width=1366,00, height=728,00
2. Showing the Primary Stage
2.1 The Code
FxStageExample2.java
import javafx.application.Application;import javafx.stage.Stage;public class FxStageExample2 extends Application{public static void main(String[] args) {Application.launch(args);}public void start(Stage stage) {// Display the Stagestage.show();// Close the Stagestage.close();}}Thestart() method has no code. When you run the application, you do not see a window, nor do you see output on the console. The application runs forever. You will need to use the system-specific keys to cancel the application.
@Overridepublic void start(Stage stage) {stage.close(); // Close the only stage you have}If you are using Windows, use your favorite key combination Ctrl + Alt + Del to activate the task manager! If you are using the command prompt, use Ctrl + C.
Recall that JavaFXApplication Thread is terminated when thePlatform.exit() method is called or the last shown stage is closed.
@Overridepublic void start(Stage stage) {Platform.exit(); // Exit the application}The JVM terminates when all nondaemon threads die. JavaFXApplication Thread is a nondaemon thread. TheApplication.launch() method returns when
the JavaFXApplication Thread terminates.
Theclose() method does not close the stage if the stage is not showing.
@Overridepublic void start(Stage stage) {stage.close(); // Close the only stage you have}The following code will show and close the stage:
// Display the Stagestage.show();// Close the Stagestage.close();
3. Setting the Bounds of a Stage
3.1 The Code
FxStageExample3.java
import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.layout.VBox;import javafx.stage.Stage;public class FxStageExample3 extends Application{public static void main(String[] args) {Application.launch(args);}public void start(Stage stage) {// Set the title of the Stagestage.setTitle("Stage with a Button in the Scene");// Create the ButtonButton button = new Button("Hello");// Create the VBoxVBox root = new VBox(button);// Create the SceneScene scene = new Scene(root, 200, 100);// Add the Scene to the Stagestage.setScene(scene);// Set the width and height of the Stagestage.setWidth(400);stage.setHeight(100);// Display the Stagestage.show();}}The bounds of aStage consist of four properties:x,y,width, andheight. Thex andy properties determine the location (or position) of the upper-left corner of the stage. Thewidth andheight properties determine its size. You can use the getters and setters for these properties to get and set their values.
Let’s add aButton to theScene and set the scene width and height to 300 and 100, respectively, as follows:
@Overridepublic void start(Stage stage) {// Set the title of the Stagestage.setTitle("Stage with a Button in the Scene");// Create the ButtonButton button = new Button("Hello");// Create the VBoxVBox root = new VBox(button);// Create the SceneScene scene = new Scene(root, 200, 100);// Add the Scene to the Stagestage.setScene(scene);// Set the width and height of the Stagestage.setWidth(400);stage.setHeight(100);// Display the Stagestage.show();}3.2 The GUI
The following image shows aStage with aScene that contains aButton where the size of theScene is not specified.

4. Initializing the Style of a Stage
4.1 The Code
FxStageExample4.java
import javafx.application.Application;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.Label;import javafx.scene.layout.VBox;import javafx.scene.paint.Color;import javafx.stage.Stage;import javafx.stage.StageStyle;public class FxStageExample4 extends Application{public static void main(String[] args) {Application.launch(args);}public void start(final Stage stage) {// Create the LabelLabel styleLabel = new Label("Stage Style");// Create the ButtonButton closeButton = new Button("Close");// Add an EventHandler to the ButtoncloseButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { stage.close(); } }); // Create the VBOxVBox root = new VBox();// Add the Children to the VBoxroot.getChildren().addAll(styleLabel, closeButton);// Create the SceneScene scene = new Scene(root, 200, 100);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("The Style of a Stage");// Display the Stagethis.show(stage, styleLabel, StageStyle.DECORATED);//this.show(stage, styleLabel, UNDECORATED);//this.show(stage, styleLabel, TRANSPARENT);//this.show(stage, styleLabel, UNIFIED);//this.show(stage, styleLabel, UTILITY);}private void show(Stage stage, Label styleLabel, StageStyle style) {// Set the text for the label to match the stylestyleLabel.setText(style.toString());// Set the stylestage.initStyle(style);// For a transparent style, set the scene fill to null. Otherwise, the// content area will have the default white background of the scene.if (style == StageStyle.TRANSPARENT) {stage.getScene().setFill(null);stage.getScene().getRoot().setStyle("-fx-background-color: transparent");} else if(style == StageStyle.UNIFIED) {stage.getScene().setFill(Color.TRANSPARENT);}// Display the stagestage.show();}}The area of aStage can be divided into two parts: content area and decorations.
The content area displays the visual content of itsScene. Typically, decorations consist of a title bar and borders. The presence of a title bar and its content varies depending on the type of decorations provided by the platform. Some decorations provide additional features rather than just an aesthetic look.
For example, a title bar may be used to drag a stage to a different location. Different buttons in a title bar may be used to minimize, maximize, restore, and close aStage.
In JavaFX, the style attribute of aStage determines its background color and decorations. Based on styles, you can have the following five types of stages in JavaFX:
- Decorated
- Undecorated
- Transparent
- Unified
- Utility
A decoratedStage has a solid white background and platform decorations.
An undecoratedStage has a solid white background and no decorations.
A transparentStage has a transparent background and no decorations.
A unifiedStage has platform decorations and no border between the client area and decorations. The client area background is unified with the decorations. To see the effect of the unified stage style, theScene should be filled withColor.TRANSPARENT. Unified style is a conditional feature. A utility stage has a solid white background and minimal platform decorations.
You can set the style of a stage using theinitStyle(StageStyle style) method of theStage class. The style of a stage must be set before it is shown for the first time. Setting it the second time, after the stage has been shown, throws a runtime exception.
By default, a stage is decorated.
The five types of styles for a stage are defined as five constants in theStageStyle enum:
- StageStyle.DECORATED
- StageStyle.UNDECORATED
- StageStyle.TRANSPARENT
- StageStyle.UNIFIED
- StageStyle.UTILITY
4.2 The GUI
The following figure shows theStage using theStageStyle.DECORATED style.

5. Moving an Undecorated Stage
5.1 The Code
FxStageExample5.java
import javafx.application.Application;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.Label;import javafx.scene.input.MouseEvent;import javafx.scene.layout.VBox;import javafx.stage.Stage;import javafx.stage.StageStyle;public class FxStageExample5 extends Application{private Stage stage;private double dragOffsetX;private double dragOffsetY;public static void main(String[] args) {Application.launch(args);}public void start(final Stage stage) {// Store the stage reference in the instance variable to// use it in the mouse pressed event handler later.this.stage = stage;// Create the LabelLabel msgLabel = new Label("Press the mouse button and drag.");// Create the ButtonButton closeButton = new Button("Close");// Add the EventHandler to the ButtoncloseButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { stage.close(); } });// Create the VBoxVBox root = new VBox();// Add the children to the VBoxroot.getChildren().addAll(msgLabel, closeButton);// Create the SceneScene scene = new Scene(root, 300, 200);// Set mouse pressed and dragged even handlers for the scenescene.setOnMousePressed(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { handleMousePressed(event); } });scene.setOnMouseDragged(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { handleMouseDragged(event); } });// Add the Scene to The Stagerstage.setScene(scene);// Set the Titlestage.setTitle("Moving a Stage");// Set the Style for the Stagestage.initStyle(StageStyle.UNDECORATED);// Display the Stagestage.show();}protected void handleMousePressed(MouseEvent e) {// Store the mouse x and y coordinates with respect to the// stage in the reference variables to use them in the drag eventthis.dragOffsetX = e.getScreenX() - stage.getX();this.dragOffsetY = e.getScreenY() - stage.getY();}protected void handleMouseDragged(MouseEvent e) {// Move the stage by the drag amountstage.setX(e.getScreenX() - this.dragOffsetX);stage.setY(e.getScreenY() - this.dragOffsetY);}}You can move a stage to a different location by dragging its title bar. In an undecorated or transparent stage, a title bar is not available. You need to write a few lines of code to let the user move this kind of stage by dragging the mouse over the scene area.
The above example show how to write the code to support dragging of aStage. If you change theStage to be transparent, you will need to drag the stage by dragging the mouse over only the message label, as the transparent area will not respond to the mouse events.
The following snippet of code adds the mouse pressed and mouse dragged event handlers to theScene:
// Set mouse pressed and dragged even handlers for the scenescene.setOnMousePressed(new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {handleMousePressed(event);}});scene.setOnMouseDragged(new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {handleMouseDragged(event);}});When you press the mouse in the scene, thehandleMousePressed() method is called. ThegetScreenX() andgetScreenY() methods of theMouseEvent object return the x and y coordinates of the mouse with respect to the upper-left corner of the screen.
When you drag the mouse, thehandleMouseDragged() method is called. The method computes and sets the position of theStage using the position of the mouse when it was pressed and its position during the drag.
5.2 The GUI
The following image shows aStage, which can be moved by the mouse handlers.

6. Initializing Modality of a Stage
6.1 The Code
FxStageExample6.java
import javafx.application.Application;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.Label;import javafx.scene.layout.VBox;import javafx.stage.Modality;import javafx.stage.Stage;import javafx.stage.Window;public class FxStageExample6 extends Application{public static void main(String[] args) {Application.launch(args);}public void start(final Stage stage) {/* Create the Buttons to display each kind of modal stage */Button ownedNoneButton = new Button("Owned None");ownedNoneButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { showDialog(stage, Modality.APPLICATION_MODAL); } });Button nonOwnedNoneButton = new Button("Non-owned None");nonOwnedNoneButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { showDialog(stage, Modality.APPLICATION_MODAL); } });Button ownedWinButton = new Button("Owned Window Modal");ownedWinButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { showDialog(stage, Modality.APPLICATION_MODAL); } });Button nonOwnedWinButton = new Button("Non-owned Window Modal");nonOwnedWinButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { showDialog(stage, Modality.APPLICATION_MODAL); } });Button ownedAppButton = new Button("Owned Application Modal");ownedAppButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { showDialog(stage, Modality.APPLICATION_MODAL); } });Button nonOwnedAppButton = new Button("Non-owned Application Modal");nonOwnedAppButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { showDialog(stage, Modality.APPLICATION_MODAL); } });// Create the VBoxVBox root = new VBox();// Add the children to the VBoxroot.getChildren().addAll(ownedNoneButton, nonOwnedNoneButton,ownedWinButton, nonOwnedWinButton,ownedAppButton, nonOwnedAppButton);// Create the SceneScene scene = new Scene(root, 300, 200);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("The Primary Stage");// Display the Stagestage.show();}private void showDialog(Window owner, Modality modality) {// Create a Stage with specified owner and modalityfinal Stage stage = new Stage();stage.initOwner(owner);stage.initModality(modality);// Create the LabelLabel modalityLabel = new Label(modality.toString());// Create the ButtonButton closeButton = new Button("Close");// Add the EventHandler to the ButtoncloseButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { stage.close(); } });// Create the VBoxVBox root = new VBox();// Add the Children to the VBoxroot.getChildren().addAll(modalityLabel, closeButton);// Create the SceneScene scene = new Scene(root, 200, 100);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("A Dialog Box");// Display the Stagestage.show();}}In a GUI application, you can have two types of windows: modal and modeless. When a modal window is displayed, the user cannot work with other windows in the application until the modal window is dismissed. If an application has multiple modeless windows showing, the user can switch between them at any time.

Thank you!
We will contact you soon.
JavaFX has three types of modality for a stage:
- None
- Window modal
- Application modal
Modality of aStage is defined by one of the following three constants in theModality enum in thejavafx.stage package:
- NONE
- WINDOW_MODAL
- APPLICATION_MODAL
You can set the modality of a stage using theinitModality(Modality m) method of theStage class as follows:
// Create a Stage object and set its modalityStage stage = new Stage();stage.initModality(Modality.WINDOW_MODAL);/* More code goes here.*/// Show the stagestage.show();
AStage can have an owner. An owner of aStage is anotherWindow. You can set an owner of aStage using theinitOwner(Window owner) method of theStage class.
The owner of aStage must be set before the stage is shown. The owner of aStage may be null, and in this case, it is said that theStage does not have an owner. Setting an owner of aStage creates an owner-owned relationship. For example, aStage is minimized or hidden if its owner is minimized or hidden, respectively.
The default modality of aStage isNONE. When aStage with the modalityNONE is displayed, it does not block any other windows in the application. It behaves as a modeless window. AStage with theWINDOW_MODAL modality blocks all windows in its owner hierarchy.
If aStage with its modality set toAPPLICATION_MODAL is displayed, you must work with theStage and dismiss it before you can work with any other windows in the application.
Notice that anAPPLICATION_MODAL stage blocks all other windows in the same application, irrespective of the owner-owned relationships.
6.2 The GUI
The following image displays the primary stage with six buttons. Each button opens a secondary stage with a specified modality and owner. The text of the buttons tells you what kind of secondary stage they will open.

When the secondary stage is shown, try clicking on the primary stage. When the modality of the secondary stage blocks the primary stage, you will not be able to
work with the primary stage; clicking the primary stage will set the focus back to the secondary stage.

7. Resizing a Stage
7.1 The Code
FxStageExample7.java
import javafx.application.Application;import javafx.geometry.Rectangle2D;import javafx.scene.Group;import javafx.scene.Scene;import javafx.stage.Screen;import javafx.stage.Stage;public class FxStageExample7 extends Application{public static void main(String[] args) {Application.launch(args);}public void start(Stage stage) {// Create the GroupGroup group = new Group();// Create the SceneScene scene = new Scene(group);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("A Maximized Stage");// Set the position and size of the stage equal to the position and// size of the screenRectangle2D visualBounds = Screen.getPrimary().getVisualBounds();stage.setX(visualBounds.getMinX());stage.setY(visualBounds.getMinY());stage.setWidth(visualBounds.getWidth());stage.setHeight(visualBounds.getHeight());// Display the Stagestage.show();}}You can set whether a user can or cannot resize a stage by using itssetResizable(boolean resizable) method.
Note that a call to thesetResizable() method is a hint to the implementation to make the stage resizable. By default, a stage is resizable.
Sometimes, you may want to restrict the use to resize a stage within a range of width and height. ThesetMinWidth(),setMinHeight(),setMaxWidth(), andsetMaxHeight() methods of theStage class let you set the range within which the user can resize a stage.
7.2 The GUI
The following image shows resizeableStage.
8. Showing a Stage and Waiting for It to Close
8.1 The Code
FxStageExample8.java
import javafx.application.Application;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.TextArea;import javafx.scene.layout.VBox;import javafx.stage.Stage;public class FxStageExample8 extends Application{// Create the counterprotected static int counter = 0;// Create the Stageprotected Stage lastOpenStage;// Create the TextAreaprotected TextArea area = new TextArea();public static void main(String[] args) {Application.launch(args);}public void start(Stage stage) {// Create the VBoxVBox root = new VBox();// Create the ButtonButton openButton = new Button("Open");// Add the EventHandler to the buttonopenButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { open(++counter); } });// Add the children to the VBoxroot.getChildren().addAll(openButton,area);// Create the SceneScene scene = new Scene(root, 400, 400);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("The Primary Stage");// Display the Stagestage.show();// Set the Stage as the last opened Stagethis.lastOpenStage = stage;}private void open(final int stageNumber) {// Create a new StageStage stage = new Stage();// Set the Title of the Stagestage.setTitle("#" + stageNumber);// Create a Say-Hello-ButtonButton sayHelloButton = new Button("Say Hello");// Add the EventHandler to the ButtonsayHelloButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { area.appendText("Hello from #" + stageNumber + "\n"); } });// Create an Open ButtonButton openButton = new Button("Open");// Add the EventHandler to the ButtonopenButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { open(++counter); } });// Create the VBoxVBox root = new VBox();// Add the children to the VBoxroot.getChildren().addAll(sayHelloButton, openButton);// Create the SceneScene scene = new Scene(root, 200, 200);// Add the Scene to the Stagestage.setScene(scene);// Set the Position of the Stagestage.setX(this.lastOpenStage.getX() + 50);stage.setY(this.lastOpenStage.getY() + 50);// Set the current Stage as the last opened Stagethis.lastOpenStage = stage;area.appendText("Before stage.showAndWait(): " + stageNumber + "\n");// Show the Stage and wait for it to closestage.showAndWait();area.appendText("After stage.showAndWait(): " + stageNumber + "\n");}}You often want to display a dialog box and suspend further processing until it is closed. For example, you may want to display a message box to the user with options to click yes and no buttons, and you want different actions performed based on which button is clicked by the user. In this case, when the message box is displayed to the user, the program must wait for it to close before it executes the next sequence of logic.
Consider the following pseudo-code:
Option userSelection = messageBox("Close", "Do you want to exit?", YESNO);if (userSelection == YES) { stage.close();}In this pseudo-code, when the messageBox() method is called, the program needs to wait to execute the subsequent if statement until the message box is dismissed.
The show() method of the Window class returns immediately, making it useless to open a dialog box in the above example. You need to use the showAndWait() method, which shows the stage and waits for it to close before returning to the caller. The showAndWait() method stops processing the current event temporarily and starts a nested event loop to process other events.
You can have multiple stages open using the showAndWait() method. Each call to the method starts a new nested event loop. A specific call to the method returns to the caller when all nested event loops created after this method call have terminated.
This rule may be confusing in the beginning. Let’s look at an example to explain this in detail. Suppose you have three stages: s1, s2, and s3. Stage s1 is opened using the call s1.showAndWait(). From the code in s1, stage s2 is opened using the call s2.showAndWait(). At this point, there are two nested event loops: one created by s1.showAndWait() and another by s2.showAndWait(). The call to s1.showAndWait() will return only after both s1 and s2 have been closed, irrespective of the order they were closed. The s2.showAndWait() call will return after s2 has been closed.
8.2 The GUI
The following image shows a program that will allow you to play with theshowAndWait() method call using multiple stages.
The primary stage is opened with an Open button. Clicking the Open button opens a
secondaryStage using theshowAndWait() method.

The secondary stage has two buttons—Say Hello and Open—which will, respectively, will print a message on the console and open another secondaryStage.
A message is printed on the console before and after the call to theshowAndWait() method.

You need to open multiple secondary stages, print messages by clicking the Say HelloButton, close them in any order you want, and then look at the output on the console.
9. Download Java Source Code
This was an example ofavafx.stage
You can download the full source code of this example here:JavaFxStageExample.zip

Thank you!
We will contact you soon.





