Revision 39986

View differences:

tags/libraries/org.gvsig.fmap.control/2.0/src-test/org/gvsig/fmap/mapcontrol/tools/AreaListenerTest.java
1
package org.gvsig.fmap.mapcontrol.tools;
2

  
3
import java.awt.geom.Point2D;
4

  
5
import org.cresques.cts.IProjection;
6
import org.gvsig.fmap.crs.CRSFactory;
7
import org.gvsig.fmap.mapcontext.MapContext;
8
import org.gvsig.fmap.mapcontext.ViewPort;
9
import org.gvsig.fmap.mapcontrol.MapControl;
10
import org.gvsig.tools.junit.AbstractLibraryAutoInitTestCase;
11

  
12

  
13
public class AreaListenerTest extends AbstractLibraryAutoInitTestCase {
14
	private IProjection projectionUTM = CRSFactory.getCRS("EPSG:23030");
15
	private IProjection projectionGeo = CRSFactory.getCRS("EPSG:4230");
16
		
17
	@Override
18
	protected void doSetUp() throws Exception {
19
		// Nothing to do	
20
	}
21

  
22
	public void test1() {
23
		AreaListenerImpl areaListenerUTM=new AreaListenerImpl(newMapControlUTM());
24
		AreaListenerImpl areaListenerGeo=new AreaListenerImpl(newMapControlGeo());
25
		Double[] xsUTM=new Double[] {new Double(731292),new Double(731901),new Double(730138)};
26
		Double[] ysUTM=new Double[] {new Double(4351223),new Double(4350768),new Double(4349232)};
27
		double areaUTM=areaListenerUTM.returnCoordsArea(xsUTM,ysUTM,new Point2D.Double(730138,4349232));
28
		Double[] xsGeo=new Double[] {new Double(-0.31888183),new Double(-0.31173131),new Double(-0.33268401)};
29
		Double[] ysGeo=new Double[] {new Double(39.27871741),new Double(39.27464327),new Double(39.26117368)};
30
		double areaGeo=areaListenerGeo.returnGeoCArea(xsGeo,ysGeo,new Point2D.Double(-0.33268401,39.26117368));
31
		assertTrue("Area UTM igual a Geo",areaUTM<(areaGeo+1000)&& areaUTM>(areaGeo-1000));
32
	}
33
	private MapControl newMapControlUTM() {
34
		ViewPort vp = new ViewPort(projectionUTM);
35
		MapControl mc=new MapControl();
36
		mc.setMapContext(new MapContext(vp));
37
		return mc;
38
	}
39
	private MapControl newMapControlGeo() {
40
		ViewPort vp = new ViewPort(projectionGeo);
41
		MapControl mc=new MapControl();
42
		mc.setMapContext(new MapContext(vp));
43
		return mc;
44
	}
45
}
tags/libraries/org.gvsig.fmap.control/2.0/src/org/gvsig/app/gui/JComboBoxUnits.java
1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.app.gui;
42

  
43
import org.gvsig.fmap.mapcontext.MapContext;
44
import org.gvsig.i18n.Messages;
45
import org.gvsig.utils.swing.JComboBox;
46

  
47

  
48
/**
49
 * <p>Class representing a JComboBox with the measure units handled by the application.
50
 * It takes values from Attributes.NAMES and Attributes.CHANGE static fields. So, to
51
 * add more measure units, you must edit Attributes class and change will be automatically
52
 * reflected in the combo box.</p>
53
 *
54
 * <p>The internatiolanization of the field is automatically handled by the system</p>
55
 * @author jaume dominguez faus - jaume.dominguez@iver.es
56
 */
57
public class JComboBoxUnits extends JComboBox {
58
	private static final long serialVersionUID = 8015263853737441433L;
59

  
60
	/**
61
	 * Creates a new instance of JUnitComboBox including "pixel" units and
62
	 * setting them as automatically pre-selected.
63
	 */
64
	public JComboBoxUnits() {
65
		this(true);
66
	}
67

  
68
	/**
69
	 *
70
	 * Creates a new instance of JUnitComboBox. If includePixel is true
71
	 * then pixel units are included in the list and they are automatically
72
	 * pre-selected. Otherwise, meters are preselected.
73
	 *
74
	 */
75
	public JComboBoxUnits(boolean includePixel) {
76
		super();
77
		String[] names=MapContext.getDistanceNames();
78

  
79
		for (int i = 0; i < names.length; i++) {
80
			super.addItem(Messages.getText(names[i]));
81
		}
82
		if (includePixel) {
83
			super.addItem(Messages.getText("_Pixels"));
84
			setSelectedItem(Messages.getText("_Pixels"));
85
		} else {
86
			setSelectedIndex(1);
87
		}
88
		setMaximumRowCount(10);
89
	}
90

  
91

  
92
	/**
93
	 * Returns the conversion factor from the <b>unit selected in the combo box</b>
94
	 * to <b>meters</b> or <b>0</b> if pixels have been selected as the size unit.
95
	 * @return
96
	 */
97
	public double getUnitConversionFactor() {
98
			double unitFactor;
99
			try {
100
				unitFactor = MapContext.getDistanceTrans2Meter()[getSelectedIndex()];
101
			} catch (ArrayIndexOutOfBoundsException aioobEx) { //jijiji
102
				unitFactor = 0; // which represents size in pixel
103
			}
104
			return unitFactor;
105

  
106
	}
107

  
108
	/**
109
	 * the use of this method is not allowed in this combo box.
110
	 * @deprecated
111
	 */
112
	public void addItem(Object anObject) {
113
		throw new Error("Operation not allowed");
114
	}
115

  
116
	/**
117
	 * the use of this method is not allowed for this combo box.
118
	 * @deprecated
119
	 */
120
	public void removeAllItems() {
121
		throw new Error("Operation not allowed");
122
	}
123

  
124
	public int getSelectedUnitIndex() {
125
		int i = getSelectedIndex();
126
		if (i>MapContext.getDistanceNames().length-1)
127
			return -1;
128
		else return i;
129
	}
130

  
131
	public void setSelectedUnitIndex(int unitIndex) {
132
		if (unitIndex == -1) {
133
			setSelectedIndex(getItemCount()-1);
134
		} else {
135
			setSelectedIndex(unitIndex);
136
		}
137
	}
138

  
139

  
140

  
141
}
0 142

  
tags/libraries/org.gvsig.fmap.control/2.0/src/org/gvsig/fmap/IconThemeHelper.java
1
package org.gvsig.fmap;
2

  
3
import java.awt.Image;
4

  
5
import javax.swing.ImageIcon;
6

  
7
import org.gvsig.tools.swing.api.ToolsSwingLocator;
8
import org.gvsig.tools.swing.icontheme.IconTheme;
9
import org.slf4j.Logger;
10
import org.slf4j.LoggerFactory;
11

  
12
public class IconThemeHelper {
13

  
14
	private static Logger logger = LoggerFactory.getLogger(IconThemeHelper.class);
15
	
16
	public static void registerIcon(String group, String name, Object obj) {
17
		String resourceName;
18
		ClassLoader loader;
19
		IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
20
		if( group == null || group.trim().length()==0 ) {
21
			resourceName = "images/"+name+".png";
22
		} else {
23
			resourceName = "images/"+group+"/"+name+".png";
24
		}
25
		if( obj instanceof Class ) {
26
			loader = ((Class) obj).getClassLoader();
27
		} else {
28
			loader = obj.getClass().getClassLoader();
29
		}
30
		try {
31
			iconTheme.registerDefault("mapcontrol", group, name, null, loader.getResource(resourceName));
32
		} catch( Throwable e) {
33
			logger.info(e.getMessage());
34
		}
35
	}
36

  
37
	public static ImageIcon getImageIcon(String iconName) {
38
		IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
39
		return iconTheme.get(iconName);
40
	}
41
	
42
	public static Image getImage(String iconName) {
43
		IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
44
		return iconTheme.get(iconName).getImage();
45
	}
46
}
0 47

  
tags/libraries/org.gvsig.fmap.control/2.0/src/org/gvsig/fmap/mapcontrol/MapControlManager.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22

  
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 {Iver T.I.}   {Task}
26
*/
27
 
