Drag & Drop from Linux (KDE, Gnome) File Managers (Konqueror, Nautilus) to Java Applications

I tried a few months ago to get drag & drop working from Konqueror to a Java application but it didn't work. Two programmers (myself and another) each had a crack at it and couldn't get it to work. I found one link through Google that seemed to be promising (see reply 23 or 23) but that didn't work. Then finally today by using slightly different keywords in my Google searching, I managed to find this link, which led me to this bug report. It turns out the "workaround" works great and I got it working. Works with Konqueror as well as Nautilus. Haven't tried any other Qt/KDE or GTK applications. Should work with Windows as well of course. I am attaching a trimmed down version of the workaround version with only the essentials to get this working. It it a lot nicer looking than the forum.sun.com link above. I had such a tough time finding the solution to this online, I hope others find this blog post and thus have an easier time at it than I did.

AttachmentSize
Plain text icon TestDragDropLinux.java_.txt3.46 KB

Comments

Thank you very much for sharing this, I've implemented a cross platform file TransferHandler with your help. I give you the code just for information:

public class FileAndTextTransferHandler extends TransferHandler {
    private static final long serialVersionUID = 1L;
 
    private static final String URI_LIST_MIME_TYPE = "text/uri-list;class=java.lang.String";
 
  private DataFlavor fileFlavor, stringFlavor;
  private DataFlavor uriListFlavor;
 
  private Utilisateur user = null;
 
  public FileAndTextTransferHandler() {
 
    fileFlavor = DataFlavor.javaFileListFlavor;
    stringFlavor = DataFlavor.stringFlavor;
 
    try {
      uriListFlavor = new DataFlavor(URI_LIST_MIME_TYPE);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }
 
  public FileAndTextTransferHandler(Utilisateur u) {
 
    fileFlavor = DataFlavor.javaFileListFlavor;
    stringFlavor = DataFlavor.stringFlavor;
 
    try {
      uriListFlavor = new DataFlavor(URI_LIST_MIME_TYPE);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
 
    this.user = u;
  }
 
  @Override
  public boolean importData(JComponent c, Transferable t) {
 
    if (!canImport(c, t.getTransferDataFlavors())) {
      return false;
    }
 
    try {
      // Windows
      if (hasFileFlavor(t.getTransferDataFlavors())) {
 
        final java.util.List files = (java.util.List) t
            .getTransferData(fileFlavor);
 
        process(files);       
 
        return true;
 
      // Linux
      }else if(hasURIListFlavor(t.getTransferDataFlavors())){
 
          final List<File> files = textURIListToFileList((String) t.getTransferData(uriListFlavor));
 
        if(files.size()>0){
 
            process(files);
        }
 
      }else if (hasStringFlavor(t.getTransferDataFlavors())) {
 
        String str = ((String) t.getTransferData(stringFlavor));
 
        System.out.println(str);
 
        return true;
      }
    } catch (UnsupportedFlavorException ufe) {
      System.out.println("importData: unsupported data flavor");
    } catch (IOException ieo) {
      System.out.println("importData: I/O exception");
    }
    return false;
  }
 
  @Override
  public int getSourceActions(JComponent c) {
    return COPY;
  }
 
  @Override
  public boolean canImport(JComponent c, DataFlavor[] flavors) {
    if (hasFileFlavor(flavors)) {
      return true;
    }
    if (hasStringFlavor(flavors)) {
      return true;
    }
    return false;
  }
 
  private boolean hasFileFlavor(DataFlavor[] flavors) {
    for (int i = 0; i < flavors.length; i++) {
      if (fileFlavor.equals(flavors[i])) {
        return true;
      }
    }
    return false;
  }
 
  private boolean hasStringFlavor(DataFlavor[] flavors) {
    for (int i = 0; i < flavors.length; i++) {
      if (stringFlavor.equals(flavors[i])) {
        return true;
      }
    }
    return false;
  }
 
  private boolean hasURIListFlavor(DataFlavor[] flavors) {
    for (int i = 0; i < flavors.length; i++) {
      if (uriListFlavor.equals(flavors[i])) {
        return true;
      }
    }
    return false;
  }
 
  /** Your helpfull function */
  private static List<File> textURIListToFileList(String data) {
    List<File> list = new ArrayList<File>(1);
    for (StringTokenizer st = new StringTokenizer(data, "\r\n"); st.hasMoreTokens();) {
      String s = st.nextToken();
      if (s.startsWith("#")) {
        // the line is a comment (as per the RFC 2483)
        continue;
      }
      try {
        URI uri = new URI(s);
        File file = new File(uri);
        list.add(file);
      } catch (URISyntaxException e) {
        e.printStackTrace();
      } catch (IllegalArgumentException e) {
        e.printStackTrace();
      }
    }
    return list;
  }
 
}

Merci beaucoup

Add new comment