source: josm/trunk/src/org/openstreetmap/josm/gui/widgets/FilterField.java@ 16438

Last change on this file since 16438 was 16438, checked in by simon04, 4 years ago

see #19251 - Java 8: use Stream

  • Property svn:eol-style set to native
File size: 3.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.widgets;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.Arrays;
7import java.util.List;
8import java.util.Objects;
9import java.util.regex.PatternSyntaxException;
10import java.util.stream.Collectors;
11
12import javax.swing.JTable;
13import javax.swing.RowFilter;
14import javax.swing.event.DocumentEvent;
15import javax.swing.event.DocumentListener;
16import javax.swing.table.AbstractTableModel;
17import javax.swing.table.TableModel;
18import javax.swing.table.TableRowSorter;
19
20import org.openstreetmap.josm.tools.Logging;
21import org.openstreetmap.josm.tools.Utils;
22
23/**
24 * Text field allowing to filter contents.
25 * @since 15116
26 */
27public class FilterField extends JosmTextField {
28
29 /**
30 * Constructs a new {@code TableFilterField}.
31 */
32 public FilterField() {
33 setToolTipText(tr("Enter a search expression"));
34 SelectAllOnFocusGainedDecorator.decorate(this);
35 }
36
37 /**
38 * Defines the filter behaviour.
39 */
40 @FunctionalInterface
41 public interface FilterBehaviour {
42 /**
43 * Filters a component according to the given filter expression.
44 * @param expr filter expression
45 */
46 void filter(String expr);
47 }
48
49 /**
50 * Enables filtering of given table/model.
51 * @param table table to filter
52 * @param model table model
53 * @return {@code this} for easy chaining
54 */
55 public FilterField filter(JTable table, AbstractTableModel model) {
56 return filter(new TableFilterBehaviour(table, model));
57 }
58
59 /**
60 * Enables generic filtering.
61 * @param behaviour filter behaviour
62 * @return {@code this} for easy chaining
63 */
64 public FilterField filter(FilterBehaviour behaviour) {
65 getDocument().addDocumentListener(new FilterFieldAdapter(behaviour));
66 return this;
67 }
68
69 private static class TableFilterBehaviour implements FilterBehaviour {
70 private final JTable table;
71 private final AbstractTableModel model;
72
73 TableFilterBehaviour(JTable table, AbstractTableModel model) {
74 this.table = Objects.requireNonNull(table, "table");
75 this.model = Objects.requireNonNull(model, "model");
76 Objects.requireNonNull(table.getRowSorter(), "table.rowSorter");
77 }
78
79 @Override
80 public void filter(String expr) {
81 try {
82 final TableRowSorter<? extends TableModel> sorter =
83 (TableRowSorter<? extends TableModel>) table.getRowSorter();
84 if (expr == null || expr.isEmpty()) {
85 sorter.setRowFilter(null);
86 } else {
87 expr = expr.replace("+", "\\+");
88 // split search string on whitespace, do case-insensitive AND search
89 List<RowFilter<Object, Object>> andFilters = Arrays.stream(expr.split("\\s+"))
90 .map(word -> RowFilter.regexFilter("(?i)" + word))
91 .collect(Collectors.toList());
92 sorter.setRowFilter(RowFilter.andFilter(andFilters));
93 }
94 model.fireTableDataChanged();
95 } catch (PatternSyntaxException | ClassCastException ex) {
96 Logging.warn(ex);
97 }
98 }
99 }
100
101 private class FilterFieldAdapter implements DocumentListener {
102 private final FilterBehaviour behaviour;
103
104 FilterFieldAdapter(FilterBehaviour behaviour) {
105 this.behaviour = Objects.requireNonNull(behaviour);
106 }
107
108 private void filter() {
109 behaviour.filter(Utils.strip(getText()));
110 }
111
112 @Override
113 public void changedUpdate(DocumentEvent e) {
114 filter();
115 }
116
117 @Override
118 public void insertUpdate(DocumentEvent e) {
119 filter();
120 }
121
122 @Override
123 public void removeUpdate(DocumentEvent e) {
124 filter();
125 }
126 }
127}
Note: See TracBrowser for help on using the repository browser.