有一个TableModel。需要同时根据两个不同的列进行排序

时间:2013-06-03 01:33:25

标签: java swing user-interface tablemodel

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

  1. (Col.B)“Clt A - 001”(上校D)上午11:34
  2. (Col.B)“Clt B - 001”(上校D)12:42 AM
  3. (Col.B)“Clt A - 001”(第D栏)下午1:18
  4. (Col.B)“Clt A - 002”(第D栏)下午1:18
  5. (Col.B)“Clt C - 001”(上校D)上午10:30
  6. (Col.B)“Clt C - 001”(第D栏)下午2:45
  7. 我需要的输出类型是:

    1. (Col.B)“Clt A - 001”(上校D)上午11:34
    2. (Col.B)“Clt A - 001”(第D栏)下午1:18
    3. (Col.B)“Clt A - 002”(第D栏)下午1:18
    4. (Col.B)“Clt B - 001”(上校D)12:42 AM
    5. (Col.B)“Clt C - 001”(上校D)上午10:30
    6. (Col.B)“Clt C - 001”(第D栏)下午2:45
    7. 我不明白的是,当我编写自定义compare()方法时,我只获取特定列的对象。但是,如果您在上面的示例数据中观察到,排序取决于辅助列中的信息。 (我无法通过使用sortPrecedence来克服这个问题,因为当Col.D中的时间戳相同时,Col.B的值实际上并不相同。如果我最初按照Col.D排序,稍后按Col.B排序,那么排序顺序主要由时间戳驱动,而不是按照字母B的字母顺序驱动。是TableRowSorter我的选项吗?如果是,我应该如何实现比较器?任何帮助都非常感激。

      感谢。

1 个答案:

答案 0 :(得分:3)

看看How to use tables, Sorting

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

我引用......

  

要指定列的排序顺序和排序优先级,请调用   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);

工作示例

enter image description here

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的{​​{1}}所需列中提供TableRowSorter即可实现基本要求......

enter image description here

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

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