2012-01-17 96 views
7

我有一个应用程序,我想通过将外部文件从Windows资源管理器拖到应用程序中来导入外部文件。我有这个基本的功能工作。但是,我想将默认的拖放光标图标更改为应用程序相应的游标。当按下鼠标键并将其保持在应用程序上时,我无法更改用户可见的光标。如果拖放操作在同一个swing应用程序中,我已经看过这个例子。我试图用DragGestureListener和DragSource来完成这个任务。似乎除非拖动源在摆动范围内,否则不会调用这些方法。将外部文件拖入swing应用程序时,是否可以更改拖动光标?将外部文件拖入Swing应用程序时设置自定义光标

请参阅该简化的例子:

public class DnDTemplate extends JFrame { 

private static final long serialVersionUID = 1L; 
private JComponent thePane = null; 
private Cursor dropCursor = null; 

public DnDTemplate() { 
    super("Drop File Here"); 

    thePane = (JComponent) getContentPane(); 
    thePane.setTransferHandler(new DndTransferHandler()); 

    ImageIcon imageIcon = new ImageIcon("drop_here.gif"); 
    Image image = imageIcon.getImage();  
    BufferedImage bufferedImage = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB); 
    Graphics graphics = bufferedImage.getGraphics(); 
    graphics.drawImage(image, 0, 0, null); 
    dropCursor = Toolkit.getDefaultToolkit().createCustomCursor(bufferedImage, new Point(16, 16), "drop cursor"); 

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setSize(300, 300); 
} 

public static void main(String[] args) { 
    new DnDTemplate().setVisible(true); 
} 

class DndTransferHandler extends TransferHandler { 

    private static final long serialVersionUID = 1L; 

    @Override 
    public boolean canImport(TransferHandler.TransferSupport info) { 
     // This gets called repeatedly while dragged file is over frame 
     if (!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { 
      return false; 
     } 
     // Even though this method is called at the appropriate time, 
     // setting the cursor here is of no consequence 
     info.getComponent().setCursor(dropCursor); 

     return true; 
    } 

    @Override 
    public boolean importData(TransferHandler.TransferSupport info) { 
     // this gets called when file is dropped 
     if (!info.isDrop()) { 
      return false; 
     } 

     Transferable transferable = info.getTransferable(); 
     String importFileName = null; 
     try { 
      List<File> fileList = (List<File>) transferable.getTransferData(DataFlavor.javaFileListFlavor); 
      Iterator<File> iterator = fileList.iterator(); 
      while (iterator.hasNext()) { 
       File f = iterator.next(); 
       importFileName = f.getAbsolutePath(); 
      } 
      info.getComponent().setCursor(dropCursor); 
      thePane.setCursor(dropCursor); 

     } catch (Exception e) { 
      return false; 
     } 

     System.out.println("Importing " + importFileName); 
     // Return the cursor back to the default 
     thePane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 
     return true; 
    } 

} 

}

+6

不,这没有回答这个问题。我确实看到过,并试图使用setDropTarget。 dragEnter方法在适当的时候被调用,但是光标保持默认的拖放图标,并且不会改变为我指定的那个。 – agility 2012-01-18 02:53:01

+0

我试图在dragOver中设置光标,并且遇到http://bugs.sun.com/view_bug.do?bug_id=4451328中提到的闪烁。可能它毕竟不是固定的。 – tenorsax 2012-01-18 04:02:32

回答

1

免责声明:这应该是一个评论,而不是一个答案,但它仅仅是太长的意见。我会删除这个答案,如果它是完全不正确的

我没有测试这个,但看看TransferHandler的API我建议看看TransferHandler#getDragImage方法。

当从设置了TransferHandler的组件启动拖动时,是否使用此图像时使用该图像还是有点不清楚,或者在从应用程序外部启动拖动并且光标经过已为其设置TransferHandler的组件。我发现an example这似乎表明这在Java应用程序一定的工作,但目前还没有定论约从外部应用程序

Bug ID 4816922建议使用TransferHandler#getVisualRepresentation来拖和下降,但目前还不清楚是否错误已修复。

+2

虽然我应该在我的问题中指定,但我正在寻找Java 6中的解决方案。这仅在Java 7中实现。此外,在使用TransferHandler.setDragImage测试此解决方案时,调用似乎被忽略,并且出现拖动图标在调用setDragImage的情况下也是如此。 – agility 2012-01-17 20:15:44

相关问题