S-JIS[2007-09-11/2015-03-22] 変更履歴
コピー(カット)&ペーストで使われるクリップボードをJavaから扱える。
(WindowsのCtrl+CやCtrl+V)
|
|
Swingのコンポーネント(JTree等)でコピー&ペーストを処理したいなら、TransferHandlerを使う方が便利。[2009-03-26]
(いずれにしてもTransferableを扱うのだが、Ctrl+CやCtrl+Vのキー操作処理がデフォルトで登録されているので)
クリップボード関連のクラスはjava.awtパッケージに在る。
ToolKitからシステムのクリップボードに該当するインスタンスを取得し、それを使って操作を行う。
import java.awt.Toolkit; import java.awt.datatransfer.Clipboard;
Toolkit kit = Toolkit.getDefaultToolkit(); Clipboard clip = kit.getSystemClipboard();
クリップボードには色々な種類(文字列やら画像やら)のデータが入っている可能性があるので、文字列が欲しい場合は「文字列(stringFlavor)」を指定してデータを取り出す。
public static String getClipboardString() { Toolkit kit = Toolkit.getDefaultToolkit(); Clipboard clip = kit.getSystemClipboard(); try { return (String) clip.getData(DataFlavor.stringFlavor); } catch (UnsupportedFlavorException e) { return null; } catch (IOException e) { return null; } }
※getData()はJDK1.5以降で使用可能。JDK1.4まではreturn
(String)clip.getContents(null).getTransferData(DataFlavor.stringFlavor);
という感じ。
というか、getData()の中身はJDK1.4までの方法そのもの(とnullチェック)。
文字列をクリップボードに保存するにはStringSelectionクラスを使う。
StringSelectionはstringFlavorをサポートしているので、それを使って文字列の取得が出来る。
import java.awt.datatransfer.StringSelection;
public static void setClipboardString(String str) { Toolkit kit = Toolkit.getDefaultToolkit(); Clipboard clip = kit.getSystemClipboard(); StringSelection ss = new StringSelection(str); clip.setContents(ss, ss); }
Clipboard#setContents()の第1引数にはクリップボードのデータを保持するオブジェクト (Transferableのインスタンス)を渡す。
Clipboard#setContents()の第2引数にはClipboardOwnerインターフェースのインスタンスを指定する。必要なければnullでもよい。
これは、「クリップボードの内容が他のコピー(やカット)によって書き換えられて、自分の内容が不要になったとき」に通知される(コールバックされる)オブジェクトを指定する。つまり、その時にはこのオブジェクトのlostOwnership()が呼ばれる。
このメソッドが呼ばれたということは「これ以上データが使われない」ということなので、自分が保持していたデータを破棄する処理を行う。
StringSelectionの場合はClipboardOwnerも実装しているので そのまま渡すことが出来る。
public static Image getClipboardImage() { Toolkit kit = Toolkit.getDefaultToolkit(); Clipboard clip = kit.getSystemClipboard(); try { return (Image) clip.getData(DataFlavor.imageFlavor); } catch (UnsupportedFlavorException e) { return null; } catch (IOException e) { return null; } }
画像のSelectionクラスは無いみたいなので、StringSelectionクラスを参考に自作しちゃえ。
public static void setClipboardImage(Image img) { Toolkit kit = Toolkit.getDefaultToolkit(); Clipboard clip = kit.getSystemClipboard(); ImageSelection is = new ImageSelection(img); clip.setContents(is, is); }
public class ImageSelection implements Transferable, ClipboardOwner { protected Image data; /** コンストラクター */ public ImageSelection(Image image) { this.data = image; } /** 対応しているフレーバーを返す */ public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] { DataFlavor.imageFlavor }; } /** フレーバーが対応しているかどうか */ public boolean isDataFlavorSupported(DataFlavor flavor) { return DataFlavor.imageFlavor.equals(flavor); } /** 保持している画像を返す */ public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if (DataFlavor.imageFlavor.equals(flavor)) { return data; } throw new UnsupportedFlavorException(flavor); } /** クリップボードのデータとして不要になった時に呼ばれる */ public void lostOwnership(Clipboard clipboard, Transferable contents) { this.data = null; } }
Windowsのエクスプローラーでファイルを選択してコピーすると、クリップボードにファイル名(の一覧)が入る。[2007-09-13]
これをJavaから取り出すことが出来る。
public static List<File> getClipboardFiles() { Toolkit kit = Toolkit.getDefaultToolkit(); Clipboard clip = kit.getSystemClipboard(); try { @SuppressWarnings("unchecked") List<File> list = (List<File>) clip.getData(DataFlavor.javaFileListFlavor); // for (File f : list) { System.out.println(f); } return list; } catch (UnsupportedFlavorException e) { return null; } catch (IOException e) { return null; } }
Clipboardには値をクリアするメソッドは用意されていないので、空文字列をコピーすることで代用する。[2015-03-22]
import java.awt.Toolkit; import java.awt.datatransfer.StringSelection;
public static void clearContents() { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); StringSelection ss = new StringSelection(""); clipboard.setContents(ss, ss); }