Reputation: 816
I've a JTable
which shows an array of data of the type
String [] data = {"String1", "String2", "String3", "String4"};
but in the JTable I show only the first 3 items and the fourth is hidden for the user. But I would sorter the table even in base of the String4
that is not shown in JTable. I read JTable tutorial and I found out how to use TableRowSorter
and set a Comparator
but method setComparator
wants as its argument the column to order but this is not available for me.
Could anyone help me to solve this task? thank you
Upvotes: 3
Views: 363
Reputation: 347204
The trick is, include the column in the TableModel
, but remove it from the TableColumnModel
The "A" column is actually randomly generated, so it will sort in an unpredictable manner
You can disable columns from been sortable using something like sorter.setSortable(1, false);
, this could be used to prevent the user from clicking the column header and ruining your "hidden" sort.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
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.TableRowSorter;
public class MagicSort {
public static void main(String[] args) {
new MagicSort();
}
public MagicSort() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private SortOrder order = SortOrder.ASCENDING;
public TestPane() {
RowDataTableModel model = new RowDataTableModel();
TableRowSorter<RowDataTableModel> sorter = new TableRowSorter<>(model);
sorter.setComparator(0, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
JTable table = new JTable(model);
table.setRowSorter(sorter);
table.getColumnModel().removeColumn(table.getColumn("A"));
setLayout(new BorderLayout());
add(new JScrollPane(table));
JButton change = new JButton("Change");
add(change, BorderLayout.SOUTH);
change.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sort(sorter);
}
});
sort(sorter);
}
protected void sort(TableRowSorter<RowDataTableModel> sorter) {
List<RowSorter.SortKey> keys = new ArrayList<>(1);
keys.add(new RowSorter.SortKey(0, order));
sorter.setSortKeys(keys);
switch (order) {
case ASCENDING:
order = SortOrder.DESCENDING;
break;
case DESCENDING:
order = SortOrder.UNSORTED;
break;
case UNSORTED:
order = SortOrder.ASCENDING;
break;
}
}
}
public class RowDataTableModel extends AbstractTableModel {
private List<RowData> data = new ArrayList<>(25);
public RowDataTableModel() {
for (int index = 0; index < 10; index++) {
data.add(new RowData(index));
}
}
public String getKeyColumnValue(int row) {
return data.get(row).get(0);
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data.get(rowIndex).get(columnIndex);
}
}
public class RowData {
private List<String> values = new ArrayList<>();
public RowData(int offset) {
offset *= 5;
for (int index = 1; index < 5; index++) {
values.add(Character.toString((char) ('A' + (offset + index))));
}
values.add(0, Character.toString((char) ('A' + Math.random() * 26)));
}
public String get(int col) {
return values.get(col);
}
}
}
Note: However, visually, this could be confusing to the user, so I'd use it sparingly.
Upvotes: 3