I have a JTable and I want to show the visible record count in a JLabel next to it. So whenever I filter on the JTable or do anything that changes the visible row count, I want the JLabel to be updated with the new record count? What kind of listener do I implement to capture these events?
Table#getRowCount()
actually returns the number of rows in the table view. So you could just call that method in the listener of what ever event causes the row count to change. Unfortunately, I'm unaware of any listener that listener for changes in the table row count change
The most direct listener (for your filter case) you could probably use a RowSorterListener
which is "notified of changes to a RowSorter". You could do something like:
private void addListenerToSorter(RowSorter rowSorter,
final JTable table,
final JLabel rowCountLabel) {
rowSorter.addRowSorterListener(new RowSorterListener() {
@Override
public void sorterChanged(RowSorterEvent e) {
int newRowCount = table.getRowCount();
rowCountLabel.setText("Number of view rows: " + newRowCount);
}
});
}
Note the RowSorterEvent
also allows you to get the previous row count, if you're interested in that.
Here's a complete example:
import java.awt.BorderLayout;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TestTableSortFilter {
private JTable jTable = new JTable(createTableModel());
private JLabel rowCountLabel = new JLabel();
private TableRowSorter<TableModel> rowSorter
= new TableRowSorter<>(jTable.getModel());
private JTextField jtfFilter = new JTextField();
private JButton jbtFilter = new JButton("Filter");
public TestTableSortFilter() {
jTable.setRowSorter(rowSorter);
addListenerToSorter(rowSorter, jTable, rowCountLabel);
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JLabel("Specify a number to match:"),
BorderLayout.LINE_START);
panel.add(jtfFilter, BorderLayout.CENTER);
panel.add(rowCountLabel, BorderLayout.PAGE_END);
rowCountLabel.setText("Number of view rows: " + jTable.getRowCount());
jtfFilter.getDocument().addDocumentListener(new DocumentListener(){
@Override
public void insertUpdate(DocumentEvent e) { sortRows(); }
@Override
public void removeUpdate(DocumentEvent e) { sortRows(); }
@Override
public void changedUpdate(DocumentEvent e) {}
private void sortRows() {
String text = jtfFilter.getText();
if (text.trim().length() == 0) {
rowSorter.setRowFilter(null);
} else {
rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
}
}
});
JFrame frame = new JFrame();
frame.add(panel, BorderLayout.PAGE_END);
frame.add(new JScrollPane(jTable), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private TableModel createTableModel() {
String[] cols = {"col1", "col2", "col3", "col4"};
DefaultTableModel model = new DefaultTableModel(cols, 0);
int value = 0;
for (int i = 0; i < 100; i++) {
Vector row = new Vector();
for (int j = 0; j < cols.length; j++) {
row.add(value);
value++;
}
model.addRow(row);
}
return model;
}
private void addListenerToSorter(RowSorter rowSorter,
final JTable table,
final JLabel rowCountLabel) {
rowSorter.addRowSorterListener(new RowSorterListener() {
@Override
public void sorterChanged(RowSorterEvent e) {
int newRowCount = table.getRowCount();
rowCountLabel.setText("Number of view rows: " + newRowCount);
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new TestTableSortFilter();
}
});
}
}