PDFファイルの結合・分割のツールをJavaで作成する際、SwingのJListにOSネイティブのツール(Windwosの場合はExplorer)からファイルをDrag & DropするGUIを設けようとしました。
しかし、JListやJTableはデフォルトではDropに対応していないことが判明しました。
http://java.sun.com/docs/books/tutorial/uiswing/dnd/intro.html#defaultSupport
そこで、SwingでのDrag & Dropの処理について手持ちの書籍、インターネットを探しまわってみましたが、分かりやすい説明が意外となく、ちょっと難航しました。以下その際のメモです。
インターネット捜索の旅
まず、上記URLのThe Java TutorialでSwingのDrag & DropとData Transferの仕組みを把握しました。この記事を元にしたと思われるIT Proの連載記事も多少参考になりました。
「Java SE 6完全攻略」第29回 Swingでのドラッグ&ドロップ その1 | 日経 xTECH(クロステック)
ただ、この記事の内容はサンプルコードも含めちょっと難しく、これだけでは理解が不十分でした。そこで、ちょうどJListへファイルのDropを扱った以下のブログにあるFileDropHandlerのサンプルコードと解説を読み、ようやく自分でコードを書けるようになりました。
http://weblogs.java.net/blog/shan_man/archive/2006/09/toplevel_drop_w.html
JListでファイルのドロップを扱う方法
まず、JListにドロップを扱うためのTransferHandlerサブクラスをセットします。
DefaultListModel fileListModel = new DefaultListModel(); JList fileList = new JList(fileListModel); fileList.setTransferHandler(new FileDropHandler(fileListModel));
TransferHandlerサブクラスは、今回の場合ファイルを扱います。Dropだけ扱えればよいので、canImportメソッドとimportDataメソッドをオーバーライドします。
public class FileDropHandler extends TransferHandler { public FileDropHandler(DefaultListModel aModel) { model = aModel; } public boolean canImport(TransferSupport support) { if (!support.isDrop()) { return false; } return support.isDataFlavorSupported(DataFlavor.javaFileListFlavor); } public boolean importData(TransferSupport support) { if (!canImport(support)) { return false; } Transferable transferable = support.getTransferable(); try { Object data = transferable.getTransferData(DataFlavor.javaFileListFlavor); List fileList = (List)data; for (Object file : fileList) { model.addElement(file); } } catch (UnsupportedFlavorException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } return true; } private DefaultListModel model; }