2017-03-06 102 views
1

在我的JavaFX應用程序中,我支持從應用程序內部拖放操作系統到我的應用程序。下面的行爲是我想什麼來完成:取消拖動操作JavaFX

  • 如果用戶從我的應用程序內開始拖動和他離開我的主窗口中,用鼠標(離開我的應用程序),我想取消拖動動作,所以即使他用光標回來,他也不會觸發任何dragover事件(例如)。

我相信我必須在我的主窗口上的dragExitted上觸發某種事件。是否有任何方法可以實現這一點?

+0

也許,如果拖出的應用程序邊界消耗事件? – Sedrick

+0

即使我使用該事件,我只消耗dragExitted事件....它不會取消拖動操作。當它回來時,它仍會觸發「dragEntered」,「dragOver」和「dragDropped」 – Robert

+1

只是一個猜測:清除鼠標退出時的拖動板? –

回答

1

這是你可以玩的東西。我認爲它符合你的需求。

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.*; 
import javafx.scene.input.*; 
import javafx.scene.layout.*; 
import javafx.scene.paint.*; 
import javafx.scene.text.*; 
import javafx.stage.Stage; 

/** 
* 
* @author blj0011 
*/ 
public class ConsumeDragEvent extends Application 
{ 

    @Override 
    public void start(Stage primaryStage) 
    { 

     final Text source = new Text(50, 100, "DRAG ME"); 
     final Text target = new Text(300, 100, "DROP HERE"); 

     final boolean[] hasBeenOffScreen = {false}; 




     source.setOnDragDetected(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent event) { 
       /* drag was detected, start a drag-and-drop gesture*/ 
       /* allow any transfer mode */ 
       hasBeenOffScreen[0] = false; 
       Dragboard db = source.startDragAndDrop(TransferMode.ANY); 

       ((Node) event.getSource()).setCursor(Cursor.HAND); 
       /* Put a string on a dragboard */ 
       ClipboardContent content = new ClipboardContent(); 
       content.putString(source.getText()); 
       db.setContent(content); 

       event.consume(); 
      } 
     });   


     source.setOnDragDone(new EventHandler<DragEvent>() { 
      @Override 
      public void handle(DragEvent event) { 
       /* the drag and drop gesture ended */ 
       /* if the data was successfully moved, clear it */ 
       if (event.getTransferMode() == TransferMode.MOVE) { 
        source.setText(""); 
       } 
       event.consume(); 
      } 
     }); 


     target.setOnDragOver(new EventHandler<DragEvent>() { 
      @Override 
      public void handle(DragEvent event) { 
       /* data is dragged over the target */ 
       /* accept it only if it is not dragged from the same node 
       * and if it has a string data */ 
       if (event.getGestureSource() != target && 
         event.getDragboard().hasString()) { 
        /* allow for moving */ 
        event.acceptTransferModes(TransferMode.MOVE); 
       } 

       event.consume(); 
      } 
     }); 

     target.setOnDragEntered(new EventHandler<DragEvent>() { 
      @Override 
      public void handle(DragEvent event) { 
      /* the drag-and-drop gesture entered the target */ 
      /* show to the user that it is an actual gesture target */ 
       if (event.getGestureSource() != target && 
         event.getDragboard().hasString()) { 
        target.setFill(Color.GREEN); 
       } 

       event.consume(); 
      } 
     }); 

     target.setOnDragExited(new EventHandler<DragEvent>() { 
      @Override 
      public void handle(DragEvent event) { 
       /* mouse moved away, remove the graphical cues */ 
       target.setFill(Color.BLACK); 

       event.consume(); 
      } 
     }); 

     target.setOnDragDropped(new EventHandler<DragEvent>() { 
      @Override 
      public void handle(DragEvent event) { 
       /* data dropped */ 
       /* if there is a string data on dragboard, read it and use it */ 
       System.out.println(hasBeenOffScreen[0]); 
       if(hasBeenOffScreen[0] == true) 
       { 
        event.setDropCompleted(false); 

       } 
       else 
       { 
        Dragboard db = event.getDragboard(); 
        boolean success = false; 
        if (db.hasString()) { 
         target.setText(db.getString()); 
         success = true; 
        } 
        /* let the source know whether the string was successfully 
        * transferred and used */ 
        event.setDropCompleted(success); 
       } 


       event.consume(); 
      } 
     }); 


     Pane root = new Pane(); 
     root.getChildren().addAll(source, target); 

     Scene scene = new Scene(root, 500, 500); 
//  scene.setOnDragOver(event -> { 
//    
//    scene.setCursor(Cursor.DEFAULT); 
//    System.out.println(event.getX()); 
//    System.out.println(scene.getX()); 
//    System.out.println(scene.getWidth()); 
//     
//    if(event.getX() >= scene.getWidth()) 
//    { 
//     System.out.println("Out of scene!"); 
//     // Dragboard db = source.startDragAndDrop(TransferMode.ANY); 
//      hasBeenOffScreen[0] = true; 
//     event.consume(); 
//    } 
//   });  

     scene.setOnDragExited(event ->{ 
      hasBeenOffScreen[0] = true; 
      System.out.println("Off scene!"); 

     }); 
     primaryStage.setTitle("Hello World!"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    class Delta{double x, y;} 
    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) 
    { 
     launch(args); 
    } 

} 
+1

謝謝你的回答。正如我所看到的,你只是模擬用戶他沒有拖動任何東西,只是一個視覺上的東西,對吧?我會檢查是否沒有其他方法可以實際取消拖動操作,如果沒有,我會接受您的答案,因爲它可能是唯一的解決方案。 – Robert