package skrueger.swing; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Timer; import java.util.TimerTask; import java.util.regex.Pattern; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.RowFilter; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableRowSorter; /** * Connects a {@link JTextField} with a {@link JTable} to filter the data. The * column it should filter are given as indices on construction. * */ public class FilterTableKeyListener extends KeyAdapter { private final JTable table; private final int[] indices; private final JTextField jTextField; private Timer setRowFilterTimer; /** * Collects key events for 300ms, The constructor adds itself the the * {@link JTextField}! * * @param table * @param jTextField * @param indices */ public FilterTableKeyListener(JTable table, JTextField jTextField, int... indices) { this(table, 300, jTextField, indices); } /** * The constructor adds itself the the {@link JTextField}! * * @param table * @param jTextField * @param waitToUpdateGuiMs * ms to wait until the table rowSorter is changed. * @param indices */ public FilterTableKeyListener(JTable table, long waitToUpdateGuiMs, JTextField jTextField, int... indices) { this.table = table; this.jTextField = jTextField; this.indices = indices; jTextField.addKeyListener(this); } @Override public void keyReleased(KeyEvent e) { String text = jTextField.getText(); newFilterForTable( (TableRowSorter) table.getRowSorter(), text, indices); } /** * When a key is released, filter for the table is updated */ private void newFilterForTable( final TableRowSorter sorter, String text, int... indices) { // System.out.println("\n" + text); String filter = ""; String[] split = text.trim().split("\\s"); for (String s : split) { if (s.trim().isEmpty()) continue; s = Pattern.quote(s); s = s.substring(2, s.length() - 2); filter += "|.*" + s + ".*"; } if (filter.length() > 0) filter = filter.substring(1); // If current expression doesn't parse, don't update. try { // System.out.println(filter); final RowFilter rf = RowFilter .regexFilter("(?i)" + filter, indices); if (setRowFilterTimer != null) setRowFilterTimer.cancel(); setRowFilterTimer = new Timer("Set rowFilter for JTable"); setRowFilterTimer.schedule(new TimerTask() { @Override public void run() { sorter.setRowFilter(rf); } }, 300); return; } catch (java.util.regex.PatternSyntaxException e) { return; } // sorter.setRowFilter(null); } }