How to drag an undecorated window (stage) of JavaFX
Asked Answered
A

3

21

I have this undecorated window:

public static void initStartPage(final Stage primaryStage) {

        final Stage startPage = new Stage();
        startPage.initStyle(StageStyle.UNDECORATED);
        //startPage.initOwner(primaryStage);
        //startPage.toFront();
        Scene scene = new Scene(agentsPanel(), 900, 500);
        startPage.setScene(scene);
        startPage.show();

    }

I would like to know how I can make it a draggable undecorated window? I want to change its position when the user selects the window with the right mouse button and then move the mouse while keeping the mouse button pressed down.

P.S. I tested this solution, but it's not working:

private static FlowPane flow;
    private static BorderPane bpi;

    public static void initStartPage(final Stage primaryStage) {

        final Stage startPage = new Stage();
        startPage.initStyle(StageStyle.UNDECORATED);
        startPage.initOwner(primaryStage);
        //startPage.toFront();
        Scene scene = new Scene(agentsPanel(primaryStage), 900, 500);
        startPage.setScene(scene);
        startPage.show();

    }

    private static double xOffset = 0;
    private static double yOffset = 0;

    public static BorderPane agentsPanel(final Stage primaryStage) {

        BorderPane bp = new BorderPane();
        bp.setPrefSize(900, 500);
        bp.setMaxSize(900, 500);

        HBox thb = new HBox(10); // Set spacing between each child into the HBox
        thb.setPadding(new Insets(15, 15, 15, 15));


        HBox bhb = new HBox(10); // Set spacing between each child into the HBox
        bhb.setPadding(new Insets(15, 15, 15, 15));

        bp.setTop(thb);
        bp.setBottom(bhb);
        bp.setCenter(navigationPanel());


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

        return bp;

    }
Arethaarethusa answered 11/8, 2013 at 16:9 Comment(3)
possible duplicate of How to make an undecorated window movable / dragable in JavaFX?Davison
Also duplicate of Moving an undecorated Stage in JavaFX 2Davison
I updated the post. I tested this code but it's not working.Arethaarethusa
D
44

Just change your setOnMousePressed method to this:

bp.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                xOffset = primaryStage.getX() - event.getScreenX();
                yOffset = primaryStage.getY() - event.getScreenY();
            }
        });

and your setOnMouseDragged to this:

bp.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                primaryStage.setX(event.getScreenX() + xOffset);
                primaryStage.setY(event.getScreenY() + yOffset);
            }
        });
Dorweiler answered 11/8, 2013 at 23:37 Comment(0)
D
12

The @Eeliyaanswer working well. However, code will shorter if using the below code because we don't need to declare variables.

We need to setOnMouseDragged again and again whenever setOnMouseDragged fired but I think it's not causing the problem.

bp.setOnMousePressed(pressEvent -> {
    bp.setOnMouseDragged(dragEvent -> {
        primaryStage.setX(dragEvent.getScreenX() - pressEvent.getSceneX());
        primaryStage.setY(dragEvent.getScreenY() - pressEvent.getSceneY());
    });
});

Hope it helps

Dichroic answered 14/4, 2020 at 10:37 Comment(1)
Works and looks pretty!Pyrometer
S
0

you can use this, works for a stage as well as an Alert (basically another stage but for pup po messages). the node is the main node of that stage

//Make a Stage Draggable
public void DraggableStage(Node node, Stage stage, Alert alert ) {
    double[] xOffset = {0}, yOffset = {0};
    node.setOnMousePressed(event -> {
        if (stage != null && alert == null){
            xOffset[0] = stage.getX() - event.getScreenX();
            yOffset[0] = stage.getY() - event.getScreenY();
        } else if(stage == null && alert != null){
            xOffset[0] = alert.getX() - event.getScreenX();
            yOffset[0] = alert.getY() - event.getScreenY();
        }
    });

    node.setOnMouseDragged(event -> {
        if (stage != null && alert == null){
            stage.setX(event.getScreenX() + xOffset[0]);
            stage.setY(event.getScreenY() + yOffset[0]);
        } else if(stage == null && alert != null){
            alert.setX(event.getScreenX() + xOffset[0]);
            alert.setY(event.getScreenY() + yOffset[0]);
        }
    });
}
Shay answered 19/8, 2019 at 7:46 Comment(6)
as to the content: for code hygiene: better not pass unneeded parameters - instead have dedicated methods for stage/alert eachDealings
why waste time and repeat code? it is matter of personal choice, you can use divide and conquer if you want but in this case I IS RELATED for the content as weel as all the other one I put in the last couple ot hoursShay
please edit them to follow naming conventions .. makes it much easier for others to read and understandDealings
you are applying offset to the main panel to dragg the stage (windows in javafx) so.... the naming convention for me is ok, anyway could be as the developer wantsShay
well, actually .. no: conventions are there for a reason (make code easier to read and understand at a glance). And no, on java planet, a method starting with a capital letter is a violation of convention, always - if you don't see that (yet), you might want to read up on them (see my first comment)Dealings
It is good to accept critisism but also it is need to know how to criticize, I was using Upper camel case so I accept the critisism but please, learn how to make opinions be the logic of code, not just in some technicalities that again.... are correct I admit but the intention is to help the comunity ;) ..... trace the code for error and test them to see if Im wrong :)Shay

© 2022 - 2024 — McMap. All rights reserved.