如何在两列上对JTable进行排序,以便“1”的项目位于顶部?

时间:2012-03-09 16:13:44

标签: java swing sorting jtable

假设我有一个像这样的行的JTable:

 (2, 1)
 (1, 3)
 (1, 5)
 (3, 1)
 (2, 3)
 (2, 4)

我想对JTable进行排序,以便第一列或第二列中包含1的行位于顶部,其余行可以具有任意顺序:

 (1, 3)
 (1, 5)
 (2, 1)
 (3, 1)
 (2, 3)
 (2, 4)

有没有办法在TableRowSorter的表格中执行此操作?

UPD :我想以编程方式对表进行排序,而不是通过UI(单击列标题)

4 个答案:

答案 0 :(得分:1)

您可以使用Comparator方法为第一列定义setComparator。然后,在compare的{​​{1}}方法中,如果第一个参数为1则返回Comparator,如果第二个参数为-1则返回11否则。

答案 1 :(得分:1)

  • 不是你的错误,也没有通过重新实现API中的一个Comparator与另一个Comparator重新实现轮子,另一种方法是实现RowFilter,example for RowFilter

enter image description here

enter image description here

enter image description here

enter image description here

来自代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableBoolean extends JFrame {

    private final static String LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final long serialVersionUID = 1L;
    private JTable table;
    private DefaultTableModel model;

    public TableBoolean() {
        Object[][] data = {{"A", new Boolean(false), 2, 1}, {"B", new Boolean(true), 1, 3},
            {"A", new Boolean(false), 1, 5}, {"B", new Boolean(true), 3, 1},
            {"A", new Boolean(false), 2, 3}, {"B", new Boolean(true), 2, 4},
            {"A", new Boolean(false), 5, 2}, {"B", new Boolean(true), 7, 1}};
        String[] columnNames = {"String", "Boolean", "Integer", "Integer"};
        model = new DefaultTableModel(data, columnNames) {

            private static final long serialVersionUID = 1L;

            @Override
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }

            @Override
            public boolean isCellEditable(int row, int column) {
                return true;
            }
        };
        table = new JTable(model);
        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel());
        table.setRowSorter(sorter);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane);
        /*JButton button = new JButton("Add Row");
        button.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
        Object[] newRow = new Object[2];
        int row = table.getRowCount() + 1;
        newRow[0] = LETTERS.substring(row - 1, row);
        newRow[1] = (row % 2 == 0) ? new Boolean(true) : new Boolean(false);
        model.addRow(newRow);
        }
        });
        add(button, BorderLayout.SOUTH);*/
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                TableBoolean frame = new TableBoolean();
                frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

答案 2 :(得分:1)

我想方设法不使用TableRowSorter:您可以在TableModel中预先输出数据,然后触发事件以让表知道数据已更改。这是伪代码:

设置表格:

AbstractTableModel model = new MyModel();
JTable table = new JTable(model);

实施MyModel

public class MyModel implements AbstractTableModel {
  private ArrayList<Integer> data;

  ...
  // implement interface methods
  ...

  public void sortToTop(int a) {
    // float all rows w/ a in the first column to the top
    Collections.sort(data, new Comparator<Integer>() {
        public int compare(int o1, int o2) {
            if (o1 == a) return -1;
            if (o2 == a) return 1;
            return o1.compareTo(o2);
        }
    });
    // find how many rows at the top have a in the first row
    int startIndex = 0;
    boolean notFound = true;
    while (startIndex < data.size() && notFound) {
        if (data.get(startIndex) == a)
            startIndex++;
        else 
            notFound = false;
    }
    int endIndex = data.size();
            // get a sublist w/o these first rows
    List<Integer> sublist = data.subList(startIndex, endIndex);
    // sort sublist on the second column floating a to the top
    Collections.sort(sublist, new Comparator<Integer>() {
        public int compare(int o1, int o2) {
            if (o1 == a) return -1;
            if (o2 == a) return 1;
            return o1.compareTo(o2);
        }
    });
    this.fireTableDataChanged();
  }
}

答案 3 :(得分:0)

在我看来,最简单的方法是首先在第二列调用sort,这将产生如下结果:

(3,1)
 (2,1)
 (1,3)
 (2,3)
 (2,4)
 (1,5)

但尚未完成。如果我们在第一列调用sort,那么我们将:

(1,3)
 (1,5)
 (2,1)
 (2,3)
 (2,4)
 (3,1)

这是迄今为止最简单的方法。