6

私はこれに関連するかなりの数の質問を見つけましたが、私の問題に対する簡単な解決策は見つかりませんでした。

JTableでDouble値を正しくソートする方法が見つかりません。

AbstractTableModelを拡張して、クラス配列を受け取り、列ごとに適切な型を返しました。

class TableModelMod extends AbstractTableModel{

    private ArrayList data;
    private String [] headers;
    private Class [] types;

    TableModelMod(String [] heads, ArrayList datas, Class [] classes){
        headers = heads;
        data = datas;
        types = classes;
    }
    ... 
    @Override public Class getColumnClass(int c){
        if (c > types.length - 1)
            return null;
        else 
            return types[c];
    }
...

そして、私のカスタムJTableコンストラクターで:

TableRowSorter<TableModelMod> sorter = new TableRowSorter<TableModelMod>((TableModelMod)getModel());

しかし、行を追加すると次のエラーが発生します。

java.lang.IllegalArgumentException: Cannot format given Object as a Number

DecimalFormat.format(Object number, StringBuffer toAppendTo, FieldPosition pos)Double以外のほとんどの数値タイプを受け入れるメソッドでは失敗します。

Double列に別のクラスを使用してもエラーは発生しませんが、それでもソートは期待どおりに機能しません。さまざまな数値クラスで試しましたが、doubleを正しくソートするものはないようです。

@Override public Class getColumnClass(int c){
    if (c > types.length - 1)
        return null;
    else if (types[c] == Double.class)
        return Number.class;
    else 
        return types[c];
}

カスタムRowSorter、カスタムCellRenderer、またはその両方を実装する必要があるかどうかはわかりません。

誰かがこれをもっと簡単な方法で修正する方法を教えてもらえますか?

どうもありがとうございました。

編集済み:解決済み

問題がどこにあったかを知るのは非常に恥ずかしいことです。

Object []行を含むArrayListは、getObject(int)またはgetDouble(int)の代わりにgetString(int)を使用してデータベースResultSetから入力されたため、レンダラーは値をDoubleとして使用できませんでした。列クラスとして整数または数値を使用して例外が発生しなかったのは奇妙ですが、とにかく文字列としてソートされていました。ArrayListにはオブジェクトだけが含まれていると確信していたので、間違ったクラスで問題を探していました。

あなたの例をどうもありがとう、それらを見て、私は私のダブルスが実際には文字列であることに気づきました、そしてそれから私は変換が起こっていた場所を見つけることができました。

4

2 に答える 2

6

このコードをチェックしてください。double 値をソートします。

ここに画像の説明を入力

ここに画像の説明を入力

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class RowSorterDemo {
  public static void main(String args[]) {
    JFrame frame = new JFrame("Sort Table Demo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Object rows[][] = { { "J", 23.1 }, { "R", 21.1, }, { "E", 21.2, }, { "B", 27.1, }, { "A", 25.2, },
        { "S", 22.9, }, };

    String columns[] = { "Name", "Age" };

    TableModel model = new DefaultTableModel(rows, columns) {
      public Class getColumnClass(int column) {
        Class returnValue;
        if ((column >= 0) && (column < getColumnCount())) {
          returnValue = getValueAt(0, column).getClass();
        } else {
          returnValue = Object.class;
        }
        return returnValue;
      }
    };

    JTable table = new JTable(model);

    RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);

    table.setRowSorter(sorter);

    JScrollPane pane = new JScrollPane(table);

    frame.add(pane, BorderLayout.CENTER);

    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}

このリンクで提供されているソースを少し変更して、double 値を取るようにしました。

于 2011-09-04T13:06:16.353 に答える
6

このコードはあなたのSSCCEである可能性があります。このコードで発行したことを証明できますか?

import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableTest2 {

    public void initGUI() {
        String[] columnNames = {"numbers","double", "text"};
        Object[][] data = {{1, 0.81, "A"}, {10, 5.268752005, "B"}, {7, 100.0,"C"},{6, 52.879999, "A"},
        {4, 62.50, "B"}, {2, 854.9999, "C"},{11, 19.01, "A"}, {100, 0.0009, "B"}, {20, 100.09, "C"}};
        JTable table = new JTable(new DefaultTableModel(data, columnNames) {

            private static final long serialVersionUID = 1L;

            @Override
            public java.lang.Class<?> getColumnClass(int c) {
                return getValueAt(0, c).getClass();
            }
        });
        table.setAutoCreateRowSorter(true);
        table.getRowSorter().setSortKeys(Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
        JFrame frame = new JFrame("LFIXimate");
        frame.setResizable(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TableTest2().initGUI();
            }
        });
    }
}
于 2011-09-04T13:13:57.287 に答える