Reputation: 35
I am working on an application that begins with an TRANSPARENT AnchorPane (no title bar and round corners). I want to be able to drag and move the window around. I have gotten it to work, but when I click it, the window snaps upwards to where you are dragging from the center instead of where you click.
CSS:
.root {
-fx-background-radius: 20;
-fx-border-radius: 20;
-fx-background-color: transparent;
}
Main.java:
public void start(Stage primaryStage) throws Exception {
primaryStage.initStyle(StageStyle.TRANSPARENT);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("../Scenes/Login.fxml"));
//Creates the layout for the new scene
AnchorPane layout = (AnchorPane) loader.load();
Scene scene = new Scene(layout);
scene.setFill(Color.TRANSPARENT);
scene.getStylesheets().add(getClass().getResource("../StyleSheets/application.css").toExternalForm());
LoginController.allowDrag(layout, primaryStage);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
}
Controller:
private static final Rectangle2D SCREEN_BOUNDS = Screen.getPrimary().getVisualBounds();
public static void allowDrag(AnchorPane root, Stage primaryStage) {
root.setOnMousePressed((MouseEvent mouseEvent1) -> {
xOffset = mouseEvent1.getSceneX();
yOffset = mouseEvent1.getScreenY();
});
root.setOnMouseDragged((MouseEvent mouseEvent2)-> {
if (!mouseEvent2.isPrimaryButtonDown()) return;
//Ensures the stage is not dragged past the taskbar
if (mouseEvent2.getScreenY()<(SCREEN_BOUNDS.getMaxY()-20))
primaryStage.setY(mouseEvent2.getScreenY() - yOffset);
primaryStage.setX(mouseEvent2.getScreenX() - xOffset);
primaryStage.setY(mouseEvent2.getScreenY() - yOffset);
});
root.setOnMouseReleased((MouseEvent mouseEvent3)-> {
//Ensures the stage is not dragged past top of screen
if (primaryStage.getY()<0.0) primaryStage.setY(0.0);
});
}
I have a feeling that I need to account for where the cursor is, but I am not sure how to. Am I correct or is there something easier I am missing?
Upvotes: 2
Views: 747
Reputation: 17
Well done that is complete solution of this problem. if you want to drag window of javafx login then you can use this.
package com.systems.auth;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
import javafx.scene.input.MouseEvent;
import javafx.stage.StageStyle;
/**
* JavaFX App
*/
public class App extends Application {
private static Scene scene;
private double gapX = 0, gapY = 0;
@Override
public void start(Stage stage) throws IOException {
Parent root = loadFXML("login");
scene = new Scene(root, 700, 500);
stage.setResizable(false);
stage.initStyle(StageStyle.DECORATED.UNDECORATED);
root.setOnMouseDragged(e -> this.dragStage(e, stage));
root.setOnMouseMoved(e -> this.calculateGap(e, stage));
stage.setScene(scene);
stage.show();
}
private void calculateGap(MouseEvent event, Stage stage) {
gapX = event.getScreenX() - stage.getX();
gapY = event.getScreenY() - stage.getY();
}
private void dragStage(MouseEvent event, Stage stage) {
stage.setX(event.getScreenX() - gapX);
stage.setY(event.getScreenY() - gapY);
}
static void setRoot(String fxml) throws IOException {
scene.setRoot(loadFXML(fxml));
}
private static Parent loadFXML(String fxml) throws IOException {
System.out.print(App.class.getResource(fxml + ".fxml"));
FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
return fxmlLoader.load();
}
public static void main(String[] args) {
launch();
}
}
Upvotes: 0
Reputation: 2058
Yes! you're right! And I have a simpler workaround for you to do so :)
Add the following code in your Main.java
class,
private double gapX = 0, gapY = 0;
private void calculateGap(MouseEvent event, Stage stage) {
gapX = event.getScreenX() - stage.getX();
gapY = event.getScreenY() - stage.getY();
}
private void dragStage(MouseEvent event, Stage stage) {
stage.setX(event.getScreenX() - gapX);
stage.setY(event.getScreenY() - gapY);
}
Set these EventHandlers on your parent root layout in start()
method,
layout.setOnMouseDragged(e -> this.dragStage(e, primaryStage));
layout.setOnMouseMoved(e -> this.calculateGap(e, primaryStage));
Now you can drag your window smoothly :)
Upvotes: 5