Reputation: 32093
I'm sorry; I don't like asking "why am I getting exception
?" questions on StackOverflow (bit ironic now that I think of it...), but I can't figure out the cause of this exception! I've searched for a solution, but those that popped up were either for a subtly different exception, when people were trying to access a Transferrable
outside of an event handler, or not ever answered at all.
I'm trying to do this right inside the DropTargetListener#drop(DropTargetListener)
method. I'm testing this by dragging a PNG from the same drive that the program is running on, which makes me think that the data is readily available. My relevant code and the resulting exception are below:
(shortened for brevity, line numbers in comments, followed by =>
if it's an error line)
// 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*/ }
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)
Also, what does it mean by No drop current
? I don't see this documented anywhere.
Upvotes: 4
Views: 2136
Reputation: 3720
I think you should call:
dtde.acceptDrop(DragNDropConstants.ACTION_COPY_OR_MOVE);
Java 7 and newer:
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
before
dtde.getTransferable();
'Self defined getTransferable have no problem if you don't, Java's Transferable for native drag'n'drop operation needs this call.'
Upvotes: 15
Reputation: 105
I just encountered this problem aswell, but for a different reason than the one specified above. My fault lied in calling super.drop when overriding the drop method.
So this did not work
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
super.drop(dtde);
try{
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
List<File> fileList = (List<File>) dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
for(File f : fileList){
filesAssocTField.setText(f.getAbsolutePath());
}
} catch (Exception ex){
System.out.println("caught exception in filesAssocTField drop target");
ex.printStackTrace();
}
}
While this did
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
try{
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
List<File> fileList = (List<File>) dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
for(File f : fileList){
filesAssocTField.setText(f.getAbsolutePath());
}
} catch (Exception ex){
System.out.println("caught exception in filesAssocTField drop target");
ex.printStackTrace();
}
}
Upvotes: 1