• title: JTableのHTML形式コピーをカスタマイズする tags: [JTable, TransferHandler, Html] author: aterai pubdate: 2014-09-01T00:14:35+09:00 description: JTableのセルを選択してクリップボードにHTMLテキストをコピーするとき、そのセルのクラスに応じて生成するタグを変更します。

概要

JTableのセルを選択してクリップボードにHTMLテキストをコピーするとき、そのセルのクラスに応じて生成するタグを変更します。

サンプルコード

class HtmlTableTransferHandler extends TransferHandler {
  //@see javax/swing/plaf/basic/
  //     BasicTableUI.TableTransferHandler#createTransferable(JComponent)
  @Override protected Transferable createTransferable(JComponent c) {
    if (c instanceof JTable) {
      JTable table = (JTable) c;
      int[] rows;
      int[] cols;

      if (!table.getRowSelectionAllowed() && !table.getColumnSelectionAllowed()) {
        return null;
      }

      if (table.getRowSelectionAllowed()) {
        rows = table.getSelectedRows();
      } else {
        int rowCount = table.getRowCount();

        rows = new int[rowCount];
        for (int counter = 0; counter < rowCount; counter++) {
          rows[counter] = counter;
        }
      }

      if (table.getColumnSelectionAllowed()) {
        cols = table.getSelectedColumns();
      } else {
        int colCount = table.getColumnCount();
        cols = new int[colCount];
        for (int counter = 0; counter < colCount; counter++) {
          cols[counter] = counter;
        }
      }

      //if (rows == null || cols == null || rows.length == 0 || cols.length == 0) {
      if (cols == null || rows.length == 0 || cols.length == 0) {
        return null;
      }

      StringBuffer plainBuf = new StringBuffer();
      StringBuffer htmlBuf = new StringBuffer(64);

      htmlBuf.append("<html>\n<body>\n<table border='1'>\n");

      for (int row = 0; row < rows.length; row++) {
        htmlBuf.append("<tr>\n");
        for (int col = 0; col < cols.length; col++) {
          Object obj = table.getValueAt(rows[row], cols[col]);
          String val = Objects.toString(obj, "") + "\t";
            //.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
          plainBuf.append(val);

          if (obj instanceof Date) {
            String v = Objects.toString((Date) obj, "");
            htmlBuf.append("  <td><time>" + v + "</time></td>\n");
          } else  if (obj instanceof Color) {
            htmlBuf.append(String.format(
                "  <td style='background-color:#%06X'>&nbsp;</td>%n",
                ((Color) obj).getRGB() & 0xffffff));
          } else {
            htmlBuf.append("  <td>" + Objects.toString(obj, "") + "</td>\n");
          }
        }
        // we want a newline at the end of each line and not a tab
        plainBuf.deleteCharAt(plainBuf.length() - 1).append("\n");
        htmlBuf.append("</tr>\n");
      }

      // remove the last newline
      plainBuf.deleteCharAt(plainBuf.length() - 1);
      htmlBuf.append("</table>\n</body>\n</html>");

      return new BasicTransferable(plainBuf.toString(), htmlBuf.toString());
    }

    return null;
  }
  @Override public int getSourceActions(JComponent c) {
    return TransferHandler.COPY;
  }
}
View in GitHub: Java, Kotlin

解説

  • 上: デフォルトのBasicTableUI.TableTransferHandlerを使用
  • 下: HtmlTableTransferHandlerを設定
    • TransferHandler#createTransferable(JComponent)をオーバーライドしてクリップボードに渡すtext/htmlなテキストを独自に作成
      • text/plainBasicTableUI.TableTransferHandlerのコピーをそのまま使用
      • <table>タグに属性border='1'を追加
    • セルのクラスに応じたタグを生成
      • Date: <time>...</time>で囲む
      • Color: <td>style='background-color:#%06x'>で背景色を設定

参考リンク

コメント