28
package org.gvsig.fmap.mapcontrol;
29

  
30
import java.util.Map;
31
import java.util.prefs.Preferences;
32

  
33
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
34
import org.gvsig.fmap.mapcontrol.swing.dynobject.LayersDynObjectSetComponent;
35
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.ISnapper;
36
import org.gvsig.tools.dynobject.DynObject;
37
import org.gvsig.tools.dynobject.DynObjectSet;
38

  
39
/**
40
 * <p>
41
 * This class is the manager of the MapControl library. It is used to
42
 * manage all the properties related with the drawing of objects 
43
 * in a map, including default symbols used to draw objects
44
 * in a map, the tolerance used by the selection or edition tools...
45
 * </p>
46
 * <p>
47
 * It also holds the implementations of the {@link MapControlDrawer}'s, 
48
 * that is the responsible to draw graphical objects in a map.
49
 * </p> 
50
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
51
 */
52
public interface MapControlManager {
53

  
54
	public MapControl createJMapControlPanel() throws MapControlCreationException;
55
		
56
	/**
57
	 * Register a <code>MapControlDrawer</code> by name.
58
	 * @param name
59
	 * Name of the <code>MapControlDrawer</code>.
60
	 * @param mapControolDrawerClass
61
	 * Class used to draw graphical objects on a map.
62
	 */
63
	public void registerMapControlDrawer(String name, Class mapControolDrawerClass);
64
	
65
	/**
66
	 * Creates a <code>MapControlDrawer</code> from a name.
67
	 * @param name
68
	 * Name of the <code>MapControlDrawer</code>.
69
	 * @return
70
	 * A <code>MapControlDrawer</code>.
71
	 * @throws MapControlCreationException
72
	 */
73
	public MapControlDrawer createMapControlDrawer(String name) throws MapControlCreationException;
74
	
75
	/**
76
	 * It registers the default implementation for the <code>MapControlDrawer</code>.
77
	 * @param mapControlDrawerClass
78
	 * A <code>MapControlDrawer</code>. 
79
	 */
80
	public void registerDefaultMapControlDrawer(Class mapControlDrawerClass);
81
	
82
	/**
83
	 * It returns the default implementation for the <code>MapControlDrawer</code>.
84
	 * @return
85
	 * The default <code>MapControlDrawer</code>.
86
	 * @throws MapControlCreationException
87
	 */
88
	public MapControlDrawer createDefaultMapControlDrawer() throws MapControlCreationException;
89
	
90
	/**
91
	 * Returns a snapper in a concrete position;
92
	 * @param index
93
	 * Snapper position.
94
	 * @return
95
	 * A snapper. 
96
	 */
97
	public ISnapper getSnapperAt(int index);
98
	
99
	/**
100
	 * Returns the number of registered snappers.
101
	 * @return
102
	 * The number of registered snappers.
103
	 */
104
	public int getSnapperCount();
105
	
106
	/**
107
	 * Add a snapper.
108
	 * @param snapper
109
	 */
110
	public void registerSnapper(String name, Class snapperClass);
111
	
112
	
113
	public Preferences getEditionPreferences();
114
	
115
	/**
116
	 * Tolerance (in pixels) that has to be used by the tools
117
	 * that use snapping.
118
	 * @return
119
	 * The distance in pixels.
120
	 */
121
	public int getTolerance();
122
	
123
	/**
124
	 * Sets the tolerance (in pixels) that has to be used by the
125
	 * tools that use snapping.
126
	 * @param tolerance
127
	 * The tolerance to apply
128
	 */
129
	public void setTolerance(int tolerance);
130
	
131
	/**
132
	 * Sets the symbol that has to be used to draw a geometry when
133
	 * it is selected.
134
	 * @param selectionSymbol
135
	 * The symbol to apply.
136
	 * @deprecated the symbol for edition is the selection symbol
137
	 */
138
	public void setSelectionSymbol(ISymbol selectionSymbol);
139
	
140
	/**
141
	 * Gets the symbol used to draw the selected geometries.
142
	 * @return
143
	 * The symbol used to draw the selected geometries.
144
	 * @deprecated the symbol for edition is the selection symbol
145
	 */
146
	public ISymbol getSelectionSymbol();
147
	
148
	/**
149
	 * Sets the symbol that has to be used to draw a geometry that
150
	 * represent the axis of a geometry.
151
	 * @param axisReferencesSymbol
152
	 * The symbol to apply.
153
	 */
154
	public void setAxisReferenceSymbol(ISymbol axisReferencesSymbol);
155
	
156
	/**
157
	 * Gets the symbol used to draw the axis of a geometry.
158
	 * @return
159
	 * The symbol used to draw the axis of a geometry.
160
	 */
161
	public ISymbol getAxisReferenceSymbol();
162
	
163
	/**
164
	 * Sets the symbol that has to be used to draw a geometry when
165
	 * it is selected.
166
	 * @param geometrySelectionSymbol
167
	 * The symbol to apply.
168
	 */
169
	public void setGeometrySelectionSymbol(ISymbol geometrySelectionSymbol);
170
	
171
	/**
172
	 * Gets the symbol used to draw the selected geometries.
173
	 * @return
174
	 * The symbol used to draw the selected geometries.
175
	 */
176
	public ISymbol getGeometrySelectionSymbol();
177
	
178
	/**
179
	 * Sets the symbol that has to be used to draw the handlers.
180
	 * @param handlerSymbol
181
	 * The symbol to apply.
182
	 */
183
	public void setHandlerSymbol(ISymbol handlerSymbol);
184
	
185
	/**
186
	 * Gets the symbol used to draw the handlers.
187
	 * @return
188
	 * The symbol used to draw the handlers.
189
	 */
190
	public ISymbol getHandlerSymbol();
191

  
192
    /**
193
     * Creates a readonly component to view information of a set of layers. The
194
     * information must be provided as a set of {@link DynObject}s, through a
195
     * {@link DynObjectSet}.
196
     * 
197
     * @param layerName2InfoByPoint
198
     *            the map of {@link DynObjectSet} for each layer.
199
     * @return the component to view the information
200
     */
201
    public LayersDynObjectSetComponent createLayersDynObjectSetComponent(
202
        Map<String, DynObjectSet> layerName2InfoByPoint);
203

  
204
    /**
205
     * Creates a component to view information of a set of layers. The
206
     * information must be provided as a set of {@link DynObject}s, through a
207
     * {@link DynObjectSet}.
208
     * 
209
     * @param layerName2InfoByPoint
210
     *            the map of {@link DynObjectSet} for each layer.
211
     * @param writable
212
     *            if the DynObjects loaded must be able to be edited
213
     * @return the component to view the information
214
     */
215
    public LayersDynObjectSetComponent createLayersDynObjectSetComponent(
216
        Map<String, DynObjectSet> layerName2InfoByPoint, boolean writable);
217
}
218

  
0 219

  
tags/libraries/org.gvsig.fmap.control/2.0/src/org/gvsig/fmap/mapcontrol/MapControlException.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22

  
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 {Iver T.I.}   {Task}
26
*/
27
 
