2

JTable のデフォルトの TransferHandler は、データをタブ区切り形式でエクスポートします。データを HTML テーブルとしてエクスポートする独自の TransferHandler を作成しようとしていますが、現在、使用してもクリップボードに何もコピーされません。この機能を追加するにはどうすればよいですか?

現在、次の TransferHandler を使用してテーブルに追加していますtable.setTransferHandler(new TableTransferHandler());

public class TableTransferHandler extends TransferHandler {
    final static Logger logger = LoggerFactory.getLogger("TableTransferHandler");

    @Override
    protected Transferable createTransferable(JComponent comp) {
        JTable table = (JTable) comp;
        logger.debug("creating table selection transferable");
        return new TableSelection(table);
    }

}

TableSelection譲渡可能:

public class TableSelection implements Transferable {
    final static Logger logger = LoggerFactory.getLogger("TableSelection");

    private static DataFlavor HTML_TEXT;

    private static final List<DataFlavor> flavors = new ArrayList<DataFlavor>();

    private JTable table;

    public TableSelection(JTable table) {
        this.table = table;
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return flavors.contains(flavor);
    }

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return flavors.toArray(new DataFlavor[0]);
    }

    @Override
    public Object getTransferData(DataFlavor flavor) throws IOException, UnsupportedFlavorException {
        if (flavor.equals(HTML_TEXT)) {
            StringBuilder sb = new StringBuilder("<table>");
            int[] rows = table.getSelectedRows();
            int[] cols = table.getSelectedColumns();

            for (int row : rows) {
                int col_index = 0;
                sb.append("<tr><td>");
                for (int col : cols) {
                    Object value = table.getValueAt(row, col);
                    if (value != null)
                        sb.append(value.toString());

                    if (col_index + 1 < cols.length)
                        sb.append("</td><td>");
                }
                sb.append("</td></tr>\n");
            }
            sb.append("</table>");

            return sb.toString();
        }
        else {
            throw new UnsupportedFlavorException(flavor);
        }
    }

    static {

        try {
            HTML_TEXT = new DataFlavor("text/html;class=java.lang.String");
            flavors.add(HTML_TEXT);
        }
        catch (ClassNotFoundException e) {
            logger.error("Couldn't create HTML_TEXT flavor", e);
        }
    }
}
4

1 に答える 1

2

欠けているのは1つだけです。TransferHandler.getSourceActions次のように実装する必要があります。

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

編集:これはMac OS Xで機能します。ただし、Windowsでは、メモ帳またはワードパッドへの貼り付けは機能しますが、OpenOfficecalcでは機能しません。調査の結果、JavaAWTとOpenOfficeの両方に問題があると思います。

  • Javaは、次のHTMLクリップボード形式を生成します。

    バージョン:
    0.9StartHTML:-1
    EndHTML:-1
    ..。

これらの2つ-1は間違っています。それらはいくつかの正のオフセット数であると想定されています。ここにあるものに非常に近い既知のJDKバグがあります。

  • 一方、OpenOfficeは、このような部分的に正しいクリップボード形式を処理できませんが、メモ帳やワードパッドは処理できます。OpenOfficeのbugzillaデータベースで「pastehtmlcalc」を検索すると、7300以上(!)の未解決のバグがあります。
于 2011-12-12T06:54:09.820 に答える