抱歉;我不喜欢问“为什么我得到 exception ?” StackOverflow 上的问题(现在想起来有点讽刺......),但我无法弄清楚这个异常的原因!我一直在寻找解决方案,但那些弹出的解决方案要么是 a subtly different exception ,要么是 when people were trying to access a Transferrable outside of an event handler ,要么是 not ever answered at all

我正在尝试在 DropTargetListener#drop(DropTargetListener) 方法中执行此操作。我正在通过从运行程序的同一个驱动器中拖动一个 PNG 来测试这个,这让我认为数据很容易获得。我的相关代码和由此产生的异常如下:

代码

(为简洁起见,注释中的行号缩短,如果是错误行,则后跟 =>)

        // package declaration
        // imports

/*45 */ public class BHFileChooser extends JComponent implements DropTargetListener
/*46 */ {
            // object declaration

            ...

            // initialization methods

            ...

/*186*/     @Override
/*187*/     public void dragEnter(DropTargetDragEvent dtde)
/*188*/     {
/*189*/         setState(State.EVALUATING);
/*190*/         setState(canAccept(dtde.getTransferable()) ? State.EVALUATED_ACCEPTABLE : State.EVALUATED_UNACCEPTABLE);
/*191*/         validate();
/*192*/     }
/*193*/
/*194*/     @Override
/*195*/     public void dragExit(DropTargetEvent dte)
/*196*/     {
/*197*/         setState(State.WAITING);
/*198*/         validate();
/*199*/     }
/*200*/
/*201*/     @Override public void dragOver(DropTargetDragEvent dtde){} // unused for now
/*202*/
/*203*/     @Override
/*204*/     public void dropActionChanged(DropTargetDragEvent dtde)
/*205*/     {
/*206*/         userAction = dtde.getDropAction();
/*207*/         validate();
/*208*/     }
/*209*/
/*210*/     @Override
/*211*/     public void drop(DropTargetDropEvent dtde)
/*212*/     {
/*213*/         setState(State.WAITING); // I use a finite-state machine to keep track of what's happening
/*214*/         setState(State.EVALUATING);
/*215*/         Transferable t = dtde.getTransferable();
/*216*/         try
/*217*/         {
/*218 =>*/          if (canAccept(t))
/*219*/                 try
/*220*/                 {
/*221*/                     setState(State.EVALUATED_ACCEPTABLE);
/*222*/                     File f = (File)t.getTransferData(DataFlavor.javaFileListFlavor);
/*223*/                     acceptFile(f);
/*224*/                 }
/*225*/                 catch (UnsupportedFlavorException ex)
/*226*/                 {
/*227*/                     setState(State.EVALUATED_UNACCEPTABLE);
/*228*/                 }
/*229*/                 catch (IOException ex)
/*230*/                 {
/*231*/                     Logger.getGlobal().log(Level.SEVERE, MESSAGE_IO_EXCEPTION, ex);
/*232*/                 }
/*233*/             else
/*234*/                 setState(State.EVALUATED_UNACCEPTABLE);
/*235*/         }
/*236*/         catch (Throwable th)
/*237*/         {
/*238*/             th.printStackTrace();
/*239*/             setState(State.EVALUATED_UNACCEPTABLE); // evaluation could not be completed, so we can't accept it
/*240*/             setState(State.WAITING);                // go back to waiting for another file
/*241*/         }
/*242*/
/*243*/         validate();
/*244*/     }

            // more methods

            ...

/*267*/     public void acceptFile(File f)
/*268*/     {
/*269*/         if (fileFilter == null || fileFilter.accept(f))
/*270*/         {
/*271*/             setState(State.EVALUATED_ACCEPTABLE);
/*272*/             setState(State.LOADING);
/*273*/             file = f;
/*274*/             setState(State.LOADED);
/*275*/         }
/*276*/         else
/*277*/             setState(State.EVALUATED_UNACCEPTABLE);
/*278*/     }

            // more methods

            ...

/*311*/     private boolean canAccept(Transferable t)
/*312*/     {
/*313*/         try
/*314*/         {
/*315*/             System.out.println(Arrays.deepToString(t.getTransferDataFlavors()));
/*316*/
/*317*/             if (!t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
/*318*/                 return false;
/*319*/
/*320 =>*/          List<File> data = (List)t.getTransferData(DataFlavor.javaFileListFlavor); // the error occurs in here
/*321*/             if (fileFilter == null)
/*322*/                 return true;
/*323*/             return
/*324*/                 data.stream() // treat the list as a stream
/*325*/                 .noneMatch(   // return true if none match the following rule:
/*326*/                     (f) -> (                  // for each file
/*327*/                         !fileFilter.accept(f) // if the filter doesn't accept it
/*328*/                     )
/*329*/                 )
/*330*/             ;
/*331*/         }
/*332*/         catch (UnsupportedFlavorException ex){}
/*333*/         catch (IOException ex)
/*334*/         {
/*335*/             Logger.getLogger(BHFileChooser.class.getName()).log(Level.SEVERE, MESSAGE_IO_EXCEPTION, ex);
/*336*/         }
/*337*/         return false;
/*338*/     }

            ...

            // more methods

            ...

            // internal classes & enums like State
/*468*/ }

异常(exception)

java.awt.dnd.InvalidDnDOperationException: No drop current
    at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:245)
    at sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:73)
    at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:376)
    at org.bh.tools.comps.BHFileChooser.canAccept(BHFileChooser.java:320)
    at org.bh.tools.comps.BHFileChooser.drop(BHFileChooser.java:218)
    at java.awt.dnd.DropTarget.drop(DropTarget.java:455)
    at sun.awt.dnd.SunDropTargetContextPeer.processDropMessage(SunDropTargetContextPeer.java:538)
    at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchDropEvent(SunDropTargetContextPeer.java:852)
    at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:776)
    at sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:48)
    at java.awt.Component.dispatchEventImpl(Component.java:4738)
    at java.awt.Container.dispatchEventImpl(Container.java:2292)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
    at java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:4611)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4457)
    at java.awt.Container.dispatchEventImpl(Container.java:2278)
    at java.awt.Window.dispatchEventImpl(Window.java:2739)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:719)
    at java.awt.EventQueue$4.run(EventQueue.java:717)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

另外, No drop current 是什么意思?我在任何地方都没有看到这一点。

最佳答案

我认为你应该调用:

dtde.acceptDrop(DragNDropConstants.ACTION_COPY_OR_MOVE);

Java 7 及更新版本:
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);


dtde.getTransferable();

'自己定义的 getTransferable 没有问题,如果你不这样做,Java 的 Transferable 用于原生拖放操作需要这个调用。

ref 1 , ref 2

关于java - 为什么我会收到 InvalidDnDOOperationException?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25879171/

10-14 22:18