0

私が尋ねた別の質問(常に最後にnull値を持つjtableをソートする方法)への答えを見つけようとして、別の問題に遭遇しました。

TableRowSorterカスタムを作成するカスタムを実装していますComparator。ただし、常にタイプとしてComparatorevery を読み取るようです。これは私を困惑させました。ObjectString

以下の SSCCE で気付く場合は、次の行

System.out.println(o1.getClass() + " - " + o2.getClass());

常に出力を生成します

class java.lang.String - class java.lang.String

Object[][]データ配列の項目はさまざまなタイプですが。

import java.awt.Component;
import java.util.Comparator;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class Test {

    public static void main(String args[]) {
        JFrame frame = new JFrame();
        JTable table = new JTable();
        Object[][] data = new Object[8][3];
        data[0][0] = 6.5d; data[0][1] = "Name1";
        data[1][0] = new NullClassFiller(); data[1][1] = "Name2";
        data[2][0] = 2.6d; data[2][1] = "Name3";
        data[3][0] = 0d; data[3][1] = "Name4";
        data[4][0] = new NullClassFiller(); data[4][1] = "Name5";
        data[5][0] = -4d; data[5][1] = "Name6";
        data[6][0] = 0d; data[6][1] = "Name7";
        data[7][0] = -4.3d; data[7][1] = "Name8";
        table.setModel(new DefaultTableModel(data, new String[]{"One", "Two"}));

        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()) {
            @Override
            public Comparator<?> getComparator(final int column) {
                Comparator c = new Comparator() {
                    @Override
                    public int compare(Object o1, Object o2) {
                        System.out.println(o1.getClass() + " - " + o2.getClass());
                        if (o1 instanceof NullClassFiller) {
                            return -1;
                        } else if (o2 instanceof NullClassFiller) {
                            return -1;
                        } else {
                            return ((Comparable<Object>) o1).compareTo(o2);
                        }

                    }
                };
                return c;
            }
        };
        table.setRowSorter(sorter);
        table.getColumnModel().getColumn(0).setCellRenderer(new CustomRenderer());
        JScrollPane pane = new JScrollPane(table);
        frame.add(pane);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setSize(500, 500);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    static class NullClassFiller {}

    static class CustomRenderer extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

            if(value instanceof NullClassFiller)
                renderer.setText("");

            return renderer;
        }

    }
}
4

3 に答える 3

3

複合問題が多い...

1 つ目はDefaultTableModel. DefaultTableModel#getColumnClass戻りますObject.class

2 つ目はTableRowSorter. モデルから返された がであるTableRowSorterかどうかを確認します。そうでない場合は、 ではないため、自動的に に変換されます ...ClassComparableStringObjectComparable

したがって、基本的な解決策は、 をオーバーライドしてgetColumnClass、特定の列DefaultTableModelの適切な型を返すことです。Class

TableModel model = new DefaultTableModel(data, new String[]{"One", "Two"}) {
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return columnIndex == 0 ? Double.class : String.class;
    }
};
table.setModel(model);

TableRowSorter列をチェックすると、値Classが検索Comparableされ、テーブル モデルからの実際の値が使用され、String最初に変換されません。

最初の列を並べ替えてみると、次のようなものが表示されるはずです...

class testtablesort.TestTableSort$NullClassFiller) - class java.lang.Double
class java.lang.Double) - class testtablesort.TestTableSort$NullClassFiller
class java.lang.Double) - class java.lang.Double
class testtablesort.TestTableSort$NullClassFiller) - class java.lang.Double
class java.lang.Double) - class testtablesort.TestTableSort$NullClassFiller
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class testtablesort.TestTableSort$NullClassFiller
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class java.lang.Double
于 2013-09-08T07:07:27.073 に答える
0

問題はここにあります:

table.setModel(new DefaultTableModel(data, new String[]{"One", "Two"}));

http://docs.oracle.com/javase/tutorial/uiswing/components/table.htmlによると、

データを直接受け取る JTable コンストラクターは 2 つあります (SimpleTableDemo は最初のものを使用します)。

JTable(Object[][] rowData, Object[] columnNames) JTable(Vector rowData, Vector columnNames) The advantage of these constructors is

それらが使いやすいこと。ただし、これらのコンストラクターには欠点もあります。

すべてのセルが自動的に編集可能になります。すべてのデータ型を (文字列として) 同じように扱います。

于 2013-09-08T06:20:51.937 に答える