JavaFX 窗口拖动捕捉并且不流畅

tre*_*498 2 javafx

我正在开发一个以透明 AnchorPane(无标题栏和圆角)开头的应用程序。我希望能够拖动和移动窗口。我已经让它工作了,但是当我单击它时,窗口会向上捕捉到您从中心拖动的位置,而不是您单击的位置。

CSS:

.root {
    -fx-background-radius: 20; 
    -fx-border-radius: 20;
    -fx-background-color: transparent;
}
Run Code Online (Sandbox Code Playgroud)

主.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();
}
Run Code Online (Sandbox Code Playgroud)

控制器:

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);
    });
}
Run Code Online (Sandbox Code Playgroud)

我有一种感觉,我需要说明光标所在的位置,但我不知道该怎么做。我是正确的还是我遗漏了一些更容易的东西?

She*_*Rai 5

是的!你是对的!我有一个更简单的解决方法供您这样做:)

在你的Main.java类中添加以下代码,

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);
}
Run Code Online (Sandbox Code Playgroud)
  • calculateGap(MouseEvent event, Stage stage)正如方法名所说,它计算 MouseEvent 和 Stage 坐标之间的间隙。
  • dragStage(MouseEvent event, Stage stage)它允许您根据 MouseEvent 和计算的间隙拖动舞台。

start()方法中将这些 EventHandlers 设置在您的父根布局上,

layout.setOnMouseDragged(e -> this.dragStage(e, primaryStage));
layout.setOnMouseMoved(e -> this.calculateGap(e, primaryStage));
Run Code Online (Sandbox Code Playgroud)

现在你可以平滑地拖动你的窗口:)