Drag an undecorated Stage with the mouse.

One quick post to share a simple class that will allow users to drag a Stage if it has been declared Transparent or undecorated.

Sometimes, you may want to design your Window from scratch. That is to say remove the OS title bar and replace it with your own. To do that, you can create a Stage like that (javadoc):

Stage stage = new Stage(StageStyle.TRANSPARENT);

I created an abstract class that you extend. Then you simply call the method allowDrag when you have finished designing your window. Give it your custom titleBar, an HBox for example, and it will set the listeners. Then you can click on your title bar and drag the window where you want.

import javafx.event.EventHandler;
import javafx.event.WeakEventHandler;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

/**
 *
 * The sole purpose of this class if to allow undecorated Window to be dragged
 * with the mouse. Simply call {@link #allowDrag(javafx.scene.Node, javafx.stage.Stage)
 * } when the Stage is ready to be shown.
 */
public abstract class UndecoratedWindow {

    private double mouseDragDeltaX = 0;
    private double mouseDragDeltaY = 0;
    private EventHandler<MouseEvent> mousePressedHandler;
    private EventHandler<MouseEvent> mouseDraggedHandler;
    private WeakEventHandler<MouseEvent> weakMousePressedHandler;
    private WeakEventHandler<MouseEvent> weakMouseDraggedHandler;

    /**
     * Give the Node that will be dragged (entire window or simply your Title
     * Bar), and the Stage that will be moved.
     *
     * @param node
     * @param stage
     */
    protected void allowDrag(Node node, Stage stage) {
        mousePressedHandler = (MouseEvent event) -> {
            mouseDragDeltaX = node.getLayoutX() - event.getSceneX();
            mouseDragDeltaY = node.getLayoutY() - event.getSceneY();
        };
        weakMousePressedHandler = new WeakEventHandler<>(mousePressedHandler);
        node.setOnMousePressed(weakMousePressedHandler);

        mouseDraggedHandler = (MouseEvent event) -> {
            stage.setX(event.getScreenX() + mouseDragDeltaX);
            stage.setY(event.getScreenY() + mouseDragDeltaY);
        };
        weakMouseDraggedHandler = new WeakEventHandler<>(mouseDraggedHandler);
        node.setOnMouseDragged(weakMouseDraggedHandler);
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *