【问题标题】:Sorting double values in JTable在 JTable 中对双精度值进行排序
【发布时间】:2011-12-15 18:24:35
【问题描述】:

我发现了很多与此相关的问题,但我还没有找到解决问题的简单方法。

我找不到让 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,还是两者兼而有之。

有人可以指导我如何以更简单的方式解决这个问题吗?

非常感谢和最好的问候。

已编辑:已解决

说出问题出在哪里,挺尴尬的。

包含 Object[] 行的 ArrayList 是使用 getString(int) 而不是 getObject(int) 或 getDouble(int) 从数据库 ResultSet 填充的,因此渲染器无法将该值用作 Double。奇怪的是,它没有使用 Integer 或 Number 作为列类给出异常,但无论如何它都被排序为 String 。我在错误的类中寻找问题,因为我确信我的 ArrayList 只包含对象。

非常感谢您的示例,看着它们我注意到我的双打实际上是字符串,然后我可以找到转换发生的位置。

【问题讨论】:

  • 您应该从问题中删除解决方案并将其添加为答案。

标签: java swing jtable double tablerowsorter


【解决方案1】:

查看此代码。它对双精度值进行排序。

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

我稍微修改了link 给出的源代码,使其采用双精度值。

【讨论】:

  • 如果您没有明确设置 RowSorter,这仍然有效吗?我从来不需要手动设置排序器,只要getColumnClass() 返回正确的类,排序仍然有效。
  • 如果我没有明确设置 RowSorter,当我点击标题时不会发生任何事情。
  • 您不必显式设置排序器,只需通过 table.setAutoCreateRowSorter(true) 启用排序
  • 谢谢,真的帮了我!
【解决方案2】:

这个代码可能是你的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();
            }
        });
    }
}

【讨论】:

  • 非常感谢您的代码,我在发现错误之前测试了这两个代码,它只是 Bragboy 看起来更清晰一些,但真的,非常感谢 =)
  • @mKorbel +1 不错的答案。你好回来。很高兴见到你交配。这些天我很少活动。忙于其他事情:)
  • +1 个示例越来越短 - 很好 :-) 不需要 SortKeys,不过:getRowSorter().toggleSortOrder(0) 将进行初始排序
猜你喜欢
  • 1970-01-01
  • 2012-11-06
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 2019-04-18
相关资源
最近更新 更多