28
package org.gvsig.fmap.mapcontrol;
29

  
30
import org.gvsig.tools.exception.BaseException;
31

  
32
/**
33
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
34
 */
35
public class MapControlException extends BaseException {
36
	private static final long serialVersionUID = 981894833703125550L;
37

  
38
	/**
39
     * @see BaseException#BaseException(String, String, long)
40
     */
41
    public MapControlException(String message, String key, long code) {
42
        super(message, key, code);
43
    }
44

  
45
    /**
46
     * @see BaseException#BaseException(String, Throwable, String, long)
47
     */
48
    public MapControlException(String message, Throwable cause, String key,
49
            long code) {
50
        super(message, cause, key, code);
51
    }
52
}
53

  
54

  
0 55

  
tags/libraries/org.gvsig.fmap.control/2.0/src/org/gvsig/fmap/mapcontrol/MapControl.java
1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.fmap.mapcontrol;
42

  
43
import java.awt.Color;
44
import java.awt.Cursor;
45
import java.awt.Dimension;
46
import java.awt.Graphics;
47
import java.awt.Graphics2D;
48
import java.awt.Image;
49
import java.awt.Point;
50
import java.awt.Toolkit;
51
import java.awt.event.ActionEvent;
52
import java.awt.event.ActionListener;
53
import java.awt.event.ComponentEvent;
54
import java.awt.event.ComponentListener;
55
import java.awt.event.MouseEvent;
56
import java.awt.event.MouseListener;
57
import java.awt.event.MouseMotionListener;
58
import java.awt.event.MouseWheelEvent;
59
import java.awt.event.MouseWheelListener;
60
import java.awt.geom.Point2D;
61
import java.awt.image.BufferedImage;
62
import java.awt.image.MemoryImageSource;
63
import java.util.ArrayList;
64
import java.util.Comparator;
65
import java.util.HashMap;
66
import java.util.List;
67
import java.util.Set;
68
import java.util.TreeMap;
69
import java.util.prefs.Preferences;
70

  
71
import javax.swing.JComponent;
72
import javax.swing.SwingUtilities;
73
import javax.swing.Timer;
74

  
75
import org.cresques.cts.IProjection;
76
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
78

  
79
import org.gvsig.fmap.dal.DataStoreNotification;
80
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
81
import org.gvsig.fmap.geom.Geometry;
82
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
83
import org.gvsig.fmap.geom.GeometryLocator;
84
import org.gvsig.fmap.geom.GeometryManager;
85
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
86
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
87
import org.gvsig.fmap.geom.operation.GeometryOperationException;
88
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
89
import org.gvsig.fmap.geom.operation.tojts.ToJTS;
90
import org.gvsig.fmap.geom.primitive.Envelope;
91
import org.gvsig.fmap.mapcontext.MapContext;
92
import org.gvsig.fmap.mapcontext.MapContextLocator;
93
import org.gvsig.fmap.mapcontext.MapContextManager;
94
import org.gvsig.fmap.mapcontext.ViewPort;
95
import org.gvsig.fmap.mapcontext.events.AtomicEvent;
96
import org.gvsig.fmap.mapcontext.events.listeners.AtomicEventListener;
97
import org.gvsig.fmap.mapcontext.layers.FLayers;
98
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
99
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
100
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
101
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
102
import org.gvsig.fmap.mapcontext.layers.vectorial.GraphicLayer;
103
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
104
import org.gvsig.fmap.mapcontrol.tools.CompoundBehavior;
105
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
106
import org.gvsig.fmap.mapcontrol.tools.Listeners.ToolListener;
107
import org.gvsig.fmap.mapcontrol.tools.grid.Grid;
108
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.ISnapper;
109
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.ISnapperGeometriesVectorial;
110
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.ISnapperRaster;
111
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.ISnapperVectorial;
112
import org.gvsig.tools.ToolsLocator;
113
import org.gvsig.tools.dispose.Disposable;
114
import org.gvsig.tools.observer.Observable;
115
import org.gvsig.tools.observer.Observer;
116
import org.gvsig.tools.task.Cancellable;
117
import org.gvsig.utils.exceptionHandling.ExceptionHandlingSupport;
118
import org.gvsig.utils.exceptionHandling.ExceptionListener;
119

  
120
/**
121
 * <p>
122
 * A component that includes a {@link MapContext MapContext} with support for
123
 * use it as a particular {@link Behavior Behavior}.
124
 * </p>
125
 * 
126
 * <p>
127
 * A developer can register a set of <code>Behavior</code>, but only one (that
128
 * can be a composition of several) of them can be active. The active one
129
 * defines the way to work and access with its <code>MapContext</code>'s layers.
130
 * The active behavior, in combination with the appropriate {@link ToolListener
131
 * ToolListener} will allow user work with a particular <i>tool</i>.
132
 * </p>
133
 * 
134
 * <p>
135
 * All mouse events produced on this component will be delegated to the current
136
 * active behavior, the <i>currentMapTool</i>.
137
 * </p>
138
 * 
139
 * <p>
140
 * <b>Drawing process:</b>
141
 * </p>
142
 * 
143
 * <p>
144
 * Uses a double buffer for the drawing process of <code>MapContext</code>'s
145
 * information.
146
 * </p>
147
 * 
148
 * <p>
149
 * If the double buffer wasn't created, creates a new one.
150
 * </p>
151
 * 
152
 * <p>
153
 * Paints the component according the following algorithm: <br>
154
 * &nbsp If <i>status</i> is <i>UPDATED</i>:<br>
155
 * &nbsp &nbsp If there is a <i>double buffer</i>:<br>
156
 * &nbsp &nbsp &nbsp If there is a <i>behavior</i> for managing the
157
 * <code>MapControl</code> instance, delegates the drawing process to that
158
 * behavior, calling: <code><i>behavior_instance</i>.paintComponent(g)</code>.<br>
159
 * &nbsp &nbsp &nbsp Else, repaints the current graphical information quickly
160
 * calling: <code>g.drawImage(image,0,0,null)</code>.<br>
161
 * &nbsp Else, (<i>status</i> is <i>OUTDATED</i>, or <i>ONLY_GRAPHICS</i>):
162
 * executes a quickly repaint of the previous information calling
163
 * <code>g.drawImage(image,0,0,null)</code>, and creates a <i>painting
164
 * request</i> to delegate the heavy drawing process to the {@link Drawer2
165
 * Drawer2}'s worker thread, according the <i>SingleWorketThread</i> pattern,
166
 * starting a timer to update (invoking <code>repaint()</code>) the view every
167
 * delay of <code>1000 / drawFrameRate</code> ms. during that heavy drawing
168
 * process, and if its enabled <code>drawAnimationEnabled</code>. The
169
 * <i>painting request</i> once is being attended, invokes
170
 * <code>MapContext</code> to draw the layers:
171
 * <code>mapContext.draw(image, g, cancel,mapContext.getScaleView());</code>
172
 * <br>
173
 * <p>
174
 * Some notes:
175
 * <ul>
176
 * <li>The painting process can be cancelled calling {@link #cancelDrawing()
177
 * #cancelDrawing()}.</li>
178
 * <li>At last resort, the particular implementation of each layer in a
179
 * <code>MapControl</code>'s <code>MapContrext</code> will be that one which
180
 * will draw the graphical information, and, if supports, which could cancel its
181
 * drawing subprocess.</li>
182
 * <li>It's possible to force repaint all layers, calling
183
 * {@link #drawMap(boolean doClear) #drawMap(boolean)}.</li>
184
 * <li>It's possible repaint only the dirty layers, calling
185
 * {@link #rePaintDirtyLayers() #rePaintDirtyLayers()}.</li>
186
 * <li>It's possible repaint only the {@link GraphicLayer GraphicLayer}, calling
187
 * {@link #drawGraphics() #drawGraphics()}.</li>
188
 * </ul>
189
 * </p>
190
 * 
191
 * <p>
192
 * <b>Tools:</b>
193
 * </p>
194
 * 
195
 * <p>
196
 * A developer can:
197
 * <ul>
198
 * <li>Register each tool as:
199
 * <ul>
200
 * <li>A single behavior: {@link #addBehavior(String, Behavior)
201
 * #addMapTool(String, Behavior)}.</li>
202
 * <li>Or, a compound behavior: {@link #addBehavior(String, Behavior)
203
 * #addMapTool(String, Behavior)}.</li>
204
 * </ul>
205
 * </li>
206
 * <li>Get the current active tool: {@link #getCurrentMapTool()
207
 * #getCurrentMapTool()}.</li>
208
 * <li>Get the current active tool name: {@link #getCurrentTool()
209
 * #getCurrentTool()}.</li>
210
 * <li>Get a registered tool: {@link #getMapTool(String) #getMapTool(String)}.</li>
211
 * <li>Get the name of all tools registered: {@link #getMapToolsKeySet()
212
 * #getMapToolsKeySet()}.</li>
213
 * <li>Get all tools registered, including the name they were registered:
214
 * {@link #getNamesMapTools() #getNamesMapTools()}.</li>
215
 * <li>Determine if has a tool registered: {@link #hasTool(String)
216
 * #hasTool(String)}.</li>
217
 * <li>Set as an active tool, one of the registered: {@link #setTool(String)
218
 * #setTool(String)}.</li>
219
 * <li>Set as active tool, the previous used: {@link #setPrevTool()
220
 * #setPrevTool()}.</li>
221
 * <li>Set the current tool: {@link #setCurrentMapTool(Behavior)
222
 * #setCurrentMapTool(Behavior)}.</li>
223
 * <li>Change the draw frame rate: {@link #setDrawFrameRate(int)
224
 * #setDrawFrameRate(int)} and {@link #applyFrameRate() #applyFrameRate()}.</li>
225
 * <li>Get the draw frame rate: {@link #getDrawFrameRate() #getDrawFrameRate()}.
226
 * </li>
227
 * <li>Determine if will repaint this component each time timer finishes:
228
 * {@link #isDrawAnimationEnabled() #isDrawAnimationEnabled()}.</li>
229
 * <li>Change if will repaint this component each time timer finishes:
230
 * {@link #setDrawAnimationEnabled(boolean) #setDrawAnimationEnabled(boolean)}.</li>
231
 * <li>Get the shared object that determines if a drawing process must be
232
 * cancelled or can continue: {@link #getCanceldraw() #getCanceldraw()}.</li>
233
 * <li>Get the combined tool: {@link #getCombinedTool() #getCombinedTool()}.</li>
234
 * <li>Set a combined tool: {@link #setCombinedTool(Behavior)
235
 * #setCombinedTool(Behavior)}.</li>
236
 * <li>Remove the combined tool: {@link #removeCombinedTool()
237
 * #removeCombinedTool()}.</li>
238
 * </ul>
239
 * </p>
240
 * 
241
 * <p>
242
 * <b>Exception listener:</b>
243
 * </p>
244
 * 
245
 * <p>
246
 * Adding an <code>ExceptionListener</code>, can get notification about any
247
 * exception produced:
248
 * <ul>
249
 * <li>Attending a <i>painting request</i>.</li>
250
 * <li>Working with the active tool.</li>
251
 * <li>Applying a <i>zoom in</i> or <i>zoom out</i> operation.</li>
252
 * </ul>
253
 * </p>
254
 * 
255
 * <p>
256
 * <b>Other:</b>
257
 * </p>
258
 * 
259
 * <p>
260
 * Other useful capabilities of <code>MapControl</code>:
261
 * <ul>
262
 * <li>Cancel the current drawing process (notifying it also to the inner
263
 * <code>MapContext</code> instance and its layers): {@link #cancelDrawing()
264
 * #cancelDrawing()}.</li>
265
 * <li>Applying a <i>zoom in</i> operation centered at mouse position (without a
266
 * <code>ToolListener</code>): {@link #zoomIn() #zoomIn()}.</li>
267
 * <li>Applying a <i>zoom out</i> operation centered at mouse position (without
268
 * a <code>ToolListener</code>): {@link #zoomOut() #zoomOut()}.</li>
269
 * </ul>
270
 * </p>
271
 * 
272
 * @see CancelDraw
273
 * @see Drawer
274
 * @see MapContextListener
275
 * @see MapToolListener
276
 * 
277
 * @author Fernando Gonz?lez Cort?s
278
 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es)
279
 */
