root / trunk / extensions / extSymbology / src / org / gvsig / symbology / fmap / symbols / GradientFillSymbol.java @ 29244
History | View | Annotate | Download (9.18 KB)
1 | 20768 | jdominguez | /* 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.symbology.fmap.symbols; |
||
42 | |||
43 | import java.awt.BasicStroke; |
||
44 | import java.awt.Color; |
||
45 | import java.awt.Graphics2D; |
||
46 | import java.awt.Rectangle; |
||
47 | import java.awt.Shape; |
||
48 | import java.awt.geom.AffineTransform; |
||
49 | import java.awt.geom.Ellipse2D; |
||
50 | import java.awt.geom.Line2D; |
||
51 | import java.awt.geom.Rectangle2D; |
||
52 | |||
53 | import javax.print.attribute.PrintRequestAttributeSet; |
||
54 | |||
55 | 28369 | vcaballero | import com.iver.cit.gvsig.fmap.core.FPoint2D; |
56 | 20768 | jdominguez | import com.iver.cit.gvsig.fmap.core.FPolygon2D; |
57 | import com.iver.cit.gvsig.fmap.core.FShape; |
||
58 | import com.iver.cit.gvsig.fmap.core.GeneralPathX; |
||
59 | import com.iver.cit.gvsig.fmap.core.SymbologyFactory; |
||
60 | import com.iver.cit.gvsig.fmap.core.symbols.AbstractFillSymbol; |
||
61 | import com.iver.cit.gvsig.fmap.core.symbols.ILineSymbol; |
||
62 | import com.iver.cit.gvsig.fmap.core.symbols.ISymbol; |
||
63 | import com.iver.cit.gvsig.fmap.core.symbols.SimpleFillSymbol; |
||
64 | import com.iver.cit.gvsig.fmap.core.symbols.SymbolDrawingException; |
||
65 | import com.iver.utiles.StringUtilities; |
||
66 | import com.iver.utiles.XMLEntity; |
||
67 | import com.iver.utiles.swing.threads.Cancellable; |
||
68 | |||
69 | /**
|
||
70 | *
|
||
71 | * Allows the user to fill a polygon with a gradient color.This gradient
|
||
72 | * can be painted with 4 different methods (linal, rectangular, circular and
|
||
73 | * buffered) and, for each one will be possible to modify its angle, percentage
|
||
74 | * and intervals.
|
||
75 | *
|
||
76 | * @author pepe vidal salvador - jose.vidal.salvador@iver.es
|
||
77 | */
|
||
78 | public class GradientFillSymbol extends AbstractFillSymbol { |
||
79 | |||
80 | private GradientFillSymbol gradsym;
|
||
81 | private SimpleFillSymbol sfs = new SimpleFillSymbol(); |
||
82 | |||
83 | private double angle; |
||
84 | private double percentage = 100; |
||
85 | private int intervals; |
||
86 | 22784 | vcaballero | private Color[] gradientColor=null; |
87 | 20768 | jdominguez | |
88 | private int style; |
||
89 | 28369 | vcaballero | private PrintRequestAttributeSet properties; |
90 | 20768 | jdominguez | |
91 | public ISymbol getSymbolForSelection() {
|
||
92 | |||
93 | if (gradsym==null)gradsym=new GradientFillSymbol(); |
||
94 | return gradsym;
|
||
95 | |||
96 | } |
||
97 | |||
98 | |||
99 | public void draw(Graphics2D g, AffineTransform affineTransform, FShape shp, Cancellable cancel) { |
||
100 | |||
101 | Rectangle2D bounds = shp.getBounds();
|
||
102 | double radius = Math.abs(Math.max(bounds.getHeight(), bounds.getWidth())); |
||
103 | double centerX = bounds.getCenterX();
|
||
104 | double centerY = bounds.getCenterY();
|
||
105 | 22749 | vcaballero | |
106 | 23783 | vcaballero | if(gradientColor != null) |
107 | setFillColor(gradientColor[0]);
|
||
108 | 20768 | jdominguez | g.fill(shp); |
109 | 22749 | vcaballero | |
110 | 20768 | jdominguez | g.setClip(shp); |
111 | |||
112 | if (radius <= 1) { |
||
113 | 23783 | vcaballero | if(gradientColor != null) |
114 | g.setColor(gradientColor[0]);
|
||
115 | 20768 | jdominguez | g.drawLine((int) centerX, (int) centerY, (int) centerX, (int) centerY); |
116 | return;
|
||
117 | } |
||
118 | |||
119 | /*Creation of a new shape depending on the style of the gradient*/
|
||
120 | Shape myShape = null; |
||
121 | if (style==0) {//Style=buffered |
||
122 | myShape = shp; |
||
123 | } else if (style==1) {//Style=lineal |
||
124 | myShape = new Line2D.Double(bounds.getMinX(), bounds.getMaxY(), bounds.getMaxX(), bounds.getMaxY()); |
||
125 | } else if (style==2) {//Style=circular |
||
126 | myShape = new Ellipse2D.Double(bounds.getMinX(), bounds.getMinY(), radius, radius); |
||
127 | } else if (style==3) {//Style=rectangular |
||
128 | myShape = shp.getBounds(); |
||
129 | } |
||
130 | |||
131 | if (intervals == 0) intervals = 1; |
||
132 | |||
133 | /*The variable separation will be used to specify the width of the line*/
|
||
134 | int separation=(int) Math.abs(Math.min(bounds.getHeight(), bounds.getWidth()))/(int)intervals; |
||
135 | /*If the style is linal the separation will be double*/
|
||
136 | if (style==1)separation*=2; |
||
137 | |||
138 | /*If the user wants to apply a rotation*/
|
||
139 | boolean bRotate = angle != 0; |
||
140 | |||
141 | /*All the intervals are painted*/
|
||
142 | for (int i = intervals; (cancel==null || !cancel.isCanceled()) && i>0 ; i--) { |
||
143 | BasicStroke stroke = new BasicStroke((float) (separation*i*percentage*0.01)+1); |
||
144 | |||
145 | FShape fShape = new FPolygon2D(
|
||
146 | new GeneralPathX(stroke.createStrokedShape(myShape)));
|
||
147 | |||
148 | double cenX,cenY;
|
||
149 | cenX = fShape.getBounds().getCenterX(); |
||
150 | cenY = fShape.getBounds().getCenterY(); |
||
151 | 22749 | vcaballero | |
152 | 20768 | jdominguez | if (bRotate) {
|
153 | |||
154 | g.translate(cenX, cenY); |
||
155 | g.rotate(angle); |
||
156 | |||
157 | fShape.transform(AffineTransform.getTranslateInstance(-cenX,-cenY));
|
||
158 | 22749 | vcaballero | |
159 | 20768 | jdominguez | } |
160 | 23783 | vcaballero | if(gradientColor != null) |
161 | sfs.setFillColor(gradientColor[i-1]);
|
||
162 | 20768 | jdominguez | sfs.draw(g, affineTransform, fShape, cancel); |
163 | |||
164 | |||
165 | if (bRotate) {
|
||
166 | |||
167 | g.rotate(-angle); |
||
168 | g.translate(-cenX, -cenY); |
||
169 | } |
||
170 | } |
||
171 | |||
172 | g.setClip(null);
|
||
173 | |||
174 | /*If an outline exists it is painted*/
|
||
175 | ILineSymbol outLineSymbol = getOutline(); |
||
176 | if (outLineSymbol != null && hasOutline()) |
||
177 | outLineSymbol.draw(g, affineTransform, shp, null);
|
||
178 | } |
||
179 | |||
180 | public XMLEntity getXMLEntity() {
|
||
181 | |||
182 | XMLEntity xml = new XMLEntity();
|
||
183 | |||
184 | xml.putProperty("className", getClassName());
|
||
185 | xml.putProperty("desc", getDescription());
|
||
186 | xml.putProperty("isShapeVisible", isShapeVisible());
|
||
187 | xml.putProperty("angle", angle);
|
||
188 | xml.putProperty("intervals",intervals);
|
||
189 | xml.putProperty("percentage", percentage);
|
||
190 | xml.putProperty("style", style);
|
||
191 | xml.putProperty("referenceSystem", getReferenceSystem());
|
||
192 | xml.putProperty("unit", getUnit());
|
||
193 | |||
194 | 22784 | vcaballero | if(gradientColor != null){ |
195 | String[] strColors = new String[gradientColor.length]; |
||
196 | 22749 | vcaballero | for (int i = 0; i < strColors.length; i++) { |
197 | 22784 | vcaballero | strColors[i] = StringUtilities.color2String(gradientColor[i]); |
198 | 22749 | vcaballero | } |
199 | 22784 | vcaballero | xml.putProperty("gradientColor", strColors);
|
200 | 20768 | jdominguez | } |
201 | |||
202 | Color c2 = getFillColor();
|
||
203 | if (c2!=null) |
||
204 | xml.putProperty("color", StringUtilities.color2String(getFillColor()));
|
||
205 | |||
206 | ILineSymbol outline = getOutline(); |
||
207 | |||
208 | if (outline!=null) { |
||
209 | XMLEntity xmlOutline = outline.getXMLEntity(); |
||
210 | xmlOutline.putProperty("id", "outline"); |
||
211 | xml.addChild(xmlOutline); |
||
212 | } |
||
213 | 22749 | vcaballero | |
214 | 20768 | jdominguez | xml.putProperty("hasOutline", hasOutline());
|
215 | |||
216 | return xml;
|
||
217 | } |
||
218 | |||
219 | public void setXMLEntity(XMLEntity xml) { |
||
220 | |||
221 | if (xml.contains("color")) |
||
222 | setFillColor(StringUtilities.string2Color(xml.getStringProperty("color")));
|
||
223 | |||
224 | |||
225 | setDescription(xml.getStringProperty("desc"));
|
||
226 | setIsShapeVisible(xml.getBooleanProperty("isShapeVisible"));
|
||
227 | setAngle(xml.getDoubleProperty("angle"));
|
||
228 | setStyle(xml.getIntProperty("style"));
|
||
229 | setIntervals(xml.getIntProperty("intervals"));
|
||
230 | setPercentage(xml.getDoubleProperty("percentage"));
|
||
231 | 22749 | vcaballero | if(xml.contains("gradientColor")){ |
232 | 22784 | vcaballero | String[] strColors = xml.getStringArrayProperty("gradientColor"); |
233 | 20768 | jdominguez | |
234 | 22749 | vcaballero | Color[] cc = new Color[strColors.length]; |
235 | for (int i = 0; i < cc.length; i++) { |
||
236 | cc[i] = StringUtilities.string2Color(strColors[i]); |
||
237 | } |
||
238 | setGradientColor(cc); |
||
239 | 20768 | jdominguez | |
240 | } |
||
241 | |||
242 | XMLEntity xmlOutline = xml.firstChild("id", "outline"); |
||
243 | if (xmlOutline != null) { |
||
244 | setOutline((ILineSymbol) SymbologyFactory. |
||
245 | createSymbolFromXML(xmlOutline, "outline"));
|
||
246 | } |
||
247 | 22749 | vcaballero | |
248 | 20768 | jdominguez | if (xml.contains("unit")) { // remove this line when done |
249 | 22749 | vcaballero | |
250 | // measure unit (for outline)
|
||
251 | setUnit(xml.getIntProperty("unit"));
|
||
252 | |||
253 | // reference system (for outline)
|
||
254 | setReferenceSystem(xml.getIntProperty("referenceSystem"));
|
||
255 | 20768 | jdominguez | } |
256 | //has Outline
|
||
257 | if(xml.contains("hasOutline")) |
||
258 | setHasOutline(xml.getBooleanProperty("hasOutline"));
|
||
259 | } |
||
260 | |||
261 | |||
262 | |||
263 | |||
264 | public int getSymbolType() { |
||
265 | return FShape.POLYGON;
|
||
266 | } |
||
267 | |||
268 | 28369 | vcaballero | public void drawInsideRectangle(Graphics2D g,AffineTransform scaleInstance, Rectangle r, PrintRequestAttributeSet properties) throws SymbolDrawingException { |
269 | if (properties==null) |
||
270 | draw(g, null, new FPolygon2D(new GeneralPathX(r)), null); |
||
271 | else
|
||
272 | print(g, new AffineTransform(), new FPolygon2D(new GeneralPathX(r)), properties); |
||
273 | 20768 | jdominguez | } |
274 | |||
275 | |||
276 | public String getClassName() { |
||
277 | return getClass().getName();
|
||
278 | } |
||
279 | |||
280 | 28369 | vcaballero | public void print(Graphics2D g, AffineTransform at, FShape shape, PrintRequestAttributeSet properties) { |
281 | this.properties=properties;
|
||
282 | 29244 | vcaballero | draw(g, at, shape, null);
|
283 | 28369 | vcaballero | this.properties=null; |
284 | 20768 | jdominguez | } |
285 | |||
286 | /**
|
||
287 | * Defines the angle for the rotation of the image when it is added to create the
|
||
288 | * padding
|
||
289 | *
|
||
290 | * @return angle
|
||
291 | */
|
||
292 | public double getAngle() { |
||
293 | return angle;
|
||
294 | } |
||
295 | /**
|
||
296 | * Sets the angle for the rotation of the image when it is added to create the padding
|
||
297 | * @param angle
|
||
298 | */
|
||
299 | public void setAngle(double angle) { |
||
300 | this.angle = angle;
|
||
301 | } |
||
302 | |||
303 | public double getPercentage() { |
||
304 | return percentage;
|
||
305 | } |
||
306 | |||
307 | public void setPercentage(double percentage) { |
||
308 | this.percentage= percentage;
|
||
309 | } |
||
310 | |||
311 | public int getIntervals() { |
||
312 | return intervals;
|
||
313 | } |
||
314 | |||
315 | public void setIntervals(int intervals) { |
||
316 | this.intervals= intervals;
|
||
317 | } |
||
318 | |||
319 | public int getStyle(){ |
||
320 | |||
321 | return style;
|
||
322 | |||
323 | } |
||
324 | public void setStyle(int style) { |
||
325 | |||
326 | this.style=style;
|
||
327 | } |
||
328 | |||
329 | public Color[] getGradientColor(){ |
||
330 | |||
331 | 22784 | vcaballero | return gradientColor;
|
332 | 20768 | jdominguez | } |
333 | |||
334 | public void setGradientColor(Color[] gradientcolor) { |
||
335 | 22784 | vcaballero | this.gradientColor=gradientcolor;
|
336 | 20768 | jdominguez | } |
337 | |||
338 | } |