1

クラス FrameInfo で表されるビデオ ファイルに関する統計データを含むテーブルを表示するアプリケーションの一部に取り組んでいます。最初に、書式設定を含むすべてを実行するテーブル モデルを作成した後、それを逆の極端にリファクタリングし、テーブル モデルが各行の FrameInfo インスタンスのみを返すようにし、CellRenderer がレンダリングするフィールドとそれぞれの方法を決定できるようにしました。桁。たとえば、タイムコード値の表示をティック、秒、またはタイムコード ("00:01:02:03") の間で切り替えるには、再描画するだけです。テーブルの内容をコピーして gdocs スプレッドシートに貼り付け、すべてのセルでモデル オブジェクトの toString() の出力しか得られないことに気付くまでは満足していました (考え始めたときは論理的でしたが、明らかに私が望んでいるものではありませんでした)。 .

私のオプションは、私が今見ることができる限り:

1) すべてをモデルに戻します

長所:コピーすると、クリップボードに表示されているすべてのものがあります

短所:-タイムコードの表示モードを切り替えるときにモデルイベントをトリガーすることを意味します-ハイライター(私はJXTablesを使用しています)を書くと、モデルオブジェクトを使用できるようになった文字列の一致を行う必要があるため、再び面倒になります

2) そのままにして、レンダラーを使用するカスタム コピー アクションを作成し、レンダリングされたラベルからテキストを抽出します。

長所: - テーブルコードはクリーンなままです

短所: - 作業量(?) - 丸められた数値のようなものでは、精度が失われます

3)動的なもの(タイムコード)以外のすべてをモデルに入れ、レンダラーでタイムコードを実行し、それらの列のコピーと貼り付けのWYSIWYGを取得できないという事実を受け入れます

長所と短所: - 多かれ少なかれ中途半端な妥協

アドバイスや、私が使用できる既存のコードでさえありますか?

御時間ありがとうございます!

4

2 に答える 2

3

@trashgodの答えを拡張する:オプション1は明らかに間違っています:-) TableModelにはデータが含まれている必要があります。データをテーブル (実際には、Swing のコレクション ビューのいずれか) に表示するのは、レンダラーの唯一の仕事です。そして、できればレンダラーと同じ文字列表現を使用して、適切な形式でデータをエクスポートするのは TransferHandler の仕事です。

JXTable を使用すると、共同作業者間で文字列表現を簡単に共有できます。テキスト コンテンツを生成する小さなコインは StringValue と呼ばれ、すべての内部レンダラーが構成されます。構成が完了すると、その文字列は、検索、並べ替え、正規表現ベースのフィルタリング、テーブルの API など、すべての文字列関連の拡張機能で使用されます。

String text = table.getStringAt(row, column);

これにより、カスタム TransferHandler が文字列構築の基になることができます。

/**
 * A TableTransferable that uses JXTable string api to build
 * the exported data.
 * 
 * C&p from BasicTableUI, replaced toString with 
 * table.getStringAt(row, col)
 */
public static class XTableTransferHandler extends TransferHandler {

    /**
     * Create a Transferable to use as the source for a data transfer.
     * 
     * @param c The component holding the data to be transfered. This
     *        argument is provided to enable sharing of TransferHandlers by
     *        multiple components.
     * @return The representation of the data to be transfered.
     * 
     */
    @Override
    protected Transferable createTransferable(JComponent c) {
        if (!(c instanceof JXTable))
            return null;
        JXTable table = (JXTable) c;
        int[] rows;
        int[] cols;

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

        if (!table.getRowSelectionAllowed()) {
            int rowCount = table.getRowCount();

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

        if (!table.getColumnSelectionAllowed()) {
            int colCount = table.getColumnCount();

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

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

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

        htmlBuf.append("<html>\n<body>\n<table>\n");

        for (int row = 0; row < rows.length; row++) {
            htmlBuf.append("<tr>\n");
            for (int col = 0; col < cols.length; col++) {
                // original:
                // Object obj = table.getValueAt(rows[row], cols[col]);
                // String val = ((obj == null) ? "" : obj.toString());
                // replaced by JXTable api:
                String val = table.getStringAt(row, col);
                plainBuf.append(val + "\t");
                htmlBuf.append("  <td>" + val + "</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());
    }

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

}

使用例:

DefaultTableModel model = new DefaultTableModel(
        new String[]{"Action"}, 0);
JXTable table = new JXTable(model);
Object[] keys = table.getActionMap().allKeys();
for (Object key : keys) {
    model.addRow(new Object[]{table.getActionMap().get(key)});
}
StringValue sv = new StringValue() {

    @Override
    public String getString(Object value) {
        if (value instanceof Action) {
            return (String) ((Action) value).getValue(Action.NAME);
        }
        return StringValues.TO_STRING.getString(value);
    }

};
table.getColumn(0).setCellRenderer(new DefaultTableRenderer(sv));
table.setDragEnabled(true);
table.setTransferHandler(new XTableTransferHandler());
于 2013-07-22T05:40:35.040 に答える
2

データを含めるTableModel必要があり、選択したレンダラーがセルのコンテンツをフォーマットする必要があります。ここに示すように、カスタム で目的のドメイン固有のレンダリングを適用できますTransferablejava.text.MessageFormatと の両方で、モデルから取得したデータに同じ書式設定を適用するTableCellRendererために使用します。Transferable

于 2013-07-21T16:52:15.767 に答える