280
public class MapControl extends JComponent implements ComponentListener,
281
    Observer, Disposable {
282

  
283
    protected static final GeometryManager geomManager =
284
        GeometryLocator.getGeometryManager();
285
    private static final Logger LOG =
286
        LoggerFactory.getLogger(GeometryManager.class);
287

  
288
    /**
289
     * <p>
290
     * One of the possible status of <code>MapControl</code>. Determines that
291
     * all visible information has been drawn and its updated.
292
     * </p>
293
     */
294
    public static final int ACTUALIZADO = 0;
295

  
296
    /**
297
     * <p>
298
     * One of the possible status of <code>MapControl</code>. Determines that
299
     * not all visible information has been drawn or isn't updated.
300
     * </p>
301
     */
302
    public static final int DESACTUALIZADO = 1;
303

  
304
    /**
305
     * <p>
306
     * Determines if the drawer can update this <code>MapControl</code> instance
307
     * when the timer launches an event.
308
     * </p>
309
     */
310
    private static boolean drawAnimationEnabled = true;
311

  
312
    /**
313
     * <p>
314
     * Inner model with the layers, event support for drawing them, and the
315
     * <code>ViewPort</code> with information to adapt to the bounds available
316
     * in <i>image coordinates</i>.
317
     * </p>
318
     * 
319
     * @see #getMapContext()
320
     * @see #setMapContext(MapContext)
321
     */
322
    private MapContext mapContext = null;
323

  
324
    /**
325
     * <p>
326
     * All registered <code>Behavior</code> that can define a way to work with
327
     * this <code>MapControl</code>.
328
     * </p>
329
     * 
330
     * <p>
331
     * Only one of them can be active at a given moment.
332
     * </p>
333
     * 
334
     * @see #addBehavior(String, Behavior)
335
     * @see #addBehavior(String, Behavior[])
336
     * @see #getMapTool(String)
337
     * @see #getMapToolsKeySet()
338
     * @see #getNamesMapTools()
339
     */
340
    protected HashMap namesMapTools = new HashMap();
341

  
342
    /**
343
     * <p>
344
     * Active {@link Behavior Behavior} that will generate events according a
345
     * criterion, and then, with a {@link ToolListener ToolListener} associated,
346
     * will simulate to user that works with this component as a particular
347
     * tool.
348
     * </p>
349
     * 
350
     * @see #getCurrentMapTool()
351
     * @see #getCurrentTool()
352
     * @see #setTool(String)
353
     */
354
    protected Behavior currentMapTool = null;
355

  
356
    /**
357
     * <p>
358
     * Determines which's the current drawn status of this component:
359
     * <ul>
360
     * <li><b>OUTDATED</b>: all visible information has been drawn or isn't
361
     * updated.</li>
362
     * <li><b>UTDATED</b>: all visible information has been drawn and its
363
     * updated.</li>
364
     * <li><b>ONLY_GRAPHICS</b>: only the graphical layer must be drawn /
365
     * updated.</li>
366
     * </ul>
367
     * </p>
368
     * 
369
     * <p>
370
     * The <code>MapControl</code> drawing process will consider the value of
371
     * this parameter to decide which elements will be updated or drawn.
372
     * </p>
373
     */
374
    private int status = DESACTUALIZADO;
375

  
376
    /**
377
     * <p>
378
     * Image with a buffer to accelerate the draw the changes of the graphical
379
     * items in this component.
380
     * </p>
381
     * 
382
     * <p>
383
     * Firstly, information will be drawn in the buffer, and, when is outright
384
     * drawn, that information will be displayed. Meanwhile, the previous image
385
     * can be kept showed.
386
     * </p>
387
     * 
388
     * @see BufferedImage
389
     * 
390
     * @see #getImage()
391
     */
392
    private BufferedImage image = null;
393

  
394
    /**
395
     * <p>
396
     * Name of the tool used currently to interact with this component.
397
     * </p>
398
     * 
399
     * @see #getCurrentTool()
400
     * @see #setTool(String)
401
     */
402
    protected String currentTool;
403

  
404
    /**
405
     * <p>
406
     * Object to store the flag that notifies a drawing thread task and
407
     * <code>MapContext</code>'s layers, that must be canceled or can continue
408
     * with the process.
409
     * </p>
410
     * 
411
     * @see #cancelDrawing()
412
     */
413
    private CancelDraw canceldraw;
414

  
415
    // private boolean isCancelled = true;
416

  
417
    /**
418
     * <p>
419
     * Fires an action events after a specified delay.
420
     * </p>
421
     * 
422
     * <p>
423
     * <code>MapControl</code> will use the timer to update its visible
424
     * graphical information during a drawing process, or allowing to cancel
425
     * that process.
426
     * </p>
427
     * 
428
     * <p>
429
     * This is very useful to pretend faster interactivity to user when
430
     * <code>MapControl</code> has lots of layers, and / or layers with heavy
431
     * graphical elements, that need a long time to finish drawing all its data.
432
     * </p>
433
     */
434
    private Timer timer;
435

  
436
    /**
437
     * <p>
438
     * Reference to the {@link ViewPort ViewPort} of the {@link MapContext
439
     * MapContext} of this component.
440
     * </p>
441
     * 
442
     * <p>
443
     * After, the view port will change adapting itself according the current
444
     * projection and the extent.
445
     * </p>
446
     * 
447
     * @see #getViewPort()
448
     * 
449
     * @see ViewPort
450
     */
451
    protected ViewPort vp;
452

  
453
    /**
454
     * <p>
455
     * Manager of all <code>MapControl</code> painting requests.
456
     * </p>
457
     */
458
    private Drawer drawer;
459

  
460
    /**
461
     * <p>
462
     * Listener of all kind of mouse events produced in this component.
463
     * </p>
464
     * 
465
     * <p>
466
     * Delegates each mouse event to the current map tool.
467
     * </p>
468
     * 
469
     * @see #addBehavior(String, Behavior)
470
     * @see #addBehavior(String, Behavior[])
471
     * @see #getMapTool(String)
472
     * @see #getMapToolsKeySet()
473
     * @see #getNamesMapTools()
474
     * @see #setTool(String)
475
     */
476
    protected MapToolListener mapToolListener = new MapToolListener();
477

  
478
    /**
479
     * <p>
480
     * Listener of all events produced in a this component's
481
     * <code>MapContext</code> object during an atomic period of time.
482
     * </p>
483
     */
484
    private MapContextListener mapContextListener = new MapContextListener();
485

  
486
    /**
487
     * <p>
488
     * Group of <code>ExceptionListener</code> that, in whatever moment could be
489
     * notified a Throwable Java error or exception.
490
     * </p>
491
     * 
492
     * @see #addExceptionListener(ExceptionListener)
493
     * @see #removeExceptionListener(ExceptionListener)
494
     */
495
    private ExceptionHandlingSupport exceptionHandlingSupport =
496
        new ExceptionHandlingSupport();
497

  
498
    /**
499
     * <p>
500
     * Name of the previous tool used.
501
     * </p>
502
     */
503
    protected String prevTool;
504

  
505
    /**
506
     * <p>
507
     * Tool that will be used combined with the current tool of this
508
     * <code>MapControl</code>.
509
     * </p>
510
     */
511
    private Behavior combinedTool = null;
512

  
513
    /**
514
     * Optional grid that could be applied on the <code>MapControl</code>'s view
515
     * port.
516
     * 
517
     * @see #getGrid()
518
     * @see #setAdjustGrid(boolean)
519
     */
520
    private Grid cadgrid = new Grid();
521
    /**
522
     * Represents the cursor's point selected in <i>screen coordinates</i>.
523
     * 
524
     * @see ViewPort#fromMapPoint(Point2D)
525
     */
526
    private Point2D adjustedPoint;
527
    /**
528
     * <p>
529
     * Determines if the position of the snap of the mouse's cursor on the
530
     * <code>MapControl</code> is within the area around a control point of a
531
     * geometry.
532
     * </p>
533
     * 
534
     * <p>
535
     * The area is calculated as a circle centered at the control point and with
536
     * radius the pixels tolerance defined in the preferences.
537
     * </p>
538
     */
539
    private boolean bForceCoord = false;
540

  
541
    /**
542
     * Kind of geometry drawn to identify the kind of control point selected by
543
     * the cursor's mouse.
544
     */
545
    private ISnapper usedSnap = null;
546

  
547
    /**
548
     * Determines if the snap tools are enabled or disabled.
549
     * 
550
     * @see #isRefentEnabled()
551
     * @see #setRefentEnabled(boolean)
552
     */
553
    private boolean bRefent = true;
554

  
555
    /**
556
     * Stores the 2D map coordinates of the last point added.
557
     */
558
    private double[] previousPoint = null;
559

  
560
    protected static MapControlManager mapControlManager =
561
        MapControlLocator.getMapControlManager();
562

  
563
    private static TreeMap selected = new TreeMap(new Comparator() {
564

  
565
        public int compare(Object o1, Object o2) {
566
            if (o1.getClass().equals(o2.getClass()))
567
                return 0;
568
            if (((ISnapper) o1).getPriority() > ((ISnapper) o2).getPriority())
569
                return 1;
570
            else
571
                return -1;
572
        }
573

  
574
    });
575

  
576
    /**
577
     * Represents the cursor's point selected in <i>map coordinates</i>.
578
     * 
579
     * @see MapControl#toMapPoint
580
     */
581
    private Point2D mapAdjustedPoint;
582

  
583
    /**
584
     * Renderer used to draw the layers.
585
     */
586
    private MapControlDrawer mapControlDrawer = null;
587
	private Cursor transparentCursor;
588
	
589
	private boolean disposed = false;
590

  
591
    /**
592
     * <p>
593
     * Creates a new <code>MapControl</code> instance with the following
594
     * characteristics:
595
     * <ul>
596
     * <li><i>Name</i>: MapControl .</li>
597
     * <li>Disables the double buffer of <code>JComponent</code> .</li>
598
     * <li>Sets opaque <i>(see {@link JComponent#setOpaque(boolean)} )</i>.</li>
599
     * <li>Sets its status to <code>OUTDATED</code> .</li>
600
     * <li>Creates a new {@link CancelDraw CancelDraw} object to notify
601
     * <code>MapContext</code>'s layers if can continue processing the drawn or
602
     * must cancel it.</li>
603
     * <li>Creates a new {@link MapContext MapContext} with a new
604
     * {@link ViewPort ViewPort} in the default projection.</li>
605
     * <li>Creates a new {@link CommandListener CommandListener} for edition
606
     * operations.</li>
607
     * <li>Creates a new {@link MapToolListener MapToolListener}, and associates
608
     * it as a listener of whatever kind of mouse events produced in this
609
     * component.</li>
610
     * <li>Creates a new {@link Drawer2 Drawer2} for managing the painting
611
     * requests.</li>
612
     * <li>Creates a new timer that will invoke refresh this component
613
     * <code>drawFrameRate</code> per second, when is running a drawing process,
614
     * and its enabled <code>drawAnimationEnabled</code>.</li>
615
     * </ul>
616
     * </p>
617
     */
618
    public MapControl() {
619
        this.setName("MapControl");
620
        Toolkit toolkit = Toolkit.getDefaultToolkit();
621
        Image imageTransparentCursor = toolkit.createImage(new MemoryImageSource(16, 16, new int[16 * 16], 0,16));
622
        transparentCursor =
623
            toolkit.createCustomCursor(imageTransparentCursor, new Point(0, 0), "invisiblecursor");
624

  
625
        setDoubleBuffered(false);
626
        setOpaque(true);
627
        status = DESACTUALIZADO;
628

  
629
        // Clase usada para cancelar el dibujado
630
        canceldraw = new CancelDraw();
631

  
632
        /*
633
         * We are not accessing the user preferences here.
634
         * This is an early initialization and is supposed
635
         * to be reset afterwards from a higher level (plugin)
636
         */
637
        MapContextManager mcm = MapContextLocator.getMapContextManager();
638
        vp = new ViewPort(mcm.getDefaultCRS());
639
        
640
        setMapContext(new MapContext(vp));
641

  
642
        // eventos
643
        this.addComponentListener(this);
644
        this.addMouseListener(mapToolListener);
645
        this.addMouseMotionListener(mapToolListener);
646
        this.addMouseWheelListener(mapToolListener);
647

  
648
        this.drawer = new Drawer();
649
        // Timer para mostrar el redibujado mientras se dibuja
650
        timer =
651
            new Timer(1000 / MapContext.getDrawFrameRate(),
652
                new ActionListener() {
653

  
654
                    public void actionPerformed(ActionEvent e) {
655

  
656
                        if (drawAnimationEnabled) {
657
                            MapControl.this.repaint();
658
                        }
659
                    }
660
                });
661
        initializeGrid();
662
        
663
        if(ToolsLocator.getDisposableManager() != null) {
664
			ToolsLocator.getDisposableManager().bind(this);
665
		} else {
666
			LOG.warn("Can't retrieve the disposable manager,");
667
		}
668
    }
669

  
670
    /**
671
     * <p>
672
     * Sets a <code>MapContext</code> to this component.
673
     * </p>
674
     * 
675
     * <p>
676
     * The <code>MapContext</code> has the <i>model</i>, and most of the
677
     * <i>view</i>, and <i>control</i> logic of the layers of this component,
678
     * including a {@link ViewPort ViewPort} to adapt the information to the
679
     * projection, and to display it in the available area.
680
     * </p>
681
     * 
682
     * <p>
683
     * If <code>model</code> hadn't a <code>ViewPort</code>, assigns the current
684
     * one to it, otherwise, use its <code>ViewPort</code>.
685
     * </p>
686
     * 
687
     * <p>
688
     * After assigning the <code>MapContext</code> and <code>ViewPort</code>,
689
     * sets the same {@link MapContextListener MapContextListener} that was
690
     * using, and changes the <i>status</i> to <code>OUTDATED</code>.
691
     * </p>
692
     * 
693
     * @param model
694
     *            this component's <code>MapContext</code>, that includes the
695
     *            <code>ViewPort</code>.
696
     * 
697
     * @see MapContext
698
     * 
699
     * @see #getMapContext()
700
     */
701
    public void setMapContext(MapContext model) {
702
        if (mapContext != null) {
703
            mapContext.removeAtomicEventListener(mapContextListener);
704
            mapContext.dispose();
705
        }
706

  
707
        mapContext = model;
708

  
709
        if (mapContext.getViewPort() == null) {
710
            mapContext.setViewPort(vp);
711
        } else {
712
            vp = mapContext.getViewPort();
713
            cadgrid.setViewPort(vp);
714
        }
715

  
716
        mapContext.addAtomicEventListener(mapContextListener);
717

  
718
        status = DESACTUALIZADO;
719
    }
720

  
721
    /**
722
     * @return the mapControlDrawer
723
     */
724
    public MapControlDrawer getMapControlDrawer() {
725
        return mapControlDrawer;
726
    }
727

  
728
    /**
729
     * @param mapControlDrawer
730
     *            the mapControlDrawer to set
731
     */
732
    public void setMapControlDrawer(MapControlDrawer mapControlDrawer) {
733
        this.mapControlDrawer = mapControlDrawer;
734
        this.mapControlDrawer.setViewPort(vp);
735
    }
736

  
737
    /**
738
     * <p>
739
     * Gets this component's {@link MapContext MapContext} projection.
740
     * </p>
741
     * 
742
     * @return this component's {@link MapContext MapContext} projection
743
     * 
744
     * @see MapContext#getProjection()
745
     * @see MapControl#setProjection(IProjection)
746
     */
747
    public IProjection getProjection() {
748
        return getMapContext().getProjection();
749
    }
750

  
751
    /**
752
     * <p>
753
     * Sets the projection to this component's {@link MapContext MapContext}.
754
     * </p>
755
     * 
756
     * @param proj
757
     *            the kind of projection to this component's {@link MapContext
758
     *            MapContext}
759
     * 
760
     * @see MapContext#setProjection(IProjection)
761
     * @see MapControl#getProjection()
762
     */
763
    public void setProjection(IProjection proj) {
764
        getMapContext().setProjection(proj);
765
    }
766

  
767
    /**
768
     * <p>
769
     * Gets this component's <code>MapContext</code>, with the <i>model</i>, and
770
     * most of the <i>view</i>, and <i>control</i> logic of the layers of this
771
     * component, including a {@link ViewPort ViewPort} to adapt the information
772
     * to the projection, and display it in the available area.
773
     * </p>
774
     * 
775
     * @return this component's <code>MapContext</code>, that includes the
776
     *         <code>ViewPort</code> used to project the
777
     *         graphical information, and display it in the available area
778
     * 
779
     * @see MapContext
780
     * 
781
     * @see MapControl#setMapContext(MapContext)
782
     */
783
    public MapContext getMapContext() {
784
        return mapContext;
785
    }
786

  
787
    /**
788
     * <p>
789
     * Registers a new behavior to this component.
790
     * </p>
791
     * 
792
     * <p>
793
     * According the nature of the {@link Behavior Behavior}, different events
794
     * will be generated. Those events can be caught by a particular
795
     * {@link ToolListener ToolListener}, allowing user to interact with this
796
     * <code>MapControl</code> object as a <i>tool</i>.
797
     * </p>
798
     * 
799
     * @param name
800
     *            name to identify the behavior to add
801
     * @param tool
802
     *            the behavior to add
803
     * 
804
     * @see #addBehavior(String, Behavior[])
805
     * @see #getNamesMapTools()
806
     * @see #getMapToolsKeySet()
807
     * @see #hasTool(String)
808
     */
809
    public void addBehavior(String name, Behavior tool) {
810
        namesMapTools.put(name, tool);
811
        tool.setMapControl(this);
812
    }
813

  
814
    /**
815
     * <p>
816
     * Registers a new behavior to this component as a {@link CompoundBehavior
817
     * CompoundBehavior} made up of <code>tools</code>.
818
     * </p>
819
     * 
820
     * <p>
821
     * According the nature of the behaviors registered, different events will
822
     * be generated. Those events can be caught by a particular
823
     * {@link ToolListener ToolListener}, allowing user to interact with this
824
     * <code>MapControl</code> object as a <i>tool</i>.
825
     * </p>
826
     * 
827
     * @param name
828
     *            name to identify the compound behavior to add
829
     * @param tools
830
     *            the compound behavior to add
831
     * 
832
     * @see #addBehavior(String, Behavior)
833
     * @see #getNamesMapTools()
834
     * @see #getMapToolsKeySet()
835
     * @see #hasTool(String)
836
     */
837
    public void addBehavior(String name, Behavior[] tools) {
838
        CompoundBehavior tool = new CompoundBehavior(tools);
839
        addBehavior(name, tool);
840
    }
841

  
842
    /**
843
     * <p>
844
     * Gets the <code>Behavior</code> registered in this component, identified
845
     * by <code>name</code>.
846
     * </p>
847
     * 
848
     * @param name
849
     *            name of a registered behavior
850
     * 
851
     * @return tool the registered behavior in this component as
852
     *         <code>name</code>, or <code>null</code> if
853
     *         no one has that identifier
854
     * 
855
     * @see #addBehavior(String, Behavior)
856
     * @see #addBehavior(String, Behavior[])
857
     * @see #hasTool(String)
858
     */
859
    public Behavior getMapTool(String name) {
860
        return (Behavior) namesMapTools.get(name);
861
    }
862

  
863
    /**
864
     * <p>
865
     * Returns a set view of the keys that identified the tools registered.
866
     * </p>
867
     * 
868
     * @return a set view of the keys that identified the tools registered
869
     * 
870
     * @see HashMap#keySet()
871
     * 
872
     * @see #getNamesMapTools()
873
     * @see #addBehavior(String, Behavior)
874
     * @see #addBehavior(String, Behavior[])
875
     */
876
    public Set getMapToolsKeySet() {
877
        return namesMapTools.keySet();
878
    }
879

  
880
    /**
881
     * <p>
882
     * Returns <code>true</code> if this component contains a tool identified by
883
     * <code>toolName</code>.
884
     * </p>
885
     * 
886
     * @param toolName
887
     *            identifier of the tool
888
     * 
889
     * @return <code>true</code> if this component contains a tool identified by
890
     *         <code>toolName</code>; otherwise <code>false</code>
891
     * 
892
     * @see #addBehavior(String, Behavior)
893
     * @see #addBehavior(String, Behavior[])
894
     */
895
    public boolean hasTool(String toolName) {
896
        return namesMapTools.containsKey(toolName);
897
    }
898

  
899
    /**
900
     * <p>
901
     * Sets as current active <code>Behavior</code> associated to this
902
     * component, that one which is registered and identified by
903
     * <code>toolName</code>.
904
     * </p>
905
     * 
906
     * <p>
907
     * Changing the current active behavior for this <code>MapControl</code>,
908
     * implies also updating the previous <i>behavior</i> tool, and the current
909
     * cursor.
910
     * </p>
911
     * 
912
     * @param toolName
913
     *            name of a registered behavior
914
     * 
915
     * @see #getCurrentMapTool()
916
     * @see #getCurrentTool()
917
     */
918
    public void setTool(String toolName) {
919
        prevTool = getCurrentTool();
920
        Behavior mapTool = (Behavior) namesMapTools.get(toolName);
921
        currentMapTool = mapTool;
922
        currentTool = toolName;
923

  
924
        if (combinedTool != null) {
925
            if (mapTool instanceof CompoundBehavior) {
926
                ((CompoundBehavior) mapTool).addMapBehavior(combinedTool, true);
927
            } else {
928
                currentMapTool =
929
                    new CompoundBehavior(new Behavior[] { currentMapTool });
930
                ((CompoundBehavior) currentMapTool).addMapBehavior(
931
                    combinedTool, true);
932
            }
933
        }
934

  
935
        // this.setCursor(mapTool.getCursor());
936
    }
937

  
938
    /**
939
     * <p>
940
     * Gets as current active <code>Behavior</code> associated to this
941
     * component, that one which is registered and identified by
942
     * <code>toolName</code>.
943
     * </p>
944
     * 
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff