Я пытаюсь создать фильтр строк для JTable, чтобы ограничить количество строк, отображаемых в таблице.Как работает JTable RowFilter?
Код RowFilter прост. Он преобразует номер модели строки к числу вида строки (в случае, если таблица отсортирована), а затем проверяет, если число вида строки меньше, что количество строк, которое будет отображаться в таблице:
RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>()
{
@Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry)
{
int modelRow = entry.getIdentifier();
int viewRow = table.convertRowIndexToView(modelRow);
return viewRow < numberOfRows;
}
};
Проблемы заключается в том, что номер строки модели не всегда преобразуется в разумный номер строки просмотра, поэтому слишком много строк включаются в фильтр. Для демонстрации выполнения кода ниже:
1) Выберите «1» из выпадающего списка, и вы получите выход как:
Change the Filter to: 1
m0 : v0
m1 : v0
m2 : v0
m3 : v0
m4 : v0
Этот вывод говорит мне, что все модели строки преобразовываются для просмотра строки 0. Так как 0 меньше значения фильтра 1, все строки включены в фильтр (что неверно).
Итак, вопрос в том, почему convertRowIndexToView(modelRow)
работает не так, как ожидалось?
2) Теперь выберите «2» из выпадающего списка, и вы получите выход, как:
Change the Filter to: 2
m0 : v0
m1 : v1
m2 : v2
m3 : v3
m4 : v4
Как вы можете увидеть модели строк теперь отображение для правильного просмотра строки, поэтому только 2 строки являются включенный в фильтр, который является правильным.
3) Теперь выберите «3» из выпадающего списка, и вы получите выход, как:
Change the Filter to: 3
m0 : v0
m1 : v1
m2 : v-1
m3 : v-1
m4 : v-1
В этом случае последние 3 модели строки преобразуются в -1, который я предполагаю, означает, что строка в настоящее время не отображается в таблице, что является правильным. Таким образом, в этом случае все 5 строк снова включаются в фильтр, который неверен, так как мы хотим только первого. 3.
Итак, вопрос в том, как сбросить фильтр, чтобы все строки модели отображались в исходную строку представления?
Я пытался использовать:
((TableRowSorter) table.getRowSorter()).setRowFilter(null);
((TableRowSorter) table.getRowSorter()).setRowFilter(filter);
, чтобы очистить фильтр, перед сбросом фильтра, но это дало те же результаты, как шаг 1. То есть, теперь все модели строк на карте, чтобы просмотреть строку 0 (так все 5 строк все еще отображаются).
Вот код теста:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class FilterSSCCE extends JPanel
{
private JTable table;
public FilterSSCCE()
{
setLayout(new BorderLayout());
JComboBox<Integer> comboBox = new JComboBox<Integer>();
comboBox.addItem(new Integer(1));
comboBox.addItem(new Integer(2));
comboBox.addItem(new Integer(3));
comboBox.addItem(new Integer(4));
comboBox.addItem(new Integer(5));
comboBox.setSelectedIndex(4);
comboBox.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
//System.out.println(table.convertRowIndexToView(4));
Integer value = (Integer)comboBox.getSelectedItem();
newFilter(value);
//System.out.println(table.convertRowIndexToView(4));
}
});
add(comboBox, BorderLayout.NORTH);
table = new JTable(5, 1);
for (int i = 0; i < table.getRowCount(); i++)
table.setValueAt(String.valueOf(i+1), i, 0);
table.setAutoCreateRowSorter(true);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane, BorderLayout.CENTER);
}
private void newFilter(int numberOfRows)
{
System.out.println("Change the Filter to: " + numberOfRows);
RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>()
{
@Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry)
{
int modelRow = entry.getIdentifier();
int viewRow = table.convertRowIndexToView(modelRow);
System.out.println("m" + modelRow + " : v" + viewRow);
return viewRow < numberOfRows;
}
};
((TableRowSorter) table.getRowSorter()).setRowFilter(filter);
}
private static void createAndShowGUI()
{
JPanel panel = new JPanel();
JFrame frame = new JFrame("FilterSSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new FilterSSCCE());
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Любая идея, как создать фильтр строк для отображения первых «N» строки?
О да, еще один расстраивающий пункт. Если вы раскомментируете две строки System.out .. в методе actionPeformed(), когда вы выберете 1 из поля со списком, вы заметите, что в обоих случаях индекс модели 4 преобразуется в индекс 4, и эти два выхода зажаты вокруг неверная модель для просмотра конверсий ???
Edit:
основе MadProgrammers внушения я попробовал:
//((TableRowSorter) table.getRowSorter()).setRowFilter(filter);
TableRowSorter sorter = new TableRowSorter();
table.setRowSorter(sorter);
sorter.setRowFilter(filter);
sorter.sort();
Теперь я ничего не получаю в таблице.
«Guess», что это «несколько раз», работающих с предварительно очищенным набором данных. .. – MadProgrammer
Я закончил создание нового 'TableRowSorter', применив это к' JTable', задав 'rowFilter' этому сортировщику, а затем вызвал' sort' на 'TableRowSorter' ...: P – MadProgrammer
@MadProgrammer,'. ... предварительно отфильтрованный набор данных «да», и я думаю, вопрос в том, почему? Я думаю, что большинство фильтров основаны на фактических данных в TableModel, так что это не проблема, поскольку отображение индексов будет переделано после фильтрации? «Я закончил создание ...» - не работал для меня. Думаю, я сделал что-то еще неправильно? – camickr