2012-08-02 105 views
18

我一直在試圖移動未修飾的階段,在屏幕上,通過使用以下鼠標監聽器:移動未修飾階段的JavaFX 2

  • onPressed
  • onReleased
  • onDragged

這些事件來自一個矩形。我的想法是移動未修飾的窗口點擊矩形並拖動所有的窗口。

 
@FXML 
protected void onRectanglePressed(MouseEvent event) { 
    X = primaryStage.getX() - event.getScreenX(); 
    Y = primaryStage.getY() - event.getScreenY(); 
} 

@FXML 
protected void onRectangleReleased(MouseEvent event) { 
    primaryStage.setX(event.getScreenX()); 
    primaryStage.setY(event.getScreenY()); 
} 

@FXML 
protected void onRectangleDragged(MouseEvent event) { 
    primaryStage.setX(event.getScreenX() + X); 
    primaryStage.setY(event.getScreenY() + Y); 
} 

我得到的所有這些事件是當我按矩形並開始拖動窗口,它移動一點點。但是,當我釋放按鈕時,窗口移動到矩形所在的位置。

在此先感謝。

+0

無需處理事件onRectangleReleased。 – 2012-08-02 16:01:03

回答

17

我在未裝飾的窗口中創建了一個動畫時鐘的sample,您可以拖動它。從樣品

相關代碼:

// allow the clock background to be used to drag the clock around. 
final Delta dragDelta = new Delta(); 
layout.setOnMousePressed(new EventHandler<MouseEvent>() { 
    @Override public void handle(MouseEvent mouseEvent) { 
    // record a delta distance for the drag and drop operation. 
    dragDelta.x = stage.getX() - mouseEvent.getScreenX(); 
    dragDelta.y = stage.getY() - mouseEvent.getScreenY(); 
    } 
}); 
layout.setOnMouseDragged(new EventHandler<MouseEvent>() { 
    @Override public void handle(MouseEvent mouseEvent) { 
    stage.setX(mouseEvent.getScreenX() + dragDelta.x); 
    stage.setY(mouseEvent.getScreenY() + dragDelta.y); 
    } 
}); 

... 

// records relative x and y co-ordinates. 
class Delta { double x, y; } 

代碼看起來非常相似,你的,所以不明白爲什麼你的代碼是不是爲你工作。

+0

是的,它非常相似。終於找到了解決辦法,我的錯誤是使用了錯誤的事件。我正在使用場景構建器。但是實現setOnMouseDragged,一切都變得完美。謝謝! – 2012-08-03 07:55:29

+0

我注意到這種方法的刷新率低於系統窗口的拖動。希望我知道如何使用系統窗口位置重定位器。 – Pathfinder 2018-01-20 12:52:58

+0

設置舞臺到undecorated刪除窗口10支持快速邊緣調整 – Pathfinder 2018-01-20 13:13:44

3

我的猜測是,您:

onRectangleReleased() 

從您的

onRectanglePressed() 

傳遞同樣的座標,這是因爲如文檔中表示,從MouseEvent類返回的getX()方法

事件的水平位置相對於 的原點Mous eEvent的來源。

然後,當您釋放鼠標時,它實際上會將您的矩形放在第一次鼠標按下時的位置。

順便說一句,我使用的是StackPane用矩形內,然後採用下列代碼:

private void addDragListeners(final Node n){ 
     n.setOnMousePressed(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent me) { 
       if(me.getButton()!=MouseButton.MIDDLE) 
       { 
        initialX = me.getSceneX(); 
        initialY = me.getSceneY(); 
       } 
       else 
       { 
        n.getScene().getWindow().centerOnScreen(); 
        initialX = n.getScene().getWindow().getX(); 
        initialY = n.getScene().getWindow().getY(); 
       } 

      } 
     }); 

     n.setOnMouseDragged(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent me) { 
       if(me.getButton()!=MouseButton.MIDDLE) 
       { 
        n.getScene().getWindow().setX(me.getScreenX() - initialX); 
        n.getScene().getWindow().setY(me.getScreenY() - initialY); 
       } 
      } 
     }); 
} 

addDragListeners(mainStackPane); 

除此之外,我用的是鼠標中鍵居中在屏幕上我的窗口。我希望它有幫助。乾杯!

+0

謝謝。我正在使用場景構建器創建GUI,並且使用了錯誤的拖動事件。我實現onMouseDragged和所有作品。謝謝! – 2012-08-03 07:54:16

13

我正在使用此解決方案通過拖動任何包含的節點拖動undecoraqted階段。

private void addDraggableNode(final Node node) { 

    node.setOnMousePressed(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent me) { 
      if (me.getButton() != MouseButton.MIDDLE) { 
       initialX = me.getSceneX(); 
       initialY = me.getSceneY(); 
      } 
     } 
    }); 

    node.setOnMouseDragged(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent me) { 
      if (me.getButton() != MouseButton.MIDDLE) { 
       node.getScene().getWindow().setX(me.getScreenX() - initialX); 
       node.getScene().getWindow().setY(me.getScreenY() - initialY); 
      } 
     } 
    }); 
} 
1
double x, y; 

private void addDragListeners(final Node n, Stage primaryStage){ 

    n.setOnMousePressed((MouseEvent mouseEvent) -> { 
     this.x = n.getScene().getWindow().getX() - mouseEvent.getScreenX(); 
     this.y = n.getScene().getWindow().getY() - mouseEvent.getScreenY(); 
    }); 

    n.setOnMouseDragged((MouseEvent mouseEvent) -> { 
     primaryStage.setX(mouseEvent.getScreenX() + this.x); 
     primaryStage.setY(mouseEvent.getScreenY() + this.y); 
    }); 
} 

public void start(Stage primaryStage) { 

    try { 

     ... 

     addDragListeners(mainPane, primaryStage); 

    } catch (Exception e) { 
     e.printStackTrace(System.out); 
    } 

} 
1

基於jewelsea的答覆我做了兩個蘭巴表達式直接設置MouseListeners在我的start()方法的情景。工作正常:)

private double xOffset; 
private double yOffset; 
     /* 
     The two following lambda expressions makes it possible to move the application without the standard StageStyle 
     */ 
     //Lambda mouse event handler 
     scene.setOnMousePressed(event -> { 
      xOffset = primaryStage.getX() - event.getScreenX(); 
      yOffset = primaryStage.getY() - event.getScreenY(); 
     }); 
     //Lambda mouse event handler 
     scene.setOnMouseDragged(event -> { 
      primaryStage.setX(event.getScreenX() + xOffset); 
      primaryStage.setY(event.getScreenY() + yOffset); 
     });enter code here