clojureでswingでドラッグ&ドロップ。するだけ。
(import
(java.awt FlowLayout)
(java.awt.event ActionListener WindowListener WindowAdapter)
(java.awt.dnd DropTarget DropTargetAdapter DnDConstants)
(java.awt.datatransfer DataFlavor)
(javax.swing JFrame JTextArea JDialog JPanel JScrollPane JButton JLabel BoxLayout))
(use 'clojure.string)
(defn dnd-listener [f]
(proxy [DropTargetAdapter] []
(drop [e]
(apply f [e]))))
(defn drop-target [f]
(let [dt (DropTarget.)]
(doto dt
(.addDropTargetListener (dnd-listener f)))))
(defn dnd-panel [f]
(let [panel (JPanel.)]
(doto panel
(.add (JLabel. "please drop."))
(.setDropTarget (drop-target f)))))
(defn dnd-frame [f]
(let [frame (JFrame.)]
(doto frame
(.add (dnd-panel f))
(.addWindowListener
(proxy [WindowAdapter] []
(windowClosing [e]
(System/exit 0))))
(.setSize 640 480)
(.setVisible true))))
(defn dnd-data-from-event [event]
(let [transfer (.getTransferable event)]
(.getTransferData transfer DataFlavor/javaFileListFlavor)))
(defn dnd-data-process [f]
(fn [event]
(.acceptDrop event DnDConstants/ACTION_REFERENCE)
(apply f [(dnd-data-from-event event)])))
(defn list-panel [strs]
(let [panel (JPanel.)]
(.add panel (JTextArea. (join "\n" strs)))
(.setSize panel 460 200)
panel))
(defn vbox-layout [coll]
(let [panel (JPanel.)]
(.setLayout panel (BoxLayout. panel BoxLayout/PAGE_AXIS))
(doseq [c coll] (.add panel c))
panel))
(defn invoker-dialog [func files]
(let [dialog (JDialog.), button (JButton. "Execute")]
(.setLayout dialog (FlowLayout.))
(doto button
(.addActionListener
(proxy [ActionListener] []
(actionPerformed [e]
(doseq [f files]
(apply func [f]))))))
(doto (.getContentPane dialog)
(.add
(vbox-layout
[(list-panel
(map (fn [file] (.getAbsolutePath file)) files))
button])))
(doto dialog
(.setSize 480 320)
(.setVisible true))))
(defn drop-start [func]
(dnd-frame
(dnd-data-process
(fn [files] (invoker-dialog func files)))))
(drop-start println)