【问题标题】:How to sort JTable rows if Override "getColumnClass" has no effect如果覆盖“getColumnClass”无效,如何对 JTable 行进行排序
【发布时间】:2017-08-15 14:28:15
【问题描述】:

事实上,这更像是一个答案而不是一个问题。 从文件创建 JTable 时,我遇到了 TableRowSorter 问题。我像这样使用 TableModel:

public class TModel extends AbstractTableModel {

    public Vector data;
    public Vector colNames;
    public String datafile;
    Class[] types = {Integer.class, Date.class, Number.class, String.class, Character.class};

    public TModel(String f) {
        datafile = f;
        initVectors();
    }

    public void initVectors() {
        String aLine;
        data = new Vector();
        colNames = new Vector();
        try {
            FileInputStream fin = new FileInputStream(datafile);
            BufferedReader br = new BufferedReader(new InputStreamReader(fin));
            // extract column names
            StringTokenizer st1 =
                    new StringTokenizer(br.readLine(), "|");
            while (st1.hasMoreTokens())
                colNames.addElement(st1.nextToken());
            // extract data
            while ((aLine = br.readLine()) != null) {
                StringTokenizer st2 =
                        new StringTokenizer(aLine, "|");
                while (st2.hasMoreTokens())
                    data.addElement(st2.nextToken());
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public int getRowCount() {
        return data.size() / getColumnCount();
    }

    public int getColumnCount() {
        return colNames.size();
    }

    public String getColumnName(int columnIndex) {
        String colName = "";

        if (columnIndex <= getColumnCount())
            colName = (String) colNames.elementAt(columnIndex);

        return colName;
    }

    public Class getColumnClass(int columnIndex) {
        return this.types[columnIndex];
    }

    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        return data.elementAt((rowIndex * getColumnCount()) + columnIndex);
    }

    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        return;
    }

问题是表中的第一列排序为字符串,无论它从“GetColumnClass”方法返回哪种类型。对于此类问题,最受欢迎的建议是:“您应该覆盖 GetColumnClass 方法”或“为每列设置特定类型”。遗憾的是,这些都不适合我 :_(This topic 帮助了我很多,主要是 sn-p来自Alanmars。 简单的解决方案:如果 TableRowSorter 将数字视为字符串,只需让它像整数一样比较它们! 下面 - sn-p,对我有用:

TModel tModel = new TModel(selectedFile);
JTable table = new JTable();
JScrollPane scrollPane = new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sorter = new TableRowSorter<>(tModel);
sorter.setComparator(IndexOfDesiredColumn, new Comparator<String>() {
    @Override
    public int compare(String n1, String n2) {
    return Integer.parseInt(n1) - Integer.parseInt(n2);
    }
});
table.setModel(tModel);
table.setRowSorter(sorter);

希望这个步骤可以为那些和我面临同样问题的人节省时间。

【问题讨论】:

  • (1-) The issue was that first column in table sorted like String regardless which type it returns from "GetColumnClass" method. - 那么你的代码有问题。您的解决方法是不必要的。修复你的代码。当然,如果您重写 getColumnClass(...) 方法以返回 Integer,那么您还必须在模型中存储 Integer 值。该表不会为您将字符串转换为整数。
  • TY 发表评论,@camickr,但我只愿意分享代码 sn-p,这适用于我的情况(这就是为什么在帖子中列出 TModel 类代码 - 以显示完整图片)。如果代码看起来错误或原始,这不是现在的重点 - 它正在工作!这就是重点。我什么都没问,但感谢您分享您的知识。)
  • ...it's working! And that is the point. - 这是错误的观点。该论坛用于推广良好的编码技术。您的解决方案是一种解决方法,因为您不了解 JTable 的工作原理。我的评论是为了让其他人不要盲目地遵循解决方案。
  • @camickr,我不会不同意你的观点——好的编码总是更可取的。

标签: java swing sorting jtable tablerowsorter


【解决方案1】:

您的所有列都从原始 Vector 获取数据,即所有这些数据都在 Object...

排序器采用任何Objects,而不是null,并在它们上调用toString(),并对结果进行排序......

你的getColumnClass()方法没有正确实现,好像模型中没有数据(EG它是空的)它会抛出NullPointerException...

【讨论】:

  • (1-) And the sorter takes any Objects, that are not null, and calls toString() on them, and does the sorting with the result... - 它不调用 toString()。它只是调用比较器并传递对象。然后比较器进行比较。
  • 看一下文档:docs.oracle.com/javase/tutorial/uiswing/components/…有一个5分的步骤列表,最后一个是toString()...
  • 您的回答暗示这是第一步。无论如何,这充其量只是评论而不是解决方案。它没有建议应该如何实现 getColumnClass() 方法。也没有提到模型中的数据也必须匹配从该方法返回的类。因此,在 OP 的示例中,您不能只覆盖 getColumnClass() 以返回 Integer,然后将 String 对象存储在模型中。您还必须按照我在原始评论中的建议在模型中存储一个 Integer 对象。
猜你喜欢
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-01
  • 2015-03-23
  • 2015-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多