Reputation: 205
I want to filter a JTable
exactly by a string. My filter is like this:
Pattern.quote(textfield.getText());
But, when I filter on "G" I get also all lines of the JTable
with the entry "KG". I just want the rows with the entry "G". I looked at How to Use Tables: Sorting and Filtering, but I still don't see how.
Upvotes: 2
Views: 3575
Reputation: 9808
Another example: RowFilter#regexFilter(...) (Java Platform SE 8)
The returned filter uses Matcher.find() to test for inclusion. To test for exact matches use the characters '^' and '$' to match the beginning and end of the string respectively. For example, "^foo$" includes only rows whose string is exactly "foo" and not, for example, "food". See Pattern for a complete description of the supported regular-expression constructs.
import java.awt.*;
import java.awt.event.*;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.table.*;
public class JTableFilterDemo2 {
public JComponent makeUI() {
String[] columnNames = {"Item"};
Object[][] data = {{"G"}, {"KG"}, {"XG"}, {"Y"}, {"Z"}, {"*G"}};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
TableRowSorter<TableModel> sorter = new TableRowSorter<>(model);
JTable table = new JTable(model);
table.setRowSorter(sorter);
JTextField textField = new JTextField("G");
JButton button = new JButton("Toggle filter");
button.addActionListener(e -> {
if (sorter.getRowFilter() != null) {
sorter.setRowFilter(null);
} else {
String text = Pattern.quote(textField.getText());
String regex = String.format("^%s$", text);
sorter.setRowFilter(RowFilter.regexFilter(regex));
}
});
JPanel p = new JPanel(new BorderLayout());
p.add(textField, BorderLayout.NORTH);
p.add(new JScrollPane(table));
p.add(button, BorderLayout.SOUTH);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new JTableFilterDemo2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
Upvotes: 2
Reputation: 205785
As shown in How to Use Tables: Sorting and Filtering, use a RowFilter
to "to filter out entries from the model so that they are not shown in the view." To match "G" exactly in column zero, your filter might look like this:
final RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>() {
@Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
return "G".equals(entry.getStringValue(0));
}
};
Based on this example, pressing the button in the example below toggles the filter.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
/** https://stackoverflow.com/a/37114447/230513 */
public class JTableFilterDemo {
private static TableRowSorter<TableModel> sorter;
private Object[][] data = {{"G"}, {"KG"}, {"XG"}, {"Y"}, {"Z"}};
private String columnNames[] = {"Item"};
private TableModel model = new DefaultTableModel(data, columnNames) {
@Override
public Class<?> getColumnClass(int column) {
return String.class;
}
};
private JTable table = new JTable(model);
public JTableFilterDemo() {
table.setPreferredScrollableViewportSize(table.getPreferredSize());
sorter = new TableRowSorter<>(model);
table.setRowSorter(sorter);
final RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>() {
@Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
return "G".equals(entry.getStringValue(0));
}
};
JScrollPane scrollPane = new JScrollPane(table);
JFrame frame = new JFrame("Filtering Table");
frame.add(new JButton(new AbstractAction("Toggle filter") {
@Override
public void actionPerformed(ActionEvent e) {
if (sorter.getRowFilter() != null) {
sorter.setRowFilter(null);
} else {
sorter.setRowFilter(filter);
}
}
}), BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scrollPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JTableFilterDemo jtfd = new JTableFilterDemo();
}
});
}
}
Upvotes: 3