Как отсортировать JTable по двум столбцам, чтобы элементы с «1» находились вверху? - PullRequest
4 голосов
/ 09 марта 2012

Предположим, у меня есть 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 : я хочу отсортировать таблицу программно, а не через пользовательский интерфейс (щелкая заголовки столбцов)

Ответы [ 4 ]

1 голос
/ 09 марта 2012
  • не просто вы не правы, и не изобретайте колеса путем повторной реализации одного Comparator, интегрированного в API, с другим Comparator, другим способом является реализация RowFilter, пример для 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);
            }
        });
    }
}
1 голос
/ 09 марта 2012

Я нашел способ сделать это без использования 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();
  }
}
1 голос
/ 09 марта 2012

Вы можете определить Comparator для первого столбца, используя метод setComparator. Затем в вашем методе compare в Comparator верните -1, если первый аргумент равен 1, 1, если второй аргумент равен 1, и 0 в противном случае.

0 голосов
/ 03 марта 2014

На мой взгляд, самый простой способ сделать это - сначала вызвать сортировку во втором столбце, что приведет к чему-то вроде этого:

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

, но это еще не все.Если мы затем вызовем сортировку в первом столбце, то получим:

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

Это, безусловно, самый простой способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...