javaでファイルのドロップを受け付ける部品を作ってみた
参考にしたのは以下のサイト
- http://terai.xrea.jp/Swing/FileListFlavor.html
- 「Java SE 6完全攻略」第29回 Swingでのドラッグ&ドロップ その1 | 日経 xTECH(クロステック)
- SwingコンポーネントへWindows ExplorerからファイルをDrag & Drop - torutkのブログ
改良ポイントは、この部品をほぼ無改造で使い回せること
使い方
ドロップ時の処理順序
- ファイルがドロップされると、FileDropHandlerのdataImport()が呼び出される。
- FileDropHandlerからイベント"fileList"が発火し、ドロップされたファイルのリストがドロップイベントを処理するクラスへ通知される。
- ドロップイベントを処理するクラスは、通知されたイベントから、ドロップされたファイルのリストを取り出し処理する。
ソースコード
package filedrophandler; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.TransferHandler; /** * 非同期にファイルのドロップを処理する。 * @author cnaos */ public class FileDropHandler extends TransferHandler { public final String FILELIST_P = "fileList"; private Exception occurredException; private final PropertyChangeSupport changes; private List<File> fileList; public FileDropHandler() { this.changes = new PropertyChangeSupport(this); this.fileList = new ArrayList(); this.occurredException = null; } /** * ドロップ可能かどうかを返す * @param support * @return */ @Override public boolean canImport(final TransferSupport support) { if (!support.isDrop()) { return false; } return support.isDataFlavorSupported(DataFlavor.javaFileListFlavor); } /** * ドロップ処理を行う * @param support * @return */ @Override public boolean importData(final TransferSupport support) { // 念のためチェック if (!canImport(support)) { return false; } this.occurredException = null; Transferable transferable = support.getTransferable(); List<File> importFileList; // ドロップ処理 try { Object data = transferable.getTransferData(DataFlavor.javaFileListFlavor); importFileList = (List<File>) data; } catch (UnsupportedFlavorException e) { this.occurredException = e; e.printStackTrace(); return false; } catch (IOException e) { this.occurredException = e; e.printStackTrace(); return false; } // イベント受信側で変更されないように防御 List<File> tmpFileList = new ArrayList(importFileList); this.fileList = Collections.unmodifiableList(tmpFileList); // 変更の有無にかかわらず発火させるため、old側をnullにしている changes.firePropertyChange(FILELIST_P, null, this.fileList); return true; } /** * ドロップされたファイルのリストを返す * @return */ public List<File> getFileList() { return fileList; } public boolean isExceptionOccurred() { return this.occurredException != null; } public Exception getOccurredException() { return this.occurredException; } public void addPropertyChangeListener(PropertyChangeListener listener) { changes.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { changes.removePropertyChangeListener(listener); } }