• 追加された行はこの色です。
  • 削除された行はこの色です。
---
category: swing
folder: TableCellTransferHandler
title: JTableのセルを選択してJListにドラッグ&ドロップでIconをコピーする
tags: [JTable, JList, DragAndDrop, TransferHandler, Icon]
author: aterai
pubdate: 2015-05-25T00:03:51+09:00
description: JTableのセルを選択可能にし、ドラッグ&ドロップでそのセル内のIconをJListにコピーできるようにTransferHandlerを設定します。
image: https://lh3.googleusercontent.com/-TUrxk7yYqYM/VWHkR1mENvI/AAAAAAAAN4w/bEU29WIgjOE/s800/TableCellTransferHandler.png
---
* 概要 [#summary]
`JTable`のセルを選択可能にし、ドラッグ&ドロップでそのセル内の`Icon`を`JList`にコピーできるように`TransferHandler`を設定します。

#download(https://lh3.googleusercontent.com/-TUrxk7yYqYM/VWHkR1mENvI/AAAAAAAAN4w/bEU29WIgjOE/s800/TableCellTransferHandler.png)

* サンプルコード [#sourcecode]
#code(link){{
//DataFlavor FLAVOR = new ActivationDataFlavor(JTable.class, DataFlavor.javaJVMLocalObjectMimeType, "JTable");
class CellIconTransferHandler extends TransferHandler {
  private final DataFlavor localObjectFlavor;
  public CellIconTransferHandler(DataFlavor flavor) {
    super();
    localObjectFlavor = flavor;
  }
  public static final DataFlavor ICON_FLAVOR = new DataFlavor(Icon.class, "Icon");

  @Override protected Transferable createTransferable(JComponent c) {
    JTable table = (JTable) c;
    if (table.getSelectedColumn() != 1) {
      return null;
    if (c instanceof JTable) {
      JTable table = (JTable) c;
      int row = table.getSelectedRow();
      int col = table.getSelectedColumn();
      if (Icon.class.isAssignableFrom(table.getColumnClass(col))) {
        // return new DataHandler(table, ICON_FLAVOR.getMimeType());
        return new Transferable() {
          @Override public DataFlavor[] getTransferDataFlavors() {
            return new DataFlavor[] {ICON_FLAVOR};
          }

          @Override public boolean isDataFlavorSupported(DataFlavor flavor) {
            return Objects.equals(ICON_FLAVOR, flavor);
          }

          @Override public Object getTransferData(DataFlavor flavor)
                throws UnsupportedFlavorException {
            if (isDataFlavorSupported(flavor)) {
              return table.getValueAt(row, col);
            } else {
              throw new UnsupportedFlavorException(flavor);
            }
          }
        };
      }
    }
    return new DataHandler(table, localObjectFlavor.getMimeType());
    return null;
  }
  @Override public boolean canImport(TransferSupport info) {
    return false;
  }
  @Override public int getSourceActions(JComponent c) {
    return TransferHandler.COPY;
  }
}

class TableCellTransferHandler extends TransferHandler {
  private final DataFlavor localObjectFlavor;
  public TableCellTransferHandler(DataFlavor flavor) {
    super();
    localObjectFlavor = flavor;
  }
  @Override public boolean canImport(TransferSupport info) {
  @Override public boolean canImport(TransferHandler.TransferSupport info) {
    Component c = info.getComponent();
    if (c instanceof JList) {
      return info.isDrop() && info.isDataFlavorSupported(localObjectFlavor);
      return info.isDrop() && info.isDataFlavorSupported(ICON_FLAVOR);
    }
    return false;
  }

  @Override public int getSourceActions(JComponent c) {
    return TransferHandler.COPY;
  }

  @SuppressWarnings("unchecked")
  @Override public boolean importData(TransferSupport info) {
    if (!canImport(info)) {
      return false;
    }
    JList l = (JList) info.getComponent();
  @Override public boolean importData(TransferHandler.TransferSupport info) {
    JList<?> l = (JList<?>) info.getComponent();
    try {
      Object o = info.getTransferable().getTransferData(localObjectFlavor);
      if (o instanceof JTable) {
        JTable t = (JTable) o;
        Object obj = t.getValueAt(t.getSelectedRow(), t.getSelectedColumn());
        ((DefaultListModel) l.getModel()).addElement(obj);
      Object o = info.getTransferable().getTransferData(ICON_FLAVOR);
      if (o instanceof Icon) {
        ((DefaultListModel<Object>) l.getModel()).addElement(o);
      }
      return true;
    } catch (UnsupportedFlavorException | IOException ex) {
      ex.printStackTrace();
      return false;
    }
    return false;
  }
}
}}

* 解説 [#explanation]
上記のサンプルでは、ドラッグ元の`JTable`に`CellIconTransferHandler`を設定して特定の列のアイコンのみドラッグ可能にし、ドロップ先の`JList`には`TableCellTransferHandler`を設定してアイコンを受け取り(実際は`JTable`ごと受け取って選択されたアイコンを取得)、これを一行で表示しています。
上記のサンプルでは、ドラッグ元の`JTable`に`CellIconTransferHandler`を設定して特定の列のアイコンのみドラッグ可能にし、ドロップ先の`JList`はアイコンを受け取って表示しています。

- テスト
-- `clear`ボタン: `JList`にドロップされたアイコンをクリア
-- `filter`ボタン: `JList`にドロップされたアイコンを含む行のみ表示するフィルタを`JTable`に設定
- `clear`ボタン: `JList`にドロップされたアイコンをクリア
- `filter`ボタン: `JList`にドロップされたアイコンを含む行のみ表示するフィルタを`JTable`に設定

//* 参考リンク [#reference]
* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/TransferHandler.html TransferHandler (Java Platform SE 8)]

* コメント [#comment]
#comment
#comment