2

我的 tableModel 包含多个列(例如:列 A - F),当我第一次显示时,我应该显示首先按 B 列然后按 D 排序的表格。现在,面临的问题是:D 列是时间戳。Col. B 包含标识符,例如:

  1. (Col. B)“Clt A - 001”(Col. D)上午 11:34
  2. (Col. B)“Clt B - 001”(Col. D)12:42 AM
  3. (B 栏)“Clt A - 001”(D 栏)下午 1 点 18 分
  4. (B 栏)“Clt A - 002”(D 栏)下午 1 点 18 分
  5. (Col. B)“Clt C - 001”(Col. D)上午 10:30
  6. (B 栏)“Clt C - 001”(D 栏)下午 2 点 45 分

我需要的输出类型是:

  1. (Col. B)“Clt A - 001”(Col. D)上午 11:34
  2. (B 栏)“Clt A - 001”(D 栏)下午 1 点 18 分
  3. (B 栏)“Clt A - 002”(D 栏)下午 1 点 18 分
  4. (Col. B)“Clt B - 001”(Col. D)12:42 AM
  5. (Col. B)“Clt C - 001”(Col. D)上午 10:30
  6. (B 栏)“Clt C - 001”(D 栏)下午 2 点 45 分

我不明白的是,当我编写自定义 compare() 方法时,我只获取特定列的对象。但是,如果您在上面的示例数据中观察到,排序取决于辅助列中的信息。(我无法通过使用 sortPrecedence 来解决这个问题,因为当 col.D 中的时间戳相同时,Col.B 的值实际上并不相同。如果我最初按 Col.D 排序,然后按 Col.B 排序,那么排序顺序主要由时间戳而不是 Col. B 的字母顺序驱动。TableRowSorter 是我的选择吗?如果是,我应该如何实现比较器?非常感谢任何帮助。

谢谢。

4

1 回答 1

3

看看如何使用表格,排序

有一个示例演示了如何设置多列排序...

我引用...

要指定列的排序顺序和排序优先级,请调用 setSortKeys。这是一个示例,它按前两列对示例中使用的表进行排序。排序中列的优先级由排序键列表中排序键的顺序指示。在这种情况下,第二列具有第一个排序键,因此它们的行按名字排序,然后是姓氏。

List <RowSorter.SortKey> sortKeys 
    = new ArrayList<RowSorter.SortKey>();
sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING));
sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
sorter.setSortKeys(sortKeys);

工作示例

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableRowSorter;

public class TestMuiltColumnTableSort {

    public static void main(String[] args) {
        new TestMuiltColumnTableSort();
    }
    public static final SimpleDateFormat SDF = new SimpleDateFormat("hh:mm aa");

    public TestMuiltColumnTableSort() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                try {
                    MyTableModel model = new MyTableModel();
                    model.addRow("Job #1.1", "Clt A - 001", "11:34 AM");
                    model.addRow("Job #2.1", "Clt B - 001", "12:42 AM");
                    model.addRow("Job #1.1", "Clt A - 001", "01:18 PM");
                    model.addRow("Job #1.2", "Clt A - 002", "01:18 PM");
                    model.addRow("Job #3.1", "Clt C - 001", "10:30 AM");
                    model.addRow("Job #3.1", "Clt C - 001", "02:45 PM");
                    model.addRow("Job #1.2", "Clt A - 002", "12:00 PM");
                    JTable table = new JTable(model);
                    table.setAutoCreateRowSorter(false);
                    table.setDefaultRenderer(Date.class, new TimeCellRenderer());

                    TableRowSorter<MyTableModel> sorter = new TableRowSorter<MyTableModel>(model);
                    table.setRowSorter(sorter);

                    List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
                    sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING));
                    sortKeys.add(new RowSorter.SortKey(2, SortOrder.ASCENDING));
                    sorter.setSortKeys(sortKeys);

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new JScrollPane(table));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (ParseException exp) {
                    exp.printStackTrace();
                    System.exit(0);
                }
            }
        });
    }

    public class TimeCellRenderer extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); //To change body of generated methods, choose Tools | Templates.
            if (value instanceof Date) {
                setText(SDF.format(value));
            }
            return this;
        }
    }

    public class MyTableModel extends AbstractTableModel {

        private List<Row> rows = new ArrayList<>(25);

        public void addRow(String name, String cat, String date) throws ParseException {

            rows.add(new Row(name, cat, SDF.parse(date)));

        }

        @Override
        public int getRowCount() {
            return rows.size();
        }

        @Override
        public int getColumnCount() {
            return 3;
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            Class clazz = String.class;
            switch (columnIndex) {
                case 2:
                    clazz = Date.class;
                    break;
            }
            return clazz;
        }

        @Override
        public String getColumnName(int column) {
            String name = "??";
            switch (column) {
                case 0:
                    name = "Name";
                    break;
                case 1:
                    name = "Catagory";
                    break;
                case 2:
                    name = "Date";
                    break;
            }
            return name;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Row row = rows.get(rowIndex);
            Object value = null;
            switch (columnIndex) {
                case 0:
                    value = row.getName();
                    break;
                case 1:
                    value = row.getCat();
                    break;
                case 2:
                    value = row.getDate();
                    break;
            }
            return value;
        }
    }

    public class Row {

        private String name;
        private String cat;
        private Date date;

        public Row(String name, String cat, Date date) {
            this.name = name;
            this.cat = cat;
            this.date = date;
        }

        public String getName() {
            return name;
        }

        public String getCat() {
            return cat;
        }

        public Date getDate() {
            return date;
        }
    }
}

额外的

只需提供Comparator所需的列,TableRowSorter您应该能够满足您的基本要求...

在此处输入图像描述

sorter.setComparator(1, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.substring(0, Math.min(o1.length(), 5)).compareTo(o2.substring(0, Math.min(o2.length(), 5)));
    }
});

您应该能够为每一列提供一个camparator,从而修改子/组排序的工作方式......

于 2013-06-03T02:25:01.687 回答