/[schmitzm]/branches/1.0-gt2-2.6/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
ViewVC logotype

Contents of /branches/1.0-gt2-2.6/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 325 - (show annotations)
Wed Aug 26 15:32:54 2009 UTC (15 years, 6 months ago) by mojays
File MIME type: text/plain
File size: 12781 byte(s)
imports organized
SCHMITZM-JMapPane converted
1 /*******************************************************************************
2 * Copyright (c) 2009 Martin O. J. Schmitz.
3 *
4 * This file is part of the SCHMITZM library - a collection of utility
5 * classes based on Java 1.6, focusing (not only) on Java Swing
6 * and the Geotools library.
7 *
8 * The SCHMITZM project is hosted at:
9 * http://wald.intevation.org/projects/schmitzm/
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 3
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License (license.txt)
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 * or try this link: http://www.gnu.org/licenses/lgpl.html
25 *
26 * Contributors:
27 * Martin O. J. Schmitz - initial API and implementation
28 * Stefan A. Krüger - additional utility classes
29 ******************************************************************************/
30 /**
31 Copyright 2008 Stefan Alfons Krüger
32
33 atlas-framework - This file is part of the Atlas Framework
34
35 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
36 This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
37 You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
38
39 Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
40 Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
41 Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
42 **/
43 package skrueger.geotools.selection;
44
45 import java.beans.PropertyChangeEvent;
46 import java.beans.PropertyChangeListener;
47 import java.util.Arrays;
48 import java.util.Collection;
49 import java.util.HashSet;
50 import java.util.Set;
51 import java.util.Vector;
52
53 import javax.swing.JTable;
54 import javax.swing.ListSelectionModel;
55 import javax.swing.event.ListSelectionListener;
56
57 import org.geotools.map.MapLayer;
58 import org.geotools.styling.FeatureTypeStyle;
59 import org.geotools.styling.Style;
60 import org.opengis.feature.simple.SimpleFeature;
61 import org.opengis.filter.identity.FeatureId;
62
63 import schmitzm.geotools.FilterUtil;
64 import schmitzm.geotools.gui.JMapPane;
65 import schmitzm.geotools.map.event.FeatureSelectedEvent;
66 import schmitzm.geotools.map.event.JMapPaneEvent;
67 import schmitzm.geotools.map.event.JMapPaneListener;
68 import schmitzm.geotools.styling.StylingUtil;
69 import schmitzm.lang.LangUtil;
70 import skrueger.geotools.MapPaneToolBar;
71 import skrueger.geotools.StyledLayerInterface;
72
73 /**
74 * This class keeps the selection of a (feature) {@link JTable} synchronized
75 * with the {@link StyledLayerSelectionModel} of a layer. This is done by
76 * implementing:
77 * <ul>
78 * <li>a {@link PropertyChangeListener} which listens to the
79 * {@link StyledLayerSelectionModel} and accordingly changes the {@link JTable}
80 * selection</li>
81 * <li>a {@link ListSelectionListener} which listens to the {@link JTable} and
82 * accordingly changes the {@link StyledLayerSelectionModel} selection</li>
83 * </ul>
84 * After creating, the instance of this synchronizer must be added as listener
85 * to both, the {@link StyledLayerSelectionModel} and the table's
86 * {@link ListSelectionModel}.
87 *
88 * @author <a href="mailto:[email protected]">Martin Schmitz</a>
89 * (University of Bonn/Germany)
90 */
91 public class FeatureMapLayerSelectionSynchronizer extends
92 StyledLayerSelectionModelSynchronizer<StyledFeatureLayerSelectionModel>
93 implements JMapPaneListener {
94 public static final String SELECTION_STYLING = "SELECTION";
95 /**
96 * Holds the {@link MapLayer} to keep synchronized with the layer selection
97 * model.
98 */
99 protected final MapLayer mapLayer;
100 protected final StyledLayerInterface<?> styledLayer;
101 protected final JMapPane mapPane;
102 private final MapPaneToolBar toolBar;
103
104 /**
105 * Creates a new synchronizer
106 *
107 * @param layerSelModel
108 * layer selection model to keep synchronized with the
109 * {@link MapLayer}
110 *
111 * @param mapLayer
112 * {@link MapLayer} to keep synchronized with.
113 */
114 public FeatureMapLayerSelectionSynchronizer(
115 StyledFeatureLayerSelectionModel layerSelModel,
116 StyledLayerInterface<?> styledLayer, MapLayer mapLayer,
117 JMapPane mapPane, MapPaneToolBar toolBar) {
118
119 super(layerSelModel);
120 this.styledLayer = styledLayer;
121
122 this.mapLayer = mapLayer;
123 this.mapPane = mapPane;
124 this.toolBar = toolBar;
125 }
126
127 /**
128 * Called by {@link StyledLayerSelectionModel} when a the selection on other
129 * selection components (map, chart, ...) has changed. When calling this
130 *
131 * method changes the {@link MapLayer} selection according to the
132 * {@link StyledLayerSelectionModel} selection.
133 *
134 * @param evt
135 * an event
136 */
137 @Override
138 public void propertyChange(PropertyChangeEvent evt) {
139
140 if (!isEnabled())
141 return;
142
143 if (!(evt instanceof StyledLayerSelectionEvent))
144 return;
145 StyledLayerSelectionEvent selEvt = (StyledLayerSelectionEvent) evt;
146 // Only react on own layer and ignore events invoked by
147 // this component itself
148 if (selEvt.getEmitter() != layerSelModel || selectionChangeCausedByMe)
149 return;
150 // Apply new selection on table (except this event is one of
151 // some more events)
152 Vector<String> newSelection = layerSelModel.getSelection();
153 if (newSelection == null)
154 return;
155
156 // Avoid event circles in valueChanged(..)
157 selectionChangeCausedByMe = true;
158
159 changeLayerStyle(newSelection);
160
161 // Danger of event circles in valueChanged(..) banned
162 selectionChangeCausedByMe = false;
163 }
164
165 /**
166 * Changes the Style of the {@link MapLayer} to reflect changes of the
167 * selection.
168 *
169 * @param newSelection
170 * A {@link Vector} of SimpleFeature-IDs that are selected.
171 */
172 private void changeLayerStyle(final Vector<String> newSelection) {
173 Style selectionMapStyle = null;
174 try {
175 if (newSelection.isEmpty()) {
176
177 selectionMapStyle = styledLayer.getStyle();
178 // LOGGER.debug("NO SELECTION .. set to original style directly");
179
180 } else {
181 LOGGER.debug("SELECTION .. change style");
182
183 // We take Style from the MapLayer that is displayed at the
184 // moment. We do not use the styledLayer.getStyle, because in
185 // the atlas, this always return the default style, but
186 // additional styles might be selected.
187 // Taking the style from the mapLayer indicated, that we have to
188 // remove any selection rules first.
189 Style originalStyle = mapLayer.getStyle();
190
191 // TODO The default style is not good here. We need
192 // .createSelectionStyle(normalStyle, geoObj);
193 selectionMapStyle = StylingUtil
194 .createSelectionStyle(styledLayer.getGeoObject());
195 // selectionMapStyle = StylingUtil
196 // .createDefaultStyle(styledLayer.getGeoObject());
197
198 selectionMapStyle.getFeatureTypeStyles()[0]
199 .setName(SELECTION_STYLING);
200
201 /**
202 *
203 * Add a Filter to the selectionMapStyle, so that it is only
204 * used on objects that are selected. <br/>
205 *
206 * Note 1:<br/>
207 * It is NEVER allowed to GeoTools extend Filter () { .. } (and write
208 * tests into the evaluate block). Especially for the
209 * ShapeFileRenderer, we may only use a geotools Filter.<br/>
210 *
211 * Note 2:<br/>
212 * The FilterUtil.FILTER_FAC2.id(fids) wants a set of FeatureId-Objects!
213 */
214
215 Set<FeatureId> fids = new HashSet<FeatureId>();
216 for (String fid : newSelection) {
217 fids.add(FilterUtil.FILTER_FAC2.featureId(fid));
218 }
219
220 selectionMapStyle.getFeatureTypeStyles()[0].getRules()[0]
221 .setFilter(FilterUtil.FILTER_FAC2.id(fids));
222
223 FeatureTypeStyle[] originalFeatureTypeStyles = originalStyle
224 .getFeatureTypeStyles();
225 FeatureTypeStyle[] newFeatureTypes;
226 if (originalFeatureTypeStyles[originalFeatureTypeStyles.length - 1]
227 .getName() != null
228 && originalFeatureTypeStyles[originalFeatureTypeStyles.length - 1]
229 .getName().equals(SELECTION_STYLING)) {
230 newFeatureTypes = Arrays.copyOf(originalFeatureTypeStyles,
231 originalFeatureTypeStyles.length - 1);
232 } else {
233 newFeatureTypes = originalFeatureTypeStyles;
234 }
235
236 // The last FTS is the selection FTS
237 newFeatureTypes = LangUtil.extendArray(newFeatureTypes,
238 selectionMapStyle.getFeatureTypeStyles());
239
240 selectionMapStyle.setFeatureTypeStyles(newFeatureTypes);
241
242 }
243
244 mapLayer.setStyle(selectionMapStyle);
245 mapPane.refresh();
246 } catch (Exception e) {
247 LOGGER.error("Error while trying to create a selection style", e);
248 }
249 }
250
251 /**
252 * Used to synchronize {@link FeatureSelectedEvent}s with the
253 * {@link StyledFeatureLayerSelectionModel}
254 */
255 @Override
256 public void performMapPaneEvent(JMapPaneEvent e) {
257
258 // Ignore event if it is caused by us or the synchronizer is disabled.
259 if (!isEnabled() || selectionChangeCausedByMe)
260 return;
261
262 if (!(e instanceof FeatureSelectedEvent)) {
263 // LOGGER.debug("Ignoring event " + e);
264 return;
265 }
266
267 /**
268 * Only listen to FeatureSelectedEvents if an appropriate tool is
269 * selected.
270 */
271 final int selectedTool = toolBar.getSelectedTool();
272 if (selectedTool != MapPaneToolBar.TOOL_SELECTION_ADD
273 && selectedTool != MapPaneToolBar.TOOL_SELECTION_REMOVE
274 && selectedTool != MapPaneToolBar.TOOL_SELECTION_SET) {
275 return;
276 }
277
278 // only listen to events directly coming from JMapPane
279 // selection (ignore selections from FilterDialog)
280 if (e.getSourceObject() != this.mapPane)
281 return;
282
283 FeatureSelectedEvent fse = (FeatureSelectedEvent) e;
284
285 /**
286 * Checking, that the FeatureSelectedEvent actually contains features
287 * from this layer
288 */
289 final String sourceID = fse.getSourceLayer().getTitle();
290 final String syncForID = mapLayer.getTitle();
291 if (sourceID != null && syncForID != null
292 && !sourceID.equals(syncForID)) {
293 LOGGER.debug("Ignoring a FeatureSelectedEvent from " + sourceID);
294 return;
295 }
296
297 LOGGER.debug("do event " + fse);
298
299 // Avoid event circles in propertyChange(..)
300 selectionChangeCausedByMe = true;
301
302 Collection<SimpleFeature> selectionResult = (Collection<SimpleFeature>) fse
303 .getSelectionResult();
304
305 // reset the selection of the DpLayerSelectionModel
306 // layerSelModel.setValueIsAdjusting(true);
307
308 if (selectedTool == MapPaneToolBar.TOOL_SELECTION_ADD) {
309 layerSelModel.setValueIsAdjusting(true);
310 for (SimpleFeature f : selectionResult) {
311 layerSelModel.addSelection(f.getID());
312 }
313 layerSelModel.setValueIsAdjusting(false);
314 } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_SET) {
315 layerSelModel.setValueIsAdjusting(true);
316 layerSelModel.clearSelection();
317
318 for (SimpleFeature f : selectionResult) {
319 layerSelModel.addSelection(f.getID());
320 }
321
322 LOGGER.debug("Setting selection to " + selectionResult.size());
323 layerSelModel.setValueIsAdjusting(false);
324 } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_REMOVE) {
325 layerSelModel.setValueIsAdjusting(true);
326 for (SimpleFeature f : selectionResult) {
327 layerSelModel.removeSelection(f.getID());
328 }
329 layerSelModel.setValueIsAdjusting(false);
330 }
331
332 // Show selected features in the map, which is not automatically done by
333 // the origin: FeatureSelectedEvent
334 changeLayerStyle(layerSelModel.getSelection());
335
336 // Danger of event circles in propertyChange(..) banned
337 selectionChangeCausedByMe = false;
338 }
339
340 }

Properties

Name Value
svn:eol-style native
svn:keywords Id
svn:mime-type text/plain

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26