Сортировка двойных значений в JTable - PullRequest
6 голосов
/ 04 сентября 2011

Я нашел довольно много вопросов, связанных с этим, но я не нашел простого решения моей проблемы.

Я не могу найти способ правильно настроить значения JTable для сортировки Double.

Я расширил AbstractTableModel, чтобы получить массив Class и возвращать правильные типы для каждого столбца:

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, я не получаю ошибки, но сортировка все равно не работает должным образом. Я пробовал использовать разные числовые классы, но ни один из них, похоже, не сортирует парные слова правильно:

@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 или оба.

Может ли кто-нибудь подсказать мне, как это исправить проще?

Большое спасибо и наилучшие пожелания.

отредактировано: решено

Довольно неловко говорить, в чем проблема.

ArrayList, содержащий строки Object [], был заполнен из базы данных ResultSet с использованием getString (int) вместо getObject (int) или getDouble (int), поэтому значение не может использоваться как средство визуализации Double. Странно, что он не дает исключений, используя Integer или Number в качестве класса столбца, но в любом случае он сортируется как String. Я искал проблему в неправильных классах, так как был убежден, что мой ArrayList содержит только объекты.

Большое спасибо за ваши примеры, глядя на них, я заметил, что мои двойники на самом деле были Strings, а затем я смог найти, где происходит преобразование.

Ответы [ 2 ]

6 голосов
/ 04 сентября 2011

этот код может быть вашим 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();
            }
        });
    }
}
6 голосов
/ 04 сентября 2011

Проверьте этот код.Сортирует двойные значения.

enter image description here

enter image description here

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);
  }
}

Я немного изменил источник, указанный по этой ссылке , чтобы он принимал двойные значения.

...