作り方 †
サンプルプログラム †
package com.snail.example;
import java.awt.GridLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
/**
* ファイルをドロップするサンプルプログラム
*
* @author $author$
* @version $Revision$
*/
public class DnDExam extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel jContentPane = null;
private JTextPane jTextPane = null;
private JScrollPane jScrollPane = null;
/**
* @param owner
*/
public DnDExam() {
super("Drag & Drop Exam");
initialize();
}
/**
* This method initializes jTextPane
*
* @return javax.swing.JTextPane
*/
private JTextPane getJTextPane() {
if (jTextPane == null) {
jTextPane = new JTextPane();
}
return jTextPane;
}
/**
* This method initializes jScrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getJScrollPane() {
if (jScrollPane == null) {
jScrollPane = new JScrollPane();
jScrollPane.setViewportView(getJTextPane());
}
return jScrollPane;
}
/**
* @param args
*/
public static void main(String[] args) {
DnDExam exam = new DnDExam();
exam.setVisible(true);
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
this.setSize(300, 200);
this.setContentPane(getJContentPane());
new DropTarget(getJTextPane(), new MyDropTargetAdapter());
}
/**
* This method initializes jContentPane
*
* @return javax.swing.JPanel
*/
private JPanel getJContentPane() {
if (jContentPane == null) {
GridLayout gridLayout = new GridLayout();
gridLayout.setRows(1);
gridLayout.setColumns(1);
jContentPane = new JPanel();
jContentPane.setLayout(gridLayout);
jContentPane.add(getJScrollPane(), null);
}
return jContentPane;
}
/**
* Drop イベントを受け取る Adapter
* <pre>
* Adapter を使わない場合、 JTextPane などを継承し、DropTargetListener
* を実装するコンポーネントを新しく作らなければならない。
* VE(Visual Editor)などが作った部分はなるべくいじりたくないので、
* Adapter を使うのが適当だろう。
* </pre>
* @author $author$
* @version $Revision$
*/
private class MyDropTargetAdapter extends DropTargetAdapter {
public void drop(DropTargetDropEvent dtde) {
try {
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable transfer = dtde.getTransferable();
if (transfer.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
java.util.List<File> fileList =
(java.util.List<File>) transfer.getTransferData(
DataFlavor.javaFileListFlavor);
StringBuilder sb = new StringBuilder();
for (File file : fileList) {
sb.append(dumpFileNames(file));
}
getJTextPane().setText(sb.toString());
dtde.dropComplete(true);
}else{
dtde.dropComplete(true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String dumpFileNames(File file) {
if(file == null){
return "";
}
StringBuilder sb = new StringBuilder();
if (file.isDirectory()) {
for (File child : file.listFiles()) {
sb.append(dumpFileNames(child));
}
} else {
sb.append(file.getAbsolutePath());
sb.append("\n");
}
return sb.toString();
}
}
}
実行結果 †
余談(当初の目的) †
- なんで Drag and Drop のサンプルプログラムを作ったのかというと
- ファイルをアップロードするページ(JSP)で、 D&D で複数ファイルを一度に選択出来ないか調べるため
- D&D されたファイルの名前を列挙する Applet までは作れたのだが、そこからどうしても <input type="file"> に値が設定できない。
- というか、そもそも <input type="file"> にはプログラム(Javascript)から値を設定したり、初期値を設定したりでないことが判明
- もしもこういうことが出来ると、任意のファイル(たとえばレジストリなど)を勝手にアップロードする HTML を作れてしてしまう・・・
- ということで、Webアプリに適用することは断念
参考文献 †
Java#GUI