How to make an undecorated window movable / draggable in JavaFX?
Asked Answered
I

2

16

I have to create an application in which minimize and maximize button will be disabled.

I have used "StageStyle.UNDECORATED" with which the application will not be movable or draggable anymore, so I am searching for any other alternative to make my application.

Do anyone having solution for this?

Imf answered 3/11, 2012 at 5:16 Comment(2)
Does the above property hides the title bar all together ? How do you plan to drag the window ?Gascon
Yes NeilGhosh, the above property hides the whole title bar.Imf
O
30

To achieve the window to be undecorated but still movable/dragable you have to handle the appropriate MouseEvent on any node of your choice.

Example:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class SimpleWindowApplication extends Application {
    private double xOffset = 0;
    private double yOffset = 0;

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

    @Override
    public void start(final Stage primaryStage) {
        primaryStage.initStyle(StageStyle.UNDECORATED);
        BorderPane root = new BorderPane();

        root.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                xOffset = event.getSceneX();
                yOffset = event.getSceneY();
            }
        });
        root.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                primaryStage.setX(event.getScreenX() - xOffset);
                primaryStage.setY(event.getScreenY() - yOffset);
            }
        });

        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

Learn more from the very valuable examples contained on Oracle's JavaFX download page under: JavaFX Demos and Samples

Osteotome answered 19/11, 2012 at 19:29 Comment(2)
Yes pmoule, this is best solution for my problem, and is really much helpful for me. Thank you so much for your efforts.Imf
Worked just like that, thanks a lot for your research time... we've utilized urs :-DDoubledealing
E
0

Sole purpose of this class is to allow undecorated Window to be dragged. It also performs the duty to ensure TaskBar remains visible with FullScreen, and ensure undecorated window not dragged out of screen. Lastly its provides a bug fix to the error "css resource not found." Simply paste below code in the main class in the overridden start() method just about when the Stage is ABOUT READY to be shown or after.

WindowStyle.allowDrag(root, stage);
WindowStyle.stageDimension(stage.getWidth(), stage.getHeight());

NOTE: Paste the above when the Stage is ABOUT READY to be shown or after. For full screen window use:

WindowStyle.fullScreen(Stage stage);

To resize back to previous use:

WindowStyle.restoreScreen(Stage stage);

To add custom stylesheets to your scene, Simply paste below code in the main class in the overridden start() method after defining your scene.

scene.getStylesheets().add(WindowStyle.addStyleSheet(String css));

The name of css to be used for styling can be in the form of: main.css or styles/main.css

import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.input.MouseEvent;
import javafx.stage.Screen;
import javafx.stage.Stage;

/**
 * @author:   BENJAH
 */

public class WindowStyle {
    private static final Rectangle2D SCREEN_BOUNDS= Screen.getPrimary()
            .getVisualBounds();
    private static double[] pref_WH, offset_XY;
    private static String styleSheet;

    private WindowStyle(String css) {
        styleSheet= getClass().getResource(css).toString();
    }

    protected static void allowDrag(Parent root, Stage stage) {
        root.setOnMousePressed((MouseEvent p) -> {
            offset_XY= new double[]{p.getSceneX(), p.getSceneY()};
        });

        root.setOnMouseDragged((MouseEvent d) -> {
            //Ensures the stage is not dragged past the taskbar
            if (d.getScreenY()<(SCREEN_BOUNDS.getMaxY()-20))
                stage.setY(d.getScreenY() - offset_XY[1]);
            stage.setX(d.getScreenX() - offset_XY[0]);
        });

        root.setOnMouseReleased((MouseEvent r)-> {
            //Ensures the stage is not dragged past top of screen
            if (stage.getY()<0.0) stage.setY(0.0);
        });
    }

    //Sets the default stage prefered width and height.
    protected static void stageDimension(Double width, Double height) {
        pref_WH= new double[]{width, height};
    }

    protected static void fullScreen(Stage stage) {
        stage.setX(SCREEN_BOUNDS.getMinX());
        stage.setY(SCREEN_BOUNDS.getMinY());
        stage.setWidth(SCREEN_BOUNDS.getWidth());
        stage.setHeight(SCREEN_BOUNDS.getHeight());
    }

    protected static void restoreScreen(Stage stage) {
        stage.setX((SCREEN_BOUNDS.getMaxX() - pref_WH[0])/2);
        stage.setY((SCREEN_BOUNDS.getMaxY() - pref_WH[1])/2);
        stage.setWidth(pref_WH[0]);
        stage.setHeight(pref_WH[1]);
    }

    protected static String addStyleSheet(String css) {
        new WindowStyle(css);
        return styleSheet;
    }
}
Epigeal answered 21/12, 2017 at 17:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.