Swing/DropFileOnFileChooser のバックアップ(No.2)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/DropFileOnFileChooser へ行く。
- 1 (2019-10-21 (月) 16:32:19)
- 2 (2021-05-19 (水) 05:40:28)
- 3 (2022-11-25 (金) 11:49:53)
- category: swing folder: DropFileOnFileChooser title: JFileChooserにTransferHandlerを設定してFileをドロップ可能にする tags: [JFileChooser, TransferHandler, File, DragAndDrop] author: aterai pubdate: 2019-10-21T16:31:38+09:00 description: JFileChooserにTransferHandlerを設定してFileやDirectoryをドロップ可能にします。 image: https://drive.google.com/uc?id=1NA-vGQgCHGvMjG9nrxYwpTVuYCIgeFFZ
概要
JFileChooser
にTransferHandler
を設定してFile
やDirectory
をドロップ可能にします。
Screenshot
Advertisement
サンプルコード
chooser.setTransferHandler(new FileChooserTransferHandler());
// ...
class FileChooserTransferHandler extends TransferHandler {
@Override public boolean canImport(TransferSupport support) {
boolean canDrop = support.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
boolean isTarget = support.getComponent() instanceof JFileChooser;
return support.isDrop() && canDrop && isTarget; // && !isMultiSelection;
}
@Override public boolean importData(TransferSupport support) {
try {
JFileChooser fc = (JFileChooser) support.getComponent();
List<?> list = (List<?>) support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
File[] files = new File[list.size()];
for (int i = 0; i < list.size(); i++) {
files[i] = (File) list.get(i);
}
if (fc.isMultiSelectionEnabled()) {
fc.setSelectedFiles(files);
} else {
File f = files[0];
if (f.isDirectory()) {
fc.setCurrentDirectory(f);
} else {
fc.setSelectedFile(f);
}
}
return true;
} catch (IOException | UnsupportedFlavorException ex) {
return false;
}
}
}
View in GitHub: Java, Kotlin解説
Default
JFileChooser
のJTextField
に文字列がドロップ可能だが、ファイルはドロップ不可
TransferHandler
JFileChooser
内のJTable
、JList
、JTextField
以外にファイルをドロップ可能にするTransferHandler
を設定JFileChooser#setMultiSelectionEnabled(true)
の場合、選択された複数ファイル(ディレクトリを除く)のファイル名がJTextField
に表示されるJFileChooser#setMultiSelectionEnabled(false)
の場合、選択された複数ファイルの先頭ファイルがドロップの対象になる- ドロップの対象ファイルがディレクトリの場合、
JFileChooser#setCurrentDirectory(dir)
でカレントディレクトリを変更 - ドロップの対象ファイルがファイルの場合、
JFileChooser#setSelectedFile(file)
で選択ファイルを変更
- ドロップの対象ファイルがディレクトリの場合、
- 以下のように
TransferHandler#canImport(...)
をオーバーライドして複数ファイルが選択されている場合はドロップを拒否すると、InvalidDnDOperationException: No drop current
が発生する?
class FileChooserTransferHandler extends TransferHandler {
@Override public boolean canImport(TransferSupport support) {
boolean canDrop = support.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
boolean isTarget = support.getComponent() instanceof JFileChooser;
boolean isMultiSelection = true;
if (isTarget && canDrop) {
try {
JFileChooser fc = (JFileChooser) support.getComponent();
// XXX: java.awt.dnd.InvalidDnDOperationException: No drop current
List<?> list = (List<?>) support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
isMultiSelection = list.size() != 1;
} catch (IOException | UnsupportedFlavorException ex) {
ex.printStackTrace();
}
}
return support.isDrop() && canDrop && isTarget && !isMultiSelection;
}