Сортировать JTable, кроме последней строки
2181 просмотра
5 ответа
У меня есть, JTable
где последняя строка является общей строкой, которая объединяет все остальные строки. Когда пользователь щелкает заголовок столбца в таблице, строки сортируются по этому столбцу, за исключением общей строки, которая всегда должна быть внизу.
Есть ли простой способ реализовать это с TableRowSorter
?
Ответы (5)
2 плюса
Следующее решение работало для меня ....
В вашей табличной модели обновите getRowCount()
член, чтобы он возвращал на 1 строку меньше, чем требуется.
Затем измените индекс и количество строк, сообщаемых вашим сортировщиком, следующим образом ...
TableRowSorter<TableModel> sorter =
new DefaultTableRowSorter<TableModel>(this.getModel())
{
public int convertRowIndexToModel(int index)
{
int maxRow = super.getViewRowCount();
if (index >= maxRow)
return index;
return super.convertRowIndexToModel(index);
}
public int convertRowIndexToView(int index)
{
int maxRow = super.getModelRowCount();
if (index > maxRow)
return index;
return super.convertRowIndexToView(index);
}
public int getViewRowCount()
{
return super.getViewRowCount() + 1;
}
};
myTable.setRowSorter(sorter);
Автор: Das
Размещён: 13.06.2013 05:03
5 плюса
Лично я бы создал однорядную 2-ую таблицу с удаленным заголовком и поместил бы ее непосредственно под основной таблицей, чтобы создать иллюзию последней строки.
Помимо решения вашей проблемы с сортировкой, она также будет сохраняться, пока пользователь прокручивает эту основную таблицу, что, вероятно, хорошо, так как это строка «итогов».
Вы даже можете добавить ColumnModelListener
к основной таблице, TableColumnModel
чтобы синхронизировать изменение размера столбца.
РЕДАКТИРОВАТЬ : Вот общая идея:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TestFrame implements Runnable
{
JTable mainTable;
JTable fixedTable;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new TestFrame());
}
public void run()
{
mainTable = new JTable(8, 3);
mainTable.getTableHeader().setReorderingAllowed(false);
mainTable.setAutoCreateRowSorter(true);
for (int r = 0; r < 8; r++)
{
for (int c = 0; c < 3; c++)
{
mainTable.setValueAt((int)(Math.random()*100), r, c);
}
}
mainTable.getColumnModel().addColumnModelListener(
new TableColumnModelListener()
{
public void columnAdded(TableColumnModelEvent e) {}
public void columnRemoved(TableColumnModelEvent e) {}
public void columnMoved(TableColumnModelEvent e) {}
public void columnSelectionChanged(ListSelectionEvent e) {}
public void columnMarginChanged(ChangeEvent e)
{
synchColumnSizes();
}
});
setVisibleRowCount(mainTable, 5);
JScrollPane scroll = new JScrollPane(mainTable);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
fixedTable = new JTable(1, 3);
fixedTable.setValueAt("will not sort or", 0, 0);
fixedTable.setValueAt("scroll but will", 0, 1);
fixedTable.setValueAt("resize with main", 0, 2);
JPanel p = new JPanel(new GridBagLayout());
p.setBorder(BorderFactory.createTitledBorder("Fixed Last Row"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.WEST;
p.add(scroll, gbc);
gbc.gridy = 1;
p.add(fixedTable, gbc);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(p, BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private void synchColumnSizes()
{
TableColumnModel tcmMain = mainTable.getColumnModel();
TableColumnModel tcmFixed = fixedTable.getColumnModel();
for (int i = 0; i < tcmMain.getColumnCount(); i++)
{
int width = tcmMain.getColumn(i).getWidth();
tcmFixed.getColumn(i).setPreferredWidth(width);
}
}
public static void setVisibleRowCount(JTable table, int rows)
{
table.setPreferredScrollableViewportSize(new Dimension(
table.getPreferredScrollableViewportSize().width,
rows * table.getRowHeight()));
}
}
Автор: splungebob
Размещён: 21.05.2013 04:35
2 плюса
Есть ли простой способ реализовать это с помощью TableRowSorter?
не не просто
хорошая идея, вполне возможно установить флаг для RowSorter, его SortingKeys
есть ошибка для всех типов ClassType, кроме String
1 плюс
@Das: возможно, эта версия лучше, так как вам не нужно переопределять getRowCount (), который может использоваться и может вызывать проблемы с другими функциями
public class TableRowSorterTotal<MyTableModel extends TableModel> extends TableRowSorter<TableModel>
{
TableRowSorterTotal(MyTableModel model)
{
super(model);
}
public int convertRowIndexToModel(int index)
{
int maxRow = super.getViewRowCount();
int currModel = super.convertRowIndexToModel(index);
int maxModel = super.convertRowIndexToModel(maxRow-1);
if(currModel == maxModel)
return maxRow - 1;
if(currModel > maxModel)
return currModel- 1;
return currModel;
}
public int convertRowIndexToView(int index)
{
int maxRow = super.getModelRowCount();
int currView= super.convertRowIndexToView(index);
int maxView = super.convertRowIndexToView(maxRow-1);
if(currView == maxView)
return maxRow - 1;
if(currView > maxView)
return currView- 1;
return currView;
}
}
Автор: guest123
Размещён: 06.06.2014 08:26
1 плюс
На основе этого примера приведенный ниже пример полного примера иллюстрирует подход в принятом ответе . В частности,
Реализация
getRowCount()
вTableModel
возвращаетsize()
изList<Employee>
, который является одним меньше , чем число строк отображаются в таблице.Реализация
getValueAt()
вTableModel
иллюстрирует вызовsum()
вCOLUMN_SALARY
некоторых из возможных вариантов отображения для остальных столбцов в дополнительной строке в нижней части.Реализация
getViewRowCount()
inTableRowSorter
позволяет отображать дополнительную строку, но исключает разумную фильтрацию .
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
/**
* @see https://stackoverflow.com/a/37913520/230513
* @see https://stackoverflow.com/a/37892395/230513
*/
public class JTableColumnTotalExample {
public static void main(String[] args) {
EventQueue.invokeLater(JTableColumnTotalExample::display);
}
public static void display() {
JFrame f = new JFrame("JTable Sorting Example");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
List<Employee> listEmployees = createListEmployees();
TableModel model = new EmployeeTableModel(listEmployees);
JTable table = new JTable(model) {
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(500, getRowCount() * getRowHeight());
}
};
table.getColumnModel().getColumn(3).setCellRenderer(new CurrencyFormatter());
TableRowSorter sorter = new TableRowSorter<TableModel>(model) {
@Override
public int convertRowIndexToModel(int index) {
int maxRow = super.getViewRowCount();
if (index >= maxRow) {
return index;
}
return super.convertRowIndexToModel(index);
}
@Override
public int convertRowIndexToView(int index) {
int maxRow = super.getModelRowCount();
if (index > maxRow) {
return index;
}
return super.convertRowIndexToView(index);
}
@Override
public int getViewRowCount() {
return super.getViewRowCount() + 1;
}
};
table.setRowSorter(sorter);
f.add(new JScrollPane(table), BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static List<Employee> createListEmployees() {
List<Employee> listEmployees = new ArrayList<>();
listEmployees.add(new Employee("Peter", "Manager", 40000));
listEmployees.add(new Employee("Paul", "Programmer", 25000));
listEmployees.add(new Employee("Mary", "Designer", 25000));
listEmployees.add(new Employee("Donald", "Leader", 30000));
listEmployees.add(new Employee("Tom", "Designer", 28000));
listEmployees.add(new Employee("Samantha", "Analyst", 50000));
listEmployees.add(new Employee("Jerome", "Programmer", 32000));
listEmployees.add(new Employee("Jonathon", "Developer", 29000));
listEmployees.add(new Employee("Kevin", "Programmer", 23000));
listEmployees.add(new Employee("Anthony", "Programmer", 23000));
listEmployees.add(new Employee("John", "Designer", 33000));
listEmployees.add(new Employee("David", "Developer", 28000));
listEmployees.add(new Employee("Harry", "Designer", 31000));
listEmployees.add(new Employee("Charles", "Programmer", 26000));
listEmployees.add(new Employee("Joseph", "Manager", 40000));
return listEmployees;
}
private static class EmployeeTableModel extends AbstractTableModel {
private static final int COLUMN_NUM = 0;
private static final int COLUMN_NAME = 1;
private static final int COLUMN_JOB = 2;
private static final int COLUMN_SALARY = 3;
private final String[] columnNames = {"No", "Name", "Job", "Salary"};
private final List<Employee> listEmployees;
public EmployeeTableModel(List<Employee> listEmployees) {
this.listEmployees = listEmployees;
int indexCount = 1;
for (Employee employee : listEmployees) {
employee.setIndex(indexCount++);
}
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return listEmployees.size();
}
@Override
public String getColumnName(int columnIndex) {
return columnNames[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return getValueAt(0, columnIndex).getClass();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (rowIndex == getRowCount()) {
switch (columnIndex) {
case COLUMN_NUM:
return 999_999_999;
case COLUMN_NAME:
return "Total";
case COLUMN_JOB:
return "Salary";
case COLUMN_SALARY:
return sum();
}
}
Employee employee = listEmployees.get(rowIndex);
switch (columnIndex) {
case COLUMN_NUM:
return employee.getIndex();
case COLUMN_NAME:
return employee.getName();
case COLUMN_JOB:
return employee.getJob();
case COLUMN_SALARY:
return employee.getSalary();
default:
throw new IllegalArgumentException("Invalid column index");
}
}
private int sum() {
int sum = 0;
for (int r = 0; r < getRowCount(); r++) {
sum += (int) getValueAt(r, COLUMN_SALARY);
}
return sum;
}
}
private static class Employee {
private int index;
private String name;
private String job;
private int salary;
public Employee(String name, String job, int salary) {
this.name = name;
this.job = job;
this.salary = salary;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public int getSalary() {
return salary;
}
public void setSalary(int age) {
this.salary = age;
}
}
private static class CurrencyFormatter extends DefaultTableCellRenderer {
private NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
@Override
public Component getTableCellRendererComponent(JTable jTable, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(jTable, value,
isSelected, hasFocus, row, column);
if (c instanceof JLabel && value instanceof Number) {
JLabel label = (JLabel) c;
label.setHorizontalAlignment(JLabel.RIGHT);
Number num = (Number) value;
String text = numberFormat.format(num);
label.setText(text);
}
return c;
}
}
}
Автор: trashgod
Размещён: 20.06.2016 01:25
Вопросы из категории :
- java В чем разница между int и Integer в Java и C #?
- java Как я могу определить IP моего маршрутизатора / шлюза в Java?
- java Каков наилучший способ проверки XML-файла по сравнению с XSD-файлом?
- java Как округлить результат целочисленного деления?
- java Преобразование списка <Integer> в список <String>
- swing Java Swing: отображение изображений внутри Jar
- swing Как реализовать перетаскиваемые вкладки с помощью Java Swing?
- swing Можно ли отобразить компоненты Swing в JSP?
- swing Как добавить ActionListener в JButton в Java
- swing "Всегда сверху" Windows с Java
- jtable Как вернуть фактические границы компонентов ячейки в JTable?
- jtable Настройка Java JTable Ширина столбца
- jtable Как обернуть строки в jtable ячейке?
- jtable Как сделать столбцы в JTable Invisible для Swing Java
- jtable Выбор нескольких строк JTable
- tablerowsorter Сортировать JTable, кроме последней строки
- tablerowsorter Как обработать синхронизацию RowSorter в JTables с RowHeader?
- tablerowsorter Попытка сохранить положение сортировщика после обновления таблицы
- tablerowsorter Получить столбец, который запускает RowSorterEvent
- tablerowsorter Как обновить таблицу (JTable) без изменения порядка, сделанного с помощью setAutoCreateRowSorter?