source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/FilterDialog.java@ 4077

Last change on this file since 4077 was 4072, checked in by jttt, 13 years ago

Fix #6301 Check for null mandatory in TableCellRenderer.getTableCellRendererComponent

  • Property svn:eol-style set to native
File size: 11.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.BorderLayout;
8import java.awt.Component;
9import java.awt.Graphics2D;
10import java.awt.event.ActionEvent;
11import java.awt.event.ActionListener;
12import java.awt.event.KeyEvent;
13import java.awt.event.MouseEvent;
14import java.util.Collection;
15import java.util.HashSet;
16import java.util.Set;
17import java.util.Stack;
18
19import javax.swing.JCheckBox;
20import javax.swing.JPanel;
21import javax.swing.JScrollPane;
22import javax.swing.JTable;
23import javax.swing.ListSelectionModel;
24import javax.swing.SwingUtilities;
25import javax.swing.table.DefaultTableCellRenderer;
26import javax.swing.table.JTableHeader;
27import javax.swing.table.TableCellRenderer;
28
29import org.openstreetmap.josm.Main;
30import org.openstreetmap.josm.actions.search.SearchAction;
31import org.openstreetmap.josm.data.osm.Filter;
32import org.openstreetmap.josm.data.osm.OsmPrimitive;
33import org.openstreetmap.josm.data.osm.Relation;
34import org.openstreetmap.josm.data.osm.RelationMember;
35import org.openstreetmap.josm.data.osm.Way;
36import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
37import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
38import org.openstreetmap.josm.data.osm.event.DataSetListener;
39import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
40import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
41import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
42import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
43import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
44import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
45import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
46import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
47import org.openstreetmap.josm.gui.SideButton;
48import org.openstreetmap.josm.tools.Shortcut;
49
50/**
51 *
52 * @author Petr_Dlouhý
53 */
54public class FilterDialog extends ToggleDialog implements DataSetListener {
55
56 private JTable userTable;
57 private FilterTableModel filterModel = new FilterTableModel();
58 private SideButton addButton;
59 private SideButton editButton;
60 private SideButton deleteButton;
61 private SideButton upButton;
62 private SideButton downButton;
63
64
65 public FilterDialog(){
66 super(tr("Filter"), "filter", tr("Filter objects and hide/disable them."),
67 Shortcut.registerShortcut("subwindow:filter", tr("Toggle: {0}", tr("Filter")), KeyEvent.VK_F, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 162);
68 build();
69 }
70
71 @Override
72 public void showNotify() {
73 DatasetEventManager.getInstance().addDatasetListener(this, FireMode.IN_EDT_CONSOLIDATED);
74 filterModel.executeFilters();
75 }
76
77 @Override
78 public void hideNotify() {
79 DatasetEventManager.getInstance().removeDatasetListener(this);
80 filterModel.clearFilterFlags();
81 Main.map.mapView.repaint();
82 }
83
84 protected JPanel buildButtonRow() {
85 JPanel pnl = getButtonPanel(5);
86
87 addButton = new SideButton(marktr("Add"), "add", "SelectionList", tr("Add filter."),
88 new ActionListener(){
89 public void actionPerformed(ActionEvent evt){
90 Filter filter = (Filter)SearchAction.showSearchDialog(new Filter());
91 if(filter != null){
92 filterModel.addFilter(filter);
93 }
94 }
95 });
96 pnl.add(addButton);
97
98 editButton = new SideButton(marktr("Edit"), "edit", "SelectionList", tr("Edit filter."),
99 new ActionListener(){
100 public void actionPerformed(ActionEvent evt){
101 int index = userTable.getSelectionModel().getMinSelectionIndex();
102 if(index < 0) return;
103 Filter f = filterModel.getFilter(index);
104 Filter filter = (Filter)SearchAction.showSearchDialog(f);
105 if(filter != null){
106 filterModel.setFilter(index, filter);
107 }
108 }
109 });
110 pnl.add(editButton);
111
112 deleteButton = new SideButton(marktr("Delete"), "delete", "SelectionList", tr("Delete filter."),
113 new ActionListener(){
114 public void actionPerformed(ActionEvent evt){
115 int index = userTable.getSelectionModel().getMinSelectionIndex();
116 if(index < 0) return;
117 filterModel.removeFilter(index);
118 }
119 });
120 pnl.add(deleteButton);
121
122 upButton = new SideButton(marktr("Up"), "up", "SelectionList", tr("Move filter up."),
123 new ActionListener(){
124 public void actionPerformed(ActionEvent evt){
125 int index = userTable.getSelectionModel().getMinSelectionIndex();
126 if(index < 0) return;
127 filterModel.moveUpFilter(index);
128 userTable.getSelectionModel().setSelectionInterval(index-1, index-1);
129 }
130 });
131 pnl.add(upButton);
132
133 downButton = new SideButton(marktr("Down"), "down", "SelectionList", tr("Move filter down."),
134 new ActionListener(){
135 public void actionPerformed(ActionEvent evt){
136 int index = userTable.getSelectionModel().getMinSelectionIndex();
137 if(index < 0) return;
138 filterModel.moveDownFilter(index);
139 userTable.getSelectionModel().setSelectionInterval(index+1, index+1);
140 }
141 });
142 pnl.add(downButton);
143 return pnl;
144 }
145
146 protected String[] columnToolTips = {
147 tr("Enable filter"),
148 tr("Hide elements"),
149 null,
150 tr("Inverse filter"),
151 tr("Filter mode")
152 };
153
154 protected void build() {
155 JPanel pnl = new JPanel();
156 pnl.setLayout(new BorderLayout());
157 userTable = new JTable(filterModel){
158 @Override
159 protected JTableHeader createDefaultTableHeader() {
160 return new JTableHeader(columnModel) {
161 @Override
162 public String getToolTipText(MouseEvent e) {
163 java.awt.Point p = e.getPoint();
164 int index = columnModel.getColumnIndexAtX(p.x);
165 int realIndex = columnModel.getColumn(index).getModelIndex();
166 return columnToolTips[realIndex];
167 }
168 };
169 }
170 };
171
172 userTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
173
174 userTable.getColumnModel().getColumn(0).setMaxWidth(1);
175 userTable.getColumnModel().getColumn(1).setMaxWidth(1);
176 userTable.getColumnModel().getColumn(3).setMaxWidth(1);
177 userTable.getColumnModel().getColumn(4).setMaxWidth(1);
178
179 userTable.getColumnModel().getColumn(0).setResizable(false);
180 userTable.getColumnModel().getColumn(1).setResizable(false);
181 userTable.getColumnModel().getColumn(3).setResizable(false);
182 userTable.getColumnModel().getColumn(4).setResizable(false);
183
184 userTable.setDefaultRenderer(Boolean.class, new BooleanRenderer());
185 userTable.setDefaultRenderer(String.class, new StringRenderer());
186
187 pnl.add(new JScrollPane(userTable), BorderLayout.CENTER);
188
189 // -- the button row
190 pnl.add(buildButtonRow(), BorderLayout.SOUTH);
191 /*userTable.addMouseListener(new DoubleClickAdapter());*/
192 add(pnl, BorderLayout.CENTER);
193 }
194
195 static class StringRenderer extends DefaultTableCellRenderer {
196 @Override
197 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int column) {
198 FilterTableModel model = (FilterTableModel)table.getModel();
199 Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
200 cell.setEnabled(model.isCellEnabled(row, column));
201 return cell;
202 }
203 }
204
205 static class BooleanRenderer extends JCheckBox implements TableCellRenderer {
206 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int column) {
207 FilterTableModel model = (FilterTableModel)table.getModel();
208 setSelected(value != null && (Boolean)value);
209 setEnabled(model.isCellEnabled(row, column));
210 setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
211 return this;
212 }
213 }
214
215 public void updateDialogHeader() {
216 SwingUtilities.invokeLater(new Runnable() {
217 public void run() {
218 setTitle(tr("Filter Hidden:{0} Disabled:{1}", filterModel.disabledAndHiddenCount, filterModel.disabledCount));
219 }
220 });
221 }
222
223 public void drawOSDText(Graphics2D g) {
224 filterModel.drawOSDText(g);
225 }
226
227 /**
228 *
229 * @param primitive
230 * @return List of primitives whose filtering can be affected by change in primitive
231 */
232 private Collection<OsmPrimitive> getAffectedPrimitives(Collection<? extends OsmPrimitive> primitives) {
233 // Filters can use nested parent/child expression so complete tree is necessary
234 Set<OsmPrimitive> result = new HashSet<OsmPrimitive>();
235 Stack<OsmPrimitive> stack = new Stack<OsmPrimitive>();
236 stack.addAll(primitives);
237
238 while (!stack.isEmpty()) {
239 OsmPrimitive p = stack.pop();
240
241 if (result.contains(p)) {
242 continue;
243 }
244
245 result.add(p);
246
247 if (p instanceof Way) {
248 for (OsmPrimitive n: ((Way)p).getNodes()) {
249 stack.push(n);
250 }
251 } else if (p instanceof Relation) {
252 for (RelationMember rm: ((Relation)p).getMembers()) {
253 stack.push(rm.getMember());
254 }
255 }
256
257 for (OsmPrimitive ref: p.getReferrers()) {
258 stack.push(ref);
259 }
260 }
261
262 return result;
263 }
264
265 public void dataChanged(DataChangedEvent event) {
266 filterModel.executeFilters();
267 }
268
269 public void nodeMoved(NodeMovedEvent event) {
270 // Do nothing
271 }
272
273 public void otherDatasetChange(AbstractDatasetChangedEvent event) {
274 filterModel.executeFilters();
275 }
276
277 public void primtivesAdded(PrimitivesAddedEvent event) {
278 filterModel.executeFilters(event.getPrimitives());
279 }
280
281 public void primtivesRemoved(PrimitivesRemovedEvent event) {
282 filterModel.executeFilters();
283 }
284
285 public void relationMembersChanged(RelationMembersChangedEvent event) {
286 filterModel.executeFilters(getAffectedPrimitives(event.getPrimitives()));
287 }
288
289 public void tagsChanged(TagsChangedEvent event) {
290 filterModel.executeFilters(getAffectedPrimitives(event.getPrimitives()));
291 }
292
293 public void wayNodesChanged(WayNodesChangedEvent event) {
294 filterModel.executeFilters(getAffectedPrimitives(event.getPrimitives()));
295 }
296}
Note: See TracBrowser for help on using the repository browser.