1 |
/** SCHMITZM - This file is part of the java library of Martin O.J. Schmitz (SCHMITZM) |
/******************************************************************************* |
2 |
|
* Copyright (c) 2009 Martin O. J. Schmitz. |
3 |
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. |
* |
4 |
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. |
* This file is part of the SCHMITZM library - a collection of utility |
5 |
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 |
* classes based on Java 1.6, focusing (not only) on Java Swing |
6 |
|
* and the Geotools library. |
7 |
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. |
* |
8 |
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. |
* The SCHMITZM project is hosted at: |
9 |
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. |
* http://wald.intevation.org/projects/schmitzm/ |
10 |
**/ |
* |
11 |
|
* This program is free software; you can redistribute it and/or |
12 |
package skrueger.geotools.selection; |
* modify it under the terms of the GNU Lesser General Public License |
13 |
|
* as published by the Free Software Foundation; either version 3 |
14 |
import java.beans.PropertyChangeEvent; |
* of the License, or (at your option) any later version. |
15 |
import java.beans.PropertyChangeListener; |
* |
16 |
import java.util.Vector; |
* This program is distributed in the hope that it will be useful, |
17 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 |
import javax.swing.JTable; |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 |
import javax.swing.ListSelectionModel; |
* GNU General Public License for more details. |
20 |
import javax.swing.event.ListSelectionListener; |
* |
21 |
import javax.swing.plaf.basic.BasicTreeUI.SelectionModelPropertyChangeHandler; |
* 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 |
import org.jfree.chart.JFreeChart; |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
24 |
import org.jfree.data.general.Dataset; |
* or try this link: http://www.gnu.org/licenses/lgpl.html |
25 |
import org.jfree.data.general.SeriesDataset; |
* |
26 |
import org.jfree.data.xy.XYSeriesCollection; |
* Contributors: |
27 |
|
* Martin O. J. Schmitz - initial API and implementation |
28 |
import schmitzm.geotools.gui.FeatureCollectionTableModel; |
* Stefan A. Krüger - additional utility classes |
29 |
import schmitzm.jfree.chart.renderer.SelectionRenderer; |
******************************************************************************/ |
30 |
import schmitzm.jfree.chart.selection.DatasetSelectionListener; |
package skrueger.geotools.selection; |
31 |
import schmitzm.jfree.chart.selection.DatasetSelectionModel; |
|
32 |
import schmitzm.jfree.chart.selection.DatasetSelectionModelProvider; |
import java.beans.PropertyChangeEvent; |
33 |
import schmitzm.jfree.chart.selection.DatasetSelectionChangeEvent; |
import java.beans.PropertyChangeListener; |
34 |
import schmitzm.jfree.feature.Feature2DatasetItemDatasetGroup; |
import java.util.Vector; |
35 |
|
|
36 |
/** |
import org.jfree.data.general.Dataset; |
37 |
* This class keeps the selection of a {@link Dataset} (based on feature |
|
38 |
* attributes) synchronized with the {@link StyledLayerSelectionModel} of a layer. |
import schmitzm.jfree.chart.renderer.SelectionRenderer; |
39 |
* This is done by implementing: |
import schmitzm.jfree.chart.selection.DatasetSelectionChangeEvent; |
40 |
* <ul> |
import schmitzm.jfree.chart.selection.DatasetSelectionListener; |
41 |
* <li>a {@link PropertyChangeListener} which listens to the |
import schmitzm.jfree.chart.selection.DatasetSelectionModel; |
42 |
* {@link StyledLayerSelectionModel} and accordingly changes the {@link SelectionRenderer} |
import schmitzm.jfree.chart.selection.DatasetSelectionModelProvider; |
43 |
* selection</li> |
import schmitzm.jfree.feature.FeatureDatasetSelectionModel; |
44 |
* <li>a {@link DatasetSelectionModel} which listens to the {@link SelectionRenderer} and |
|
45 |
* accordingly changes the {@link StyledLayerSelectionModel} selection</li> |
/** |
46 |
* </ul> |
* This class keeps the selection of a {@link Dataset} (based on feature |
47 |
* After creating, the instance of this synchronizer must be added as listener |
* attributes) synchronized with the {@link StyledLayerSelectionModel} of a layer. |
48 |
* to both, the {@link StyledLayerSelectionModel} and the chart's |
* This is done by implementing: |
49 |
* {@link DatasetSelectionModel} (e.g. the renderer). |
* <ul> |
50 |
* @see DatasetSelectionModelProvider |
* <li>a {@link PropertyChangeListener} which listens to the |
51 |
* @author <a href="mailto:[email protected]">Martin Schmitz</a> |
* {@link StyledLayerSelectionModel} and accordingly changes the {@link SelectionRenderer} |
52 |
*/ |
* selection</li> |
53 |
public class ChartSelectionSynchronizer extends StyledLayerSelectionModelSynchronizer<StyledFeatureLayerSelectionModel> |
* <li>a {@link DatasetSelectionModel} which listens to the {@link SelectionRenderer} and |
54 |
implements DatasetSelectionListener { |
* accordingly changes the {@link StyledLayerSelectionModel} selection</li> |
55 |
|
* </ul> |
56 |
/** Holds the chart datset to keep synchronized with the layer selection model. */ |
* After creating, the instance of this synchronizer must be added as listener |
57 |
protected DatasetSelectionModel<?> datasetSelModel = null; |
* to both, the {@link StyledLayerSelectionModel} and the chart's |
58 |
/** Hold the mapping between feature IDs and dataset items. */ |
* {@link DatasetSelectionModel} (e.g. the renderer). |
59 |
protected Feature2DatasetItemDatasetGroup<?> mapping = null; |
* @see DatasetSelectionModelProvider |
60 |
|
* @author <a href="mailto:[email protected]">Martin Schmitz</a> |
61 |
/** |
*/ |
62 |
* Creates a new synchronizer. |
public class ChartSelectionSynchronizer extends StyledLayerSelectionModelSynchronizer<StyledFeatureLayerSelectionModel> |
63 |
* @param layerSelModel |
implements DatasetSelectionListener { |
64 |
* layer selection model to keep synchronized with the dataset |
|
65 |
* selection model |
/** Holds the chart datset to keep synchronized with the layer selection model. */ |
66 |
* @param datasetSelModel |
protected FeatureDatasetSelectionModel<?,?,?> datasetSelModel = null; |
67 |
* dataset selection model to keep synchronized with the layer |
|
68 |
* selection model |
/** |
69 |
*/ |
* Creates a new synchronizer. |
70 |
public ChartSelectionSynchronizer(StyledFeatureLayerSelectionModel layerSelModel, DatasetSelectionModel<?> datasetSelModel) { |
* @param layerSelModel |
71 |
super(layerSelModel); |
* layer selection model to keep synchronized with the dataset |
72 |
// the dataset selection model must provide a mapping |
* selection model |
73 |
// to the feature IDs |
* @param datasetSelModel |
74 |
if ( datasetSelModel.getDataset() == null || |
* dataset selection model to keep synchronized with the layer |
75 |
!(datasetSelModel.getDataset().getGroup() instanceof Feature2DatasetItemDatasetGroup) ) |
* selection model |
76 |
throw new UnsupportedOperationException("Dataset must provide a Feature2DatasetItemDatasetGroup as DatasetGroup."); |
*/ |
77 |
this.datasetSelModel = datasetSelModel; |
public ChartSelectionSynchronizer(StyledFeatureLayerSelectionModel layerSelModel, FeatureDatasetSelectionModel<?,?,?> datasetSelModel) { |
78 |
this.mapping = (Feature2DatasetItemDatasetGroup<?>)datasetSelModel.getDataset().getGroup(); |
super(layerSelModel); |
79 |
} |
this.datasetSelModel = datasetSelModel; |
80 |
|
} |
81 |
/** |
|
82 |
* Called by {@link StyledLayerSelectionModel} when a the selection on other |
/** |
83 |
* selection components (map, table, ...) has changed. When calling this |
* Called by {@link StyledLayerSelectionModel} when the selection on other |
84 |
* method changes the dataset selection according to the |
* selection components (map, table, ...) has changed. When calling this |
85 |
* {@link StyledLayerSelectionModel} selection. |
* method changes the dataset selection according to the |
86 |
* @param evt an event |
* {@link StyledLayerSelectionModel} selection. |
87 |
*/ |
* @param evt an event |
88 |
@Override |
*/ |
89 |
public void propertyChange(PropertyChangeEvent evt) { |
@Override |
90 |
if (!(evt instanceof StyledLayerSelectionEvent)) |
public void propertyChange(PropertyChangeEvent evt) { |
91 |
return; |
if (!(evt instanceof StyledLayerSelectionEvent)) |
92 |
StyledLayerSelectionEvent selEvt = (StyledLayerSelectionEvent) evt; |
return; |
93 |
// Only react on own layer and ignore events invoked by |
StyledLayerSelectionEvent selEvt = (StyledLayerSelectionEvent) evt; |
94 |
// this component itself |
// Only react on own layer and ignore events invoked by |
95 |
if (selEvt.getEmitter() != layerSelModel || selectionChangeCausedByMe) |
// this component itself |
96 |
return; |
if (selEvt.getEmitter() != layerSelModel || selectionChangeCausedByMe) |
97 |
// Apply new selection on chart (except this event is one of |
return; |
98 |
// some more events) |
// Apply new selection on chart (except this event is one of |
99 |
Vector<String> newSelection = layerSelModel.getSelection(); |
// some more events) |
100 |
if (newSelection == null) |
Vector<String> newSelection = layerSelModel.getSelection(); |
101 |
return; |
if (newSelection == null) |
102 |
|
return; |
103 |
// Avoid event circles in valueChanged(..) |
|
104 |
selectionChangeCausedByMe = true; |
// Avoid event circles in valueChanged(..) |
105 |
|
selectionChangeCausedByMe = true; |
106 |
datasetSelModel.setValueIsAdjusting(true); |
|
107 |
datasetSelModel.clearSelection(); |
datasetSelModel.setValueIsAdjusting(true); |
108 |
|
datasetSelModel.clearSelection(); |
109 |
for (String fID : newSelection) { |
for (String fID : newSelection) |
110 |
Comparable dataID = mapping.getDataID(fID); |
datasetSelModel.setItemSelected(fID, true); |
111 |
if (dataID != null ) { |
datasetSelModel.setValueIsAdjusting(false); // event is fired autmatically! |
112 |
//TODO: Fallunterscheidung zwischen den unterschiedlichen DatasetSelectionModel-Typen!! |
|
113 |
} else { |
// Danger of event circles in valueChanged(..) banned |
114 |
LOGGER.warn("Something that is not visible in the chart should be selected"); |
selectionChangeCausedByMe = false; |
115 |
} |
} |
116 |
} |
|
117 |
datasetSelModel.setValueIsAdjusting(false); // event is fired autmatically! |
/** |
118 |
|
* Called when the chart selection is changed by the user. When calling this |
119 |
// Danger of event circles in valueChanged(..) banned |
* method changes the selection of the {@link StyledLayerSelectionModel}. |
120 |
selectionChangeCausedByMe = false; |
* @param evt an event |
121 |
} |
*/ |
122 |
|
@Override |
123 |
@Override |
public void selectionChanged(DatasetSelectionChangeEvent evt) { |
124 |
public void selectionChanged(DatasetSelectionChangeEvent e) { |
// ignore event if it is part of multiple events |
125 |
// TODO Auto-generated method stub |
if (evt != null && evt.getSource().getValueIsAdjusting()) |
126 |
|
return; |
127 |
} |
// ignore event if it is caused by the ChartSelectionSynchronizer |
128 |
|
if (selectionChangeCausedByMe) |
129 |
|
return; |
130 |
} |
|
131 |
|
// Avoid event circles in propertyChange(..) |
132 |
|
selectionChangeCausedByMe = true; |
133 |
|
|
134 |
|
// reset the selection of the DpLayerSelectionModel |
135 |
|
layerSelModel.setValueIsAdjusting(true); |
136 |
|
layerSelModel.clearSelection(); |
137 |
|
for (String featureID : datasetSelModel.getSelectedFeatures()) |
138 |
|
layerSelModel.addSelection(featureID); |
139 |
|
layerSelModel.setValueIsAdjusting(false); |
140 |
|
|
141 |
|
// Danger of event circles in propertyChange(..) banned |
142 |
|
selectionChangeCausedByMe = false; |
143 |
|
} |
144 |
|
|
145 |
|
|
146 |
|
} |