javaborderjavafx-8stagewindow-decoration

JavaFX 8: Stage insets (window decoration thickness)?


How can i determine the stage/window insets in JavaFX? In Swing i could simple write:

JFrame frame = new JFrame();
Insets insets = frame.getInsets();

What would be the equivalent in JavaFX to get the size of the border and the titlebar of the window?


Solution

  • You can determine these by looking at the bounds of the scene relative to the width and height of the window.

    Given a Scene scene;, scene.getX() and scene.getY() give the x and y coordinates of the Scene within the window. These are equivalent to the left and top insets, respectively.

    The right and bottom are slightly trickier, but

    scene.getWindow().getWidth()-scene.getWidth()-scene.getX()
    

    gives the right insets, and similarly

    scene.getWindow().getHeight()-scene.getHeight()-scene.getY()
    

    gives the bottom insets.

    These values will of course only make sense once the scene is placed in a window and the window is visible on the screen.

    If you really want an Insets object you can do something like the following (which would even stay valid if the border or title bar changed size after the window was displayed):

    import javafx.application.Application;
    import javafx.beans.binding.Bindings;
    import javafx.beans.binding.ObjectBinding;
    import javafx.geometry.Insets;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    public class WindowInsetsDemo extends Application {
    
        @Override
        public void start(Stage primaryStage) {
    
            Label topLabel = new Label();
            Label leftLabel = new Label();
            Label rightLabel = new Label();
            Label bottomLabel = new Label();
    
    
            VBox root = new VBox(10, topLabel, leftLabel, bottomLabel, rightLabel);
            root.setAlignment(Pos.CENTER);
    
            Scene scene = new Scene(root, 600, 400);
    
    
            ObjectBinding<Insets> insets = Bindings.createObjectBinding(() -> 
            new Insets(scene.getY(), 
                    primaryStage.getWidth()-scene.getWidth() - scene.getX(), 
                    primaryStage.getHeight()-scene.getHeight() - scene.getY(), 
                    scene.getX()),
                    scene.xProperty(),
                    scene.yProperty(),
                    scene.widthProperty(),
                    scene.heightProperty(),
                    primaryStage.widthProperty(),
                    primaryStage.heightProperty()
                );
    
            topLabel.textProperty().bind(Bindings.createStringBinding(() -> "Top: "+insets.get().getTop(), insets));
            leftLabel.textProperty().bind(Bindings.createStringBinding(() -> "Left: "+insets.get().getLeft(), insets));
            rightLabel.textProperty().bind(Bindings.createStringBinding(() -> "Right: "+insets.get().getRight(), insets));
            bottomLabel.textProperty().bind(Bindings.createStringBinding(() -> "Bottom: "+insets.get().getBottom(), insets));
    
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }