2012-01-17 68 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

相關問題