2014-10-20 79 views
0

我在JavaFX中有一個可拖動的容器。該容器在PopUp中實現。我可以拖動容器,但是如果我拖動它,鼠標事件沒有一個常量座標。在2個固定位置之間快速切換鼠標位置。JavaFX Container Draggable

那是我的代碼:

container.setOnMouseDragged(new EventHandler<MouseEvent>() { 

      @Override 
      public void handle(MouseEvent me) { 
       // TODO Auto-generated method stub 

       if(dragAct==true){ 
        //Set the Position of the PopUp to the Position of the Mouse 
        setX(me.getX()); 
        setY(me.getY()); 
       } 
      } 
     }); 

的containe是垂直框。 Main-Class是PopUp-Class的擴展版本。

回答

1
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); 
    } 
} 
+0

它工作得很好,我有另一個關於彈出的問題。目前,PopUp可能會離開主舞臺......是否可以在主舞臺上綁定PopUp。 它不應該被允許離開主舞臺的窗口...有沒有解決方案,我嘗試了很多,但我不知道我能如何解決這個問題 – 2014-10-20 14:21:57

+0

只要檢查主舞臺的位置,它的寬度和高度,以及彈出窗口的寬度和高度,然後再移動它。 – 2014-10-20 14:23:35

+0

感謝您的解答,沒有自動化功能集成?我必須用數學來解決這個問題? – 2014-10-20 14:33:00