2014-10-20 41 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