/[schmitzm]/trunk/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
ViewVC logotype

Annotation of /trunk/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 409 - (hide annotations)
Fri Sep 18 15:00:29 2009 UTC (15 years, 5 months ago) by alfonx
Original Path: branches/1.0-gt2-2.6/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
File MIME type: text/plain
File size: 12938 byte(s)
* First start of rewriting of AtlasStyler GUI for GT2.6 and Miglayout.
* Fix for Schmitzm so that the FeatureMapLayerSelectionSynchronizer works correctly again.
1 alfonx 244 /*******************************************************************************
2     * Copyright (c) 2009 Martin O. J. Schmitz.
3     *
4     * This file is part of the SCHMITZM library - a collection of utility
5 alfonx 256 * classes based on Java 1.6, focusing (not only) on Java Swing
6 alfonx 244 * 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 alfonx 97 /**
31     Copyright 2008 Stefan Alfons Krüger
32 alfonx 409
33 alfonx 97 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 alfonx 123 import java.util.Arrays;
48 alfonx 158 import java.util.HashSet;
49 alfonx 409 import java.util.Iterator;
50 alfonx 158 import java.util.Set;
51 alfonx 97 import java.util.Vector;
52    
53     import javax.swing.JTable;
54     import javax.swing.ListSelectionModel;
55     import javax.swing.event.ListSelectionListener;
56    
57 alfonx 409 import org.geotools.feature.FeatureIterator;
58 alfonx 97 import org.geotools.map.MapLayer;
59 alfonx 123 import org.geotools.styling.FeatureTypeStyle;
60 alfonx 97 import org.geotools.styling.Style;
61 mojays 325 import org.opengis.feature.simple.SimpleFeature;
62 alfonx 158 import org.opengis.filter.identity.FeatureId;
63 alfonx 97
64 alfonx 158 import schmitzm.geotools.FilterUtil;
65 alfonx 409 import schmitzm.geotools.feature.PipedFeatureIterator;
66 alfonx 97 import schmitzm.geotools.gui.JMapPane;
67     import schmitzm.geotools.map.event.FeatureSelectedEvent;
68     import schmitzm.geotools.map.event.JMapPaneEvent;
69     import schmitzm.geotools.map.event.JMapPaneListener;
70     import schmitzm.geotools.styling.StylingUtil;
71 alfonx 104 import schmitzm.lang.LangUtil;
72 alfonx 111 import skrueger.geotools.MapPaneToolBar;
73 alfonx 224 import skrueger.geotools.StyledLayerInterface;
74 alfonx 97
75     /**
76     * This class keeps the selection of a (feature) {@link JTable} synchronized
77     * with the {@link StyledLayerSelectionModel} of a layer. This is done by
78     * implementing:
79     * <ul>
80     * <li>a {@link PropertyChangeListener} which listens to the
81     * {@link StyledLayerSelectionModel} and accordingly changes the {@link JTable}
82     * selection</li>
83     * <li>a {@link ListSelectionListener} which listens to the {@link JTable} and
84     * accordingly changes the {@link StyledLayerSelectionModel} selection</li>
85     * </ul>
86     * After creating, the instance of this synchronizer must be added as listener
87     * to both, the {@link StyledLayerSelectionModel} and the table's
88     * {@link ListSelectionModel}.
89     *
90     * @author <a href="mailto:[email protected]">Martin Schmitz</a>
91     * (University of Bonn/Germany)
92     */
93     public class FeatureMapLayerSelectionSynchronizer extends
94 alfonx 106 StyledLayerSelectionModelSynchronizer<StyledFeatureLayerSelectionModel>
95     implements JMapPaneListener {
96 alfonx 111 public static final String SELECTION_STYLING = "SELECTION";
97 alfonx 97 /**
98     * Holds the {@link MapLayer} to keep synchronized with the layer selection
99     * model.
100     */
101     protected final MapLayer mapLayer;
102 alfonx 224 protected final StyledLayerInterface<?> styledLayer;
103 alfonx 97 protected final JMapPane mapPane;
104 alfonx 111 private final MapPaneToolBar toolBar;
105 alfonx 97
106     /**
107     * Creates a new synchronizer
108     *
109     * @param layerSelModel
110     * layer selection model to keep synchronized with the
111     * {@link MapLayer}
112     *
113     * @param mapLayer
114     * {@link MapLayer} to keep synchronized with.
115     */
116     public FeatureMapLayerSelectionSynchronizer(
117     StyledFeatureLayerSelectionModel layerSelModel,
118 alfonx 224 StyledLayerInterface<?> styledLayer, MapLayer mapLayer,
119 alfonx 111 JMapPane mapPane, MapPaneToolBar toolBar) {
120 alfonx 97
121     super(layerSelModel);
122 alfonx 224 this.styledLayer = styledLayer;
123 alfonx 97
124     this.mapLayer = mapLayer;
125     this.mapPane = mapPane;
126 alfonx 111 this.toolBar = toolBar;
127 alfonx 97 }
128    
129     /**
130     * Called by {@link StyledLayerSelectionModel} when a the selection on other
131     * selection components (map, chart, ...) has changed. When calling this
132     *
133     * method changes the {@link MapLayer} selection according to the
134     * {@link StyledLayerSelectionModel} selection.
135     *
136     * @param evt
137     * an event
138     */
139     @Override
140     public void propertyChange(PropertyChangeEvent evt) {
141 alfonx 151
142     if (!isEnabled())
143     return;
144    
145 alfonx 97 if (!(evt instanceof StyledLayerSelectionEvent))
146     return;
147     StyledLayerSelectionEvent selEvt = (StyledLayerSelectionEvent) evt;
148     // Only react on own layer and ignore events invoked by
149     // this component itself
150     if (selEvt.getEmitter() != layerSelModel || selectionChangeCausedByMe)
151     return;
152     // Apply new selection on table (except this event is one of
153     // some more events)
154 alfonx 111 Vector<String> newSelection = layerSelModel.getSelection();
155 alfonx 97 if (newSelection == null)
156     return;
157    
158     // Avoid event circles in valueChanged(..)
159     selectionChangeCausedByMe = true;
160    
161     changeLayerStyle(newSelection);
162    
163     // Danger of event circles in valueChanged(..) banned
164     selectionChangeCausedByMe = false;
165     }
166    
167 alfonx 151 /**
168     * Changes the Style of the {@link MapLayer} to reflect changes of the
169     * selection.
170     *
171     * @param newSelection
172 alfonx 318 * A {@link Vector} of SimpleFeature-IDs that are selected.
173 alfonx 151 */
174 alfonx 111 private void changeLayerStyle(final Vector<String> newSelection) {
175 alfonx 97 Style selectionMapStyle = null;
176     try {
177     if (newSelection.isEmpty()) {
178    
179 alfonx 224 selectionMapStyle = styledLayer.getStyle();
180 alfonx 151 // LOGGER.debug("NO SELECTION .. set to original style directly");
181 alfonx 106
182 alfonx 97 } else {
183 alfonx 100 LOGGER.debug("SELECTION .. change style");
184 alfonx 106
185 alfonx 123 // We take Style from the MapLayer that is displayed at the
186 alfonx 224 // moment. We do not use the styledLayer.getStyle, because in
187 alfonx 123 // the atlas, this always return the default style, but
188 alfonx 224 // additional styles might be selected.
189 alfonx 123 // Taking the style from the mapLayer indicated, that we have to
190 alfonx 125 // remove any selection rules first.
191 alfonx 123 Style originalStyle = mapLayer.getStyle();
192 alfonx 101
193 alfonx 123 // TODO The default style is not good here. We need
194     // .createSelectionStyle(normalStyle, geoObj);
195 alfonx 107 selectionMapStyle = StylingUtil
196 alfonx 224 .createSelectionStyle(styledLayer.getGeoObject());
197 alfonx 151 // selectionMapStyle = StylingUtil
198 alfonx 224 // .createDefaultStyle(styledLayer.getGeoObject());
199 alfonx 106
200 alfonx 123 selectionMapStyle.getFeatureTypeStyles()[0]
201     .setName(SELECTION_STYLING);
202    
203 alfonx 158 /**
204     *
205     * Add a Filter to the selectionMapStyle, so that it is only
206     * used on objects that are selected. <br/>
207     *
208     * Note 1:<br/>
209 alfonx 409 * It is NEVER allowed to GeoTools extend Filter () { .. } (and
210     * write tests into the evaluate block). Especially for the
211 alfonx 158 * ShapeFileRenderer, we may only use a geotools Filter.<br/>
212     *
213     * Note 2:<br/>
214 alfonx 409 * The FilterUtil.FILTER_FAC2.id(fids) wants a set of
215     * FeatureId-Objects!
216 alfonx 158 */
217 alfonx 106
218 alfonx 158 Set<FeatureId> fids = new HashSet<FeatureId>();
219     for (String fid : newSelection) {
220     fids.add(FilterUtil.FILTER_FAC2.featureId(fid));
221     }
222 alfonx 106
223 alfonx 158 selectionMapStyle.getFeatureTypeStyles()[0].getRules()[0]
224     .setFilter(FilterUtil.FILTER_FAC2.id(fids));
225 alfonx 106
226 alfonx 125 FeatureTypeStyle[] originalFeatureTypeStyles = originalStyle
227     .getFeatureTypeStyles();
228     FeatureTypeStyle[] newFeatureTypes;
229     if (originalFeatureTypeStyles[originalFeatureTypeStyles.length - 1]
230     .getName() != null
231     && originalFeatureTypeStyles[originalFeatureTypeStyles.length - 1]
232     .getName().equals(SELECTION_STYLING)) {
233     newFeatureTypes = Arrays.copyOf(originalFeatureTypeStyles,
234     originalFeatureTypeStyles.length - 1);
235 alfonx 123 } else {
236     newFeatureTypes = originalFeatureTypeStyles;
237     }
238 alfonx 151
239 alfonx 123 // The last FTS is the selection FTS
240 alfonx 125 newFeatureTypes = LangUtil.extendArray(newFeatureTypes,
241     selectionMapStyle.getFeatureTypeStyles());
242    
243 alfonx 123 selectionMapStyle.setFeatureTypeStyles(newFeatureTypes);
244 alfonx 106
245 alfonx 97 }
246    
247     mapLayer.setStyle(selectionMapStyle);
248     mapPane.refresh();
249     } catch (Exception e) {
250     LOGGER.error("Error while trying to create a selection style", e);
251     }
252     }
253    
254 alfonx 151 /**
255     * Used to synchronize {@link FeatureSelectedEvent}s with the
256     * {@link StyledFeatureLayerSelectionModel}
257     */
258 alfonx 97 @Override
259     public void performMapPaneEvent(JMapPaneEvent e) {
260 alfonx 106
261 alfonx 151 // Ignore event if it is caused by us or the synchronizer is disabled.
262     if (!isEnabled() || selectionChangeCausedByMe)
263     return;
264    
265     if (!(e instanceof FeatureSelectedEvent)) {
266     // LOGGER.debug("Ignoring event " + e);
267     return;
268     }
269    
270 alfonx 111 /**
271 alfonx 151 * Only listen to FeatureSelectedEvents if an appropriate tool is
272 alfonx 111 * selected.
273     */
274     final int selectedTool = toolBar.getSelectedTool();
275     if (selectedTool != MapPaneToolBar.TOOL_SELECTION_ADD
276     && selectedTool != MapPaneToolBar.TOOL_SELECTION_REMOVE
277     && selectedTool != MapPaneToolBar.TOOL_SELECTION_SET) {
278     return;
279     }
280    
281 mojays 109 // only listen to events directly coming from JMapPane
282     // selection (ignore selections from FilterDialog)
283 alfonx 111 if (e.getSourceObject() != this.mapPane)
284     return;
285    
286 alfonx 97 FeatureSelectedEvent fse = (FeatureSelectedEvent) e;
287    
288 alfonx 151 /**
289 alfonx 158 * Checking, that the FeatureSelectedEvent actually contains features
290     * from this layer
291 alfonx 151 */
292     final String sourceID = fse.getSourceLayer().getTitle();
293     final String syncForID = mapLayer.getTitle();
294     if (sourceID != null && syncForID != null
295 alfonx 158 && !sourceID.equals(syncForID)) {
296     LOGGER.debug("Ignoring a FeatureSelectedEvent from " + sourceID);
297 alfonx 97 return;
298 alfonx 151 }
299 alfonx 97
300 alfonx 151 LOGGER.debug("do event " + fse);
301 alfonx 111
302 alfonx 97 // Avoid event circles in propertyChange(..)
303     selectionChangeCausedByMe = true;
304    
305 alfonx 409 Iterator<SimpleFeature> fi = fse.getSelectionResult().iterator();
306 alfonx 97
307 alfonx 151 // reset the selection of the DpLayerSelectionModel
308     // layerSelModel.setValueIsAdjusting(true);
309 alfonx 97
310 alfonx 151 if (selectedTool == MapPaneToolBar.TOOL_SELECTION_ADD) {
311     layerSelModel.setValueIsAdjusting(true);
312 alfonx 409
313     for (int fIdx = 0; fi.hasNext(); fIdx++) {
314     SimpleFeature f = fi.next();
315 alfonx 151 layerSelModel.addSelection(f.getID());
316     }
317     layerSelModel.setValueIsAdjusting(false);
318     } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_SET) {
319     layerSelModel.setValueIsAdjusting(true);
320     layerSelModel.clearSelection();
321 alfonx 97
322 alfonx 409 for (int fIdx = 0; fi.hasNext(); fIdx++) {
323     SimpleFeature f = fi.next();
324 alfonx 151 layerSelModel.addSelection(f.getID());
325     }
326 alfonx 111
327 alfonx 409 // LOGGER.debug("Setting selection to " + fi.());
328    
329 alfonx 151 layerSelModel.setValueIsAdjusting(false);
330     } else if (selectedTool == MapPaneToolBar.TOOL_SELECTION_REMOVE) {
331     layerSelModel.setValueIsAdjusting(true);
332 alfonx 409 for (int fIdx = 0; fi.hasNext(); fIdx++) {
333     SimpleFeature f = fi.next();
334 alfonx 151 layerSelModel.removeSelection(f.getID());
335 alfonx 111 }
336 alfonx 151 layerSelModel.setValueIsAdjusting(false);
337     }
338 alfonx 111
339     // Show selected features in the map, which is not automatically done by
340     // the origin: FeatureSelectedEvent
341 alfonx 97 changeLayerStyle(layerSelModel.getSelection());
342 alfonx 106
343 alfonx 97 // Danger of event circles in propertyChange(..) banned
344     selectionChangeCausedByMe = false;
345     }
346 alfonx 151
347 alfonx 97 }

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