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