JavaFX Container Draggable
您调用的setX和setY方法将弹出窗口的位置设置为屏幕坐标。对me.getX()和me.getY()的调用将为您提供鼠标相对于容器的坐标。当您移动弹出窗口时,容器也会移动,因此鼠标的位置相对于容器发生了变化。所以你的计算不会从一个拖动事件到下一个事件保持一致。
解决的办法是计算相对于固定事物的位置。由于您正在移动弹出窗口,这是一个窗口,固定坐标系是屏幕坐标系。 MouseEvent具有getScreenX和getScreenY方法,您可以使用它们轻松获取这些方法。
我喜欢通过保存最后一个鼠标位置来实现拖动,然后计算拖动时移动的距离。还有其他(可能不太详细)的方式做到这一点,但对我来说这是最清楚的:
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Popup;
import javafx.stage.Stage;
public class DraggingPopup extends Application {
@Override
public void start(Stage primaryStage) {
Button button = new Button("Show popup");
button.setOnAction(event -> showDraggablePopup(primaryStage));
StackPane root = new StackPane(button);
Scene scene = new Scene(root, 250, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
private void showDraggablePopup(Stage owner) {
Popup popup = new Popup();
Button closeButton = new Button("Close");
closeButton.setOnAction(event -> popup.hide());
StackPane container = new StackPane(closeButton);
container.setStyle("-fx-background-color: steelblue;");
container.setMinWidth(300);
container.setMinHeight(125);
// Dragging implementation:
ObjectProperty<Point2D> mouseLocation = new SimpleObjectProperty<>();
container.setOnMousePressed(event ->
mouseLocation.set(new Point2D(event.getScreenX(), event.getScreenY())));
container.setOnMouseDragged(event -> {
if (mouseLocation.get() != null) {
double x = event.getScreenX();
double deltaX = x - mouseLocation.get().getX() ;
double y = event.getScreenY();
double deltaY = y - mouseLocation.get().getY() ;
//in case of 2 or more computer screens this help me to avoid get stuck on 1 screen
if(Math.abs(popup.getX()-x)>popup.getWidth()){
popup.setX(x);
popup.setY(y);
}else {
popup.setX(popup.getX() + deltaX);
popup.setY(popup.getY() + deltaY);
}
mouseLocation.set(new Point2D(x, y));
}
});
container.setOnMouseReleased(event -> mouseLocation.set(null));
popup.getScene().setRoot(container);
popup.show(owner);
}
public static void main(String[] args) {
launch(args);
}
}
它工作得很好,我有另一个关于弹出的问题。目前,PopUp可能会离开主舞台......是否可以在主舞台上绑定PopUp。 它不应该被允许离开主舞台的窗口...有没有解决方案,我尝试了很多,但我不知道我能如何解决这个问题 – 2014-10-20 14:21:57
只要检查主舞台的位置,它的宽度和高度,以及弹出窗口的宽度和高度,然后再移动它。 – 2014-10-20 14:23:35
感谢您的解答,没有自动化功能集成?我必须用数学来解决这个问题? – 2014-10-20 14:33:00