2017-03-06 70 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