Java在JFrame上拖放特定扩展名的文件

我想为我的应用程序实现DnD只接受某些扩展名的文件(例如wrl)。 如果文件将被接受,我想将光标更改为拖动光标,并在拖放错误扩展名的文件时恢复到正常光标。

我一直在http://docs.oracle.com/javase/tutorial/uiswing/dnd/toplevel.html上关注以下教程/示例

我所做的更改是在canImport函数中

public boolean canImport(TransferHandler.TransferSupport support) { if (!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { return false; } Transferable t = support.getTransferable(); try { java.util.List l = (java.util.List)t.getTransferData(DataFlavor.javaFileListFlavor); if (l.size() != 1) { return false; } File f = l.get(0); String extension = f.getName().substring(f.getName().lastIndexOf(".")); return extension.equalsIgnoreCase(".wrl"); } catch (UnsupportedFlavorException e) { return false; } catch (IOException e) { return false; } } 

当我在不同的文件中拖动时,这种行为正确。 但是,当我删除文件时,我得到以下exception

 Exception in thread "AWT-EventQueue-0" java.awt.dnd.InvalidDnDOperationException: No drop current at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:227) at sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:56) at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:359) at appl.TopLevelTransferHandlerDemo$1.canImport(TopLevelTransferHandlerDemo.java:207) at javax.swing.TransferHandler$DropHandler.drop(TransferHandler.java:1454) at java.awt.dnd.DropTarget.drop(DropTarget.java:434) at javax.swing.TransferHandler$SwingDropTarget.drop(TransferHandler.java:1193) at sun.awt.dnd.SunDropTargetContextPeer.processDropMessage(SunDropTargetContextPeer.java:519) at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchDropEvent(SunDropTargetContextPeer.java:832) at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:756) at sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:30) at java.awt.Component.dispatchEventImpl(Component.java:4487) at java.awt.Container.dispatchEventImpl(Container.java:2099) at java.awt.Component.dispatchEvent(Component.java:4460) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577) at java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:4312) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4163) at java.awt.Container.dispatchEventImpl(Container.java:2085) at java.awt.Window.dispatchEventImpl(Window.java:2478) at java.awt.Component.dispatchEvent(Component.java:4460) at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 

任何帮助非常感谢

我最后一次检查,这在Mac上没有用,但是Java 7可能会改变…

在此处输入图像描述在此处输入图像描述在此处输入图像描述

现在,请记住,当涉及到拖拽时,没有简单的答案会做任何事情。

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.List; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class TestDragNDrop { public static void main(String[] args) { new TestDragNDrop(); } public TestDragNDrop() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public static class TestPane extends JPanel implements DropTargetListener { public enum DragState { Waiting, Accept, Reject } private DragState state = DragState.Waiting; private BufferedImage happy; private BufferedImage wait; private BufferedImage sad; public TestPane() { DropTarget dt = new DropTarget( this, DnDConstants.ACTION_COPY_OR_MOVE, this, true); setBackground(Color.BLACK); try { happy = ImageIO.read(getClass().getResource("/Happy.png")); wait = ImageIO.read(getClass().getResource("/Wait.png")); sad = ImageIO.read(getClass().getResource("/Sad.png")); } catch (Exception e) { e.printStackTrace(); } } @Override public Dimension getPreferredSize() { return new Dimension(300, 300); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); BufferedImage bg = null; switch (state) { case Waiting: bg = wait; break; case Accept: bg = happy; break; case Reject: bg = sad; break; } if (bg != null) { int x = (getWidth() - bg.getWidth()) / 2; int y = (getHeight() - bg.getHeight()) / 2; g.drawImage(bg, x, y, this); } } @Override public void dragEnter(DropTargetDragEvent dtde) { state = DragState.Reject; Transferable t = dtde.getTransferable(); if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { try { Object td = t.getTransferData(DataFlavor.javaFileListFlavor); if (td instanceof List) { state = DragState.Accept; for (Object value : ((List) td)) { if (value instanceof File) { File file = (File) value; String name = file.getName().toLowerCase(); if (!name.endsWith(".png")) { state = DragState.Reject; break; } } } } } catch (UnsupportedFlavorException | IOException ex) { ex.printStackTrace(); } } if (state == DragState.Accept) { dtde.acceptDrag(DnDConstants.ACTION_COPY); } else { dtde.rejectDrag(); } repaint(); } @Override public void dragOver(DropTargetDragEvent dtde) { } @Override public void dropActionChanged(DropTargetDragEvent dtde) { } @Override public void dragExit(DropTargetEvent dte) { state = DragState.Waiting; repaint(); } @Override public void drop(DropTargetDropEvent dtde) { state = DragState.Waiting; repaint(); } } }