2011-09-04 73 views
6

我发现了很多与此相关的问题,但我还没有找到解决我的问题的简单方法。在JTable中对双精度值进行排序

我无法找到一种方法使我的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)失败ac大多数数字类型除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作为列类来提供异常,但是它正在被排序为一个字符串。我在错误的类中寻找一个问题,因为我确信我的ArrayList只包含对象。

非常感谢你的例子,看着他们我发现我的双打实际上是弦乐,然后我可以找到转换发生的地方。

+1

你应该从你的问题中删除解决方案,并将其添加作为一个答案。 – murgatroid99

回答

6

查看此代码。它分类双重价值。

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

我修改,以便它需要双重价值在这个link给出一点点的来源。

+0

如果您没有明确设置RowSorter,这是否仍然有效?只要getColumnClass()返回正确的类,我就不必手动设置分类器并排序。 – AngerClown

+0

如果我没有明确设置RowSorter,当我点击一个标题时什么也没有发生。 – AlbertCossi

+0

非常感谢您的代码! – AlbertCossi

6

此代码可能是你的SSCCE,您可以demonstate你发出这个代码,从代码没有剪断,您张贴

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(); 
      } 
     }); 
    } 
} 
+0

非常感谢你在我发现我的错误之前测试了我的代码,这只是Bragboy的看起来更清晰,但真的,非常感谢你=) – AlbertCossi

+0

@mKorbel +1好的答案。你回来了。很高兴见到你交配。这些日子我很少活跃。太忙了其他的东西:) – Boro

+0

+1的例子越来越短 - gooood :-)不需要SortKeys,但:getRowSorter()。toggleSortOrder(0)将执行初始排序 – kleopatra