2016-11-17 65 views
2

我有一個節點,我想實現拖放(此對象是源不是目標)。我也希望對象隨鼠標光標一起移動。我設法做到了這兩個,但不是在同一時間。如何在拖放操作中執行代碼?

看起來setOnDragDetectedsetOnMouseDragged不能很好地協同工作。考慮一個節點具有以下處理:

import javafx.application.Application; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.input.ClipboardContent; 
import javafx.scene.input.Dragboard; 
import javafx.scene.input.TransferMode; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

public class Example extends Application { 

    @Override 
    public void start(Stage primaryStage) throws Exception { 

     Rectangle rect = new Rectangle(20, 20); 
     rect.setOnMousePressed(e -> System.out.println("Pressed")); 
     rect.setOnMouseDragged(e -> System.out.println("Dragged")); 
     rect.setOnDragDetected(e -> { 
      System.out.println("Detected"); 
      ClipboardContent content = new ClipboardContent(); 
      content.putString("something"); 
      Dragboard db = rect.startDragAndDrop(TransferMode.ANY); 
      db.setContent(content); 
     }); 
     Group subGroup = new Group(rect); 

     Scene scene = new Scene(subGroup, 100, 100); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 

     Example.launch(args); 
    } 
} 

現在點擊鼠標的節點上,然後移動鼠標。這是輸出:

Pressed 
Dragged 
Dragged 
Dragged 
Dragged 
Dragged 
Dragged 
Detected 

一旦檢測到拖動,MouseDragged處理程序停止。

我如何實現我所描述的?我注意到的一件事可能是我可以使用onDragOver作爲父項,但我希望行爲在節點中,因爲那就是它應該在的位置。

+0

我根本沒有觀察到這種行爲;檢測到拖動手勢後,onMouseDragged處理程序繼續進行報告。你應該創建一個[MCVE]並且[編輯]你的問題來包含它。 –

+0

@James_D對不起。這裏是代碼。它與我想的拖板有關。 – Mark

回答

0

你在這裏混合兩件事。簡而言之,當您調用startDragAndDrop方法時,系統將切換到拖放模式,並且Java停止將MouseEvent傳送到rect

MouseEvent documentation有一個「拖動手勢」部分,它解釋了三種拖動手勢類型。這裏只是一個簡短的總結:

  • 簡單按拖拽釋放 - 當檢測到拖拽的Java將繼續提供MouseEvents到檢測拖動的節點。
  • 完全按壓 - 拖放 - 您可以在setOnDragDetected設置的處理程序中調用startFullDrag。然後,Java也開始向其他節點(潛在手勢目標)傳遞MouseDragEvents
  • 平臺支持的拖放 - 如果您在OnDragDetected處理函數中調用startDragAndDrop,則Java將停止傳遞MouseEvents並開始交付DragEvents。這用於與其他應用程序的拖放交互。

我不清楚你想達到什麼目的,但只要你不想在應用程序外面拖動某些東西,請嘗試使用startFullDrag來代替。

另外,進一步查看DragEventMouseDragEvent文檔可能會有幫助。

+0

我只需要我的應用程序中的事件。如果我使用'startFullDrag',目標節點不會響應'OnDragEntered'並退出。有些東西需要檢查拖放操作是否正在發生,正在進入/離開他們的空間並根據內容做出反應 - 如果它是有效的。這我只能用'startDragAndDrop'來完成。 – Mark

+0

@Mark如果您使用'startFullDrag',則需要在目標上設置OnMouseDragEntered處理程序,而不是OnDragEntered。 – FelixRabe

+0

是的,但鼠標拖動處理程序的功能與D&D處理程序不同。例如:'OnDragDone'允許在拖動結束時對源進行操作,但沒有與「onMouseDragDone」等效的內容。此外,鼠標指針不會改變,以指示放置目標是否有效,就像它與D&D一樣。 – Mark