Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / MapControl.java @ 7679

History | View | Annotate | Download (27.3 KB)

1 1223 fernando
/* 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 com.iver.cit.gvsig.fmap;
42
43 1282 fjp
import java.awt.Color;
44 6266 fjp
import java.awt.Component;
45 1223 fernando
import java.awt.Dimension;
46
import java.awt.Graphics;
47
import java.awt.Graphics2D;
48 6212 fjp
import java.awt.GraphicsEnvironment;
49 1223 fernando
import java.awt.event.ActionEvent;
50
import java.awt.event.ActionListener;
51
import java.awt.event.ComponentEvent;
52
import java.awt.event.ComponentListener;
53
import java.awt.event.MouseEvent;
54
import java.awt.event.MouseListener;
55
import java.awt.event.MouseMotionListener;
56
import java.awt.event.MouseWheelEvent;
57
import java.awt.event.MouseWheelListener;
58 5874 fjp
import java.awt.geom.Point2D;
59
import java.awt.geom.Rectangle2D;
60 1223 fernando
import java.awt.image.BufferedImage;
61
import java.util.HashMap;
62 6777 jmvivo
import java.util.Set;
63 1223 fernando
64
import javax.swing.JComponent;
65
import javax.swing.Timer;
66
67
import org.cresques.cts.IProjection;
68
69 6164 luisw2
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
70 4120 caballero
import com.iver.cit.gvsig.fmap.edition.commands.CommandListener;
71 1223 fernando
import com.iver.cit.gvsig.fmap.layers.LayerEvent;
72
import com.iver.cit.gvsig.fmap.tools.BehaviorException;
73
import com.iver.cit.gvsig.fmap.tools.CompoundBehavior;
74
import com.iver.cit.gvsig.fmap.tools.Behavior.Behavior;
75
import com.iver.utiles.exceptionHandling.ExceptionHandlingSupport;
76
import com.iver.utiles.exceptionHandling.ExceptionListener;
77 5317 fjp
import com.iver.utiles.swing.threads.Cancellable;
78 1223 fernando
79
80
/**
81
 * MapControl.
82
 *
83
 * @author Fernando Gonz?lez Cort?s
84
 */
85 5874 fjp
public class MapControl extends JComponent implements ComponentListener,
86
                        CommandListener {
87 1223 fernando
        /** Cuando la vista est? actualizada. */
88
        public static final int ACTUALIZADO = 0;
89
90
        /** Cuando la vista est? desactualizada. */
91
        public static final int DESACTUALIZADO = 1;
92 2901 fjp
    public static final int ONLY_GRAPHICS = 2;
93 3346 fjp
    // public static final int FAST_PAINT = 3;
94 2531 caballero
        //private static Logger logger = Logger.getLogger(MapControl.class.getName());
95 6878 cesar
        private MapContext mapContext = null;
96 3719 caballero
    //private boolean drawerAlive = false;
97 1223 fernando
        private HashMap namesMapTools = new HashMap();
98
        private Behavior currentMapTool = null;
99
        private int status = DESACTUALIZADO;
100
        private BufferedImage image = null;
101
        private String currentTool;
102
        private CancelDraw canceldraw;
103 3719 caballero
        //private boolean isCancelled = true;
104 1223 fernando
        private Timer timer;
105
        protected ViewPort vp;
106 3719 caballero
        //private Drawer drawer;
107 3368 fjp
    private Drawer2 drawer2;
108 3372 fjp
    // private boolean firstDraw = true;
109 1223 fernando
        private MapToolListener mapToolListener = new MapToolListener();
110
        private MapContextListener mapContextListener = new MapContextListener();
111
        private ExceptionHandlingSupport exceptionHandlingSupport = new ExceptionHandlingSupport();
112 4619 caballero
113 4888 caballero
        private String prevTool;
114
115 3719 caballero
        /**
116 3331 fjp
     * We need this to avoid not wanted refresh. REMEMBER TO SET TO TRUE!!
117
     */
118
    // private boolean paintEnabled = false;
119 1223 fernando
120
        /**
121
         * Crea un nuevo NewMapControl.
122
         */
123
        public MapControl() {
124 5787 jaume
                this.setName("MapControl");
125 1223 fernando
                setDoubleBuffered(false);
126
                setOpaque(true);
127
                status = DESACTUALIZADO;
128
129
                //Clase usada para cancelar el dibujado
130
                canceldraw = new CancelDraw();
131
132
                //Modelo de datos y ventana del mismo
133
                // TODO: Cuando creamos un mapControl, deber?amos asignar
134
                // la projecci?n por defecto con la que vayamos a trabajar.
135
                // 23030 es el c?digo EPSG del UTM30 elipsoide ED50
136 6164 luisw2
                vp = new ViewPort(CRSFactory.getCRS("EPSG:23030"));
137 6878 cesar
                setMapContext(new MapContext(vp));
138 3719 caballero
139 1223 fernando
                //eventos
140
                this.addComponentListener(this);
141
                this.addMouseListener(mapToolListener);
142
                this.addMouseMotionListener(mapToolListener);
143
                this.addMouseWheelListener(mapToolListener);
144
145 3368 fjp
        this.drawer2 = new Drawer2();
146 1223 fernando
                //Timer para mostrar el redibujado mientras se dibuja
147 7679 fjp
                timer = new Timer(360,
148 1223 fernando
                                new ActionListener() {
149
                                        public void actionPerformed(ActionEvent e) {
150
                                                MapControl.this.repaint();
151
                                        }
152
                                });
153
        }
154
155
        /**
156
         * Inserta el modelo.
157
         *
158
         * @param model FMap.
159
         */
160 6878 cesar
        public void setMapContext(MapContext model) {
161 1223 fernando
                if (mapContext != null) {
162
                        mapContext.removeAtomicEventListener(mapContextListener);
163
                }
164
165
                mapContext = model;
166
167
                if (mapContext.getViewPort() == null) {
168
                        mapContext.setViewPort(vp);
169
                } else {
170
                        vp = mapContext.getViewPort();
171
172
                        // vp.setImageSize(new Dimension(getWidth(), getHeight()));
173
                        //System.err.println("Viewport en setMapContext:" + vp);
174
                }
175
176
                mapContext.addAtomicEventListener(mapContextListener);
177
178
                status = DESACTUALIZADO;
179
        }
180
181
        /**
182
         * Devuelve la proyecci?n.
183
         *
184
         * @return Proyecci?n.
185
         */
186
        public IProjection getProjection() {
187
                return getMapContext().getProjection();
188
        }
189
190
        /**
191
         * Inserta una proyecci?n.
192
         *
193
         * @param proj Proyecci?n.
194
         */
195
        public void setProjection(IProjection proj) {
196
                getMapContext().setProjection(proj);
197
        }
198
199
        /**
200
         * Devuelve el modelo.
201
         *
202
         * @return FMap.
203
         */
204 6878 cesar
        public MapContext getMapContext() {
205 1223 fernando
                return mapContext;
206
        }
207
208
        /**
209
         * Registra una herramienta (tool).
210
         *
211
         * @param name Nombre de la herramienta.
212
         * @param tool Herramienta.
213
         */
214
        public void addMapTool(String name, Behavior tool) {
215
                namesMapTools.put(name, tool);
216
                tool.setMapControl(this);
217
        }
218
219
        public void addMapTool(String name, Behavior[] tools){
220
                CompoundBehavior tool = new CompoundBehavior(tools);
221
                addMapTool(name, tool);
222
        }
223 6777 jmvivo
224
        /**
225
         * Devuelve una herramienta (tool) registrada.
226
         *
227
         * @param name Nombre de la herramienta.
228
         * @return tool Herramienta.
229
         */
230
        public Behavior getMapTool(String name) {
231
                return (Behavior)namesMapTools.get(name);
232
        }
233 3719 caballero
234 1223 fernando
        /**
235 6777 jmvivo
         * Devuelve los nombres de herramientas (tool) registradas.
236
         *
237
         * @return Set (String) nombres de las herramientas.
238
         */
239
        public Set getMapToolsKeySet() {
240
                return namesMapTools.keySet();
241
        }
242
243
244
        /**
245 6378 jaume
         * Returns true if this map control contains a tool named with the value
246
         * passed in the toolName parameter. If you have added two tools with the
247
         * same name, the last tool will overwrite the previous ones.
248
         * @param toolName
249
         * @return true if the map control contains a tool with the same name than
250
         *                 toolName. False, otherwise.
251
         */
252
        public boolean hasTool(String toolName) {
253
                return namesMapTools.containsKey(toolName);
254
        }
255
        /**
256 1223 fernando
         * DOCUMENT ME!
257
         *
258
         * @param toolName DOCUMENT ME!
259
         */
260
        public void setTool(String toolName) {
261 6378 jaume
                prevTool=getCurrentTool();
262 1223 fernando
                Behavior mapTool = (Behavior) namesMapTools.get(toolName);
263
                currentMapTool = mapTool;
264
                currentTool = toolName;
265
                this.setCursor(mapTool.getCursor());
266
        }
267 3719 caballero
        public Behavior getCurrentMapTool(){
268
                return currentMapTool;
269
        }
270 1223 fernando
        /**
271 6378 jaume
         * Returns the name of the current selected tool on this MapControl
272 1223 fernando
         *
273 6378 jaume
         * @return A tool name.
274 1223 fernando
         */
275 6378 jaume
        public String getCurrentTool() {
276 1223 fernando
                return currentTool;
277
        }
278 6777 jmvivo
279 1223 fernando
280
        /**
281
         * Cancela el dibujado. Se espera a que la cancelaci?n surta efecto
282
         */
283
        public void cancelDrawing() {
284 3368 fjp
                /* if (drawer != null) {
285 1223 fernando
                        if (!drawer.isAlive()) {
286
                                return;
287
                        }
288
                }
289 3368 fjp
                */
290 4832 fjp
                canceldraw.setCanceled(true);
291 1223 fernando
292 3368 fjp
                /* while (!isCancelled) {
293 1243 fjp
                        if (!drawer.isAlive()) {
294 1327 fjp
                            // Si hemos llegado aqu? con un thread vivo, seguramente
295
                            // no estamos actualizados.
296

297
                                break;
298 1243 fjp
                        }
299 3719 caballero

300 1223 fernando
                }
301
                canceldraw.setCancel(false);
302
                isCancelled = false;
303 3368 fjp
        drawerAlive = false; */
304 1223 fernando
        }
305 3719 caballero
306 3375 fjp
    private boolean adaptToImageSize()
307
    {
308
        if ((image == null) || (vp.getImageWidth() != this.getWidth()) || (vp.getImageHeight() != this.getHeight()))
309
        {
310
            image = new BufferedImage(this.getWidth(), this.getHeight(),
311
                    BufferedImage.TYPE_INT_ARGB);
312 6212 fjp
            // ESTILO MAC
313
//                image = GraphicsEnvironment.getLocalGraphicsEnvironment()
314
//                                .getDefaultScreenDevice().getDefaultConfiguration()
315
//                                .createCompatibleImage(this.getWidth(), this.getHeight());
316 3375 fjp
            vp.setImageSize(new Dimension(getWidth(), getHeight()));
317 6630 caballero
            getMapContext().getViewPort().refreshExtent();
318 3719 caballero
319
320 3375 fjp
            Graphics gTemp = image.createGraphics();
321
            Color theBackColor = vp.getBackColor();
322
            if (theBackColor == null)
323
                gTemp.setColor(Color.WHITE);
324
            else
325
                gTemp.setColor(theBackColor);
326 3719 caballero
327 3375 fjp
            gTemp.fillRect(0,0,getWidth(), getHeight());
328
            gTemp.dispose();
329
            status = DESACTUALIZADO;
330
            // g.drawImage(image,0,0,null);
331
            return true;
332
        }
333
        return false;
334
    }
335 1223 fernando
336
        /**
337
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
338
         */
339
        protected void paintComponent(Graphics g) {
340 3375 fjp
        adaptToImageSize();
341 3346 fjp
        /* if (status == FAST_PAINT) {
342 3331 fjp
            System.out.println("FAST_PAINT");
343
            g.drawImage(image,0,0,null);
344
            status = ACTUALIZADO;
345
            return;
346 3346 fjp
        } */
347 4568 fjp
        // System.out.println("PINTANDO MAPCONTROL" + this);
348 1223 fernando
                if (status == ACTUALIZADO) {
349 1680 luisw
                        // LWS logger.debug("Dibujando la imagen obtenida");
350 1223 fernando
351
                        /*
352
                         * Si hay un behaviour y la imagen es distinta de null se delega el dibujado
353
                         * en dicho behaviour
354
                         */
355 3372 fjp
            if (image != null)
356
            {
357
                if (currentMapTool != null)
358
                    currentMapTool.paintComponent(g);
359
                else
360
                    g.drawImage(image,0,0,null);
361 3719 caballero
362 3372 fjp
                                // System.out.println("Pinto ACTUALIZADO");
363 1223 fernando
                        }
364 3719 caballero
                } else if ((status == DESACTUALIZADO)
365 2946 fjp
                || (status == ONLY_GRAPHICS)) {
366 1680 luisw
                        // LWS System.out.println("DESACTUALIZADO: Obteniendo la imagen de la cartograf?a");
367 1223 fernando
                        /* if (isOpaque())
368
                        {
369
                            if (image==null)
370
                            {
371
                                g.setColor(vp.getBackColor());
372 3719 caballero
                                g.fillRect(0,0,getWidth(), getHeight());
373
                            }
374 1223 fernando
                            // else g.drawImage(image,0,0,null);
375
                        } */
376 3368 fjp
            // cancelDrawing();
377 1223 fernando
                        //Se crea la imagen con el color de fonde deseado
378 3375 fjp
                        /* if (image == null)
379 1223 fernando
                        {
380
                                image = new BufferedImage(this.getWidth(), this.getHeight(),
381
                                                BufferedImage.TYPE_INT_ARGB);
382
                                vp.setImageSize(new Dimension(getWidth(), getHeight()));
383
                                Graphics gTemp = image.createGraphics();
384 1303 fjp
                            Color theBackColor = vp.getBackColor();
385
                            if (theBackColor == null)
386
                                gTemp.setColor(Color.WHITE);
387
                            else
388
                                gTemp.setColor(theBackColor);
389 3719 caballero

390 1223 fernando
                                gTemp.fillRect(0,0,getWidth(), getHeight());
391
                                gTemp.dispose();
392
                                // g.drawImage(image,0,0,null);
393 3174 ldiaz
                                System.out.println("Imagen con null en DESACTUALIZADO. Width = " + this.getWidth());
394 3375 fjp
                        } */
395 3331 fjp
            // else
396
            // {
397 3719 caballero
398
399 3372 fjp
            // if (image != null)
400
            //  {
401 3331 fjp
                g.drawImage(image,0,0,null);
402 3719 caballero
403 3372 fjp
                drawer2.put(new PaintingRequest());
404
                timer.start();
405
            /* }
406
            else
407
                return; */
408 3331 fjp
            // }
409 3719 caballero
410 3368 fjp
            /* if (drawerAlive == false)
411 3331 fjp
            {
412
                drawer = new Drawer(image, canceldraw);
413
                drawer.start();
414 3719 caballero
                        //Se lanza el tread de dibujado
415 3368 fjp
            } */
416 3719 caballero
417 2946 fjp
                        // status = ACTUALIZADO;
418 1223 fernando
                }
419
        }
420
421
        /**
422
         * Devuelve la imagen de la vista.
423
         *
424
         * @return imagen.
425
         */
426
        public BufferedImage getImage() {
427
                return image;
428
        }
429
430
        /**
431
         * Marca el mapa para que en el pr?ximo redibujado se acceda a la
432
         * cartograf?a para reobtener la imagen
433 3422 fjp
         * @param doClear Solo deber?a ser true cuando se llama desde pan
434 1223 fernando
         */
435
        public void drawMap(boolean doClear) {
436 3979 caballero
                cancelDrawing();
437
                System.out.println("drawMap con doClear=" + doClear);
438 3346 fjp
        status = DESACTUALIZADO;
439 5923 fjp
        getMapContext().getLayers().setDirty(true);
440 3331 fjp
                if (doClear)
441
        {
442 3372 fjp
            // image = null; // Se usa para el PAN
443
            if (image != null)
444
            {
445
                Graphics2D g = image.createGraphics();
446
                Color theBackColor = vp.getBackColor();
447
                if (theBackColor == null)
448
                    g.setColor(Color.WHITE);
449
                else
450
                    g.setColor(theBackColor);
451
                g.fillRect(0, 0, vp.getImageWidth(), vp.getImageHeight());
452
                g.dispose();
453 3719 caballero
            }
454 3331 fjp
        }
455 1223 fernando
                repaint();
456
        }
457 6306 caballero
458 5923 fjp
        public void rePaintDirtyLayers()
459
        {
460
                cancelDrawing();
461
        status = DESACTUALIZADO;
462
        repaint();
463
        }
464 6306 caballero
465 2901 fjp
    public void drawGraphics() {
466
        status = ONLY_GRAPHICS;
467
        repaint();
468
    }
469 1223 fernando
470
        /**
471
         * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
472
         */
473
        public void componentHidden(ComponentEvent e) {
474
        }
475
476
        /**
477
         * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
478
         */
479
        public void componentMoved(ComponentEvent e) {
480
        }
481
482
        /**
483
         * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
484
         */
485
        public void componentResized(ComponentEvent e) {
486 3375 fjp
                /* image = new BufferedImage(this.getWidth(), this.getHeight(),
487 3719 caballero
                                BufferedImage.TYPE_INT_ARGB);
488 1223 fernando
                Graphics gTemp = image.createGraphics();
489
                gTemp.setColor(vp.getBackColor());
490 3372 fjp
                gTemp.fillRect(0,0,getWidth(), getHeight());
491
        System.out.println("MapControl resized");
492
            // image = null;
493 1223 fernando
            vp.setImageSize(new Dimension(getWidth(), getHeight()));
494 3375 fjp
                getMapContext().getViewPort().setScale(); */
495 3372 fjp
                // drawMap(true);
496 1223 fernando
        }
497
498
        /**
499
         * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
500
         */
501
        public void componentShown(ComponentEvent e) {
502
        }
503
504
        /**
505
         * A?ade un listener de tipo ExceptionListener.
506
         *
507
         * @param o ExceptionListener.
508
         */
509
        public void addExceptionListener(ExceptionListener o) {
510
                exceptionHandlingSupport.addExceptionListener(o);
511
        }
512
513
        /**
514
         * Borra la ExceptioListener que se pasa como par?metro.
515
         *
516
         * @param o ExceptionListener.
517
         *
518
         * @return True si se borra correctamente.
519
         */
520
        public boolean removeExceptionListener(ExceptionListener o) {
521
                return exceptionHandlingSupport.removeExceptionListener(o);
522
        }
523
524
        /**
525
         * Lanza una Excepci?n.
526
         *
527
         * @param t Excepci?n.
528
         */
529
        private void throwException(Throwable t) {
530
                exceptionHandlingSupport.throwException(t);
531
        }
532
533 3719 caballero
534 3368 fjp
    private class PaintingRequest
535
    {
536 3719 caballero
537 3372 fjp
        public PaintingRequest()
538 3368 fjp
        {
539
        }
540 3719 caballero
541 3368 fjp
        public void paint()
542
        {
543 3719 caballero
            try
544
            {
545 4832 fjp
                    canceldraw.setCanceled(false);
546 3372 fjp
                /* if (image == null)
547
                {
548
                    image = new BufferedImage(vp.getImageWidth(), vp.getImageHeight(),
549
                            BufferedImage.TYPE_INT_ARGB);
550
                    Graphics gTemp = image.createGraphics();
551
                    Color theBackColor = vp.getBackColor();
552
                    if (theBackColor == null)
553
                        gTemp.setColor(Color.WHITE);
554
                    else
555
                        gTemp.setColor(theBackColor);
556 3719 caballero

557 3372 fjp
                    gTemp.fillRect(0,0,getWidth(), getHeight());
558
                    gTemp.dispose();
559
                    // g.drawImage(image,0,0,null);
560
                    System.out.println("Imagen con null en DESACTUALIZADO. Width = " + this.getWidth());
561
                } */
562 3368 fjp
                Graphics2D g = image.createGraphics();
563 3719 caballero
564 3368 fjp
                ViewPort viewPort = mapContext.getViewPort();
565 3719 caballero
566 3368 fjp
                if (status == DESACTUALIZADO)
567
                {
568 5874 fjp
                        Graphics2D gTemp = image.createGraphics();
569 3368 fjp
                    Color theBackColor = viewPort.getBackColor();
570
                    if (theBackColor == null)
571 5874 fjp
                        gTemp.setColor(Color.WHITE);
572 3368 fjp
                    else
573 5874 fjp
                        gTemp.setColor(theBackColor);
574
                    gTemp.fillRect(0, 0, viewPort.getImageWidth(), viewPort.getImageHeight());
575 3368 fjp
                    status = ACTUALIZADO;
576 6261 fjp
                    // ESTILO MAC
577
//                    BufferedImage imgMac = new BufferedImage(vp.getImageWidth(), vp.getImageHeight(),
578
//                            BufferedImage.TYPE_INT_ARGB);
579 6306 caballero
//
580 6261 fjp
//                    mapContext.draw(imgMac, g, canceldraw, mapContext.getScaleView());
581
//                    g.drawImage(imgMac, 0, 0, null);
582
                    // FIN ESTILO MAC
583
                    // SIN MAC:
584 3372 fjp
                    mapContext.draw(image, g, canceldraw, mapContext.getScaleView());
585 3719 caballero
586 3368 fjp
                }
587
                else if (status == ONLY_GRAPHICS)
588
                {
589 3719 caballero
                    status = ACTUALIZADO;
590 3372 fjp
                    mapContext.drawGraphics(image, g, canceldraw,mapContext.getScaleView());
591 3719 caballero
592 3368 fjp
                }
593 3719 caballero
594
595 3368 fjp
                // status = FAST_PAINT;
596 3719 caballero
              //  drawerAlive = false;
597 3372 fjp
                timer.stop();
598 3368 fjp
                repaint();
599 3719 caballero
600
601 3368 fjp
            } catch (Throwable e) {
602
                timer.stop();
603 3719 caballero
              //  isCancelled = true;
604 3368 fjp
                e.printStackTrace();
605
                throwException(e);
606
            } finally {
607
            }
608 3719 caballero
609 3368 fjp
        }
610 3719 caballero
611 3368 fjp
    }
612 3719 caballero
613 3368 fjp
    /**
614
     * @author fjp
615 3719 caballero
     *
616 3368 fjp
     * Basasdo en el patr?n WorkerThread
617
     *
618
     */
619
    public class Drawer2
620
    {
621
        // Una mini cola de 2. No acumulamos peticiones de dibujado
622
        // dibujamos solo lo ?ltimo que nos han pedido.
623
        private PaintingRequest paintingRequest;
624
        private PaintingRequest waitingRequest;
625 3719 caballero
626 3368 fjp
        private boolean waiting;
627
        private boolean shutdown;
628 3719 caballero
629 3368 fjp
        public void setShutdown(boolean isShutdown)
630
        {
631
            shutdown = isShutdown;
632
        }
633 3719 caballero
634
        public Drawer2()
635 3368 fjp
        {
636
            paintingRequest = null;
637
            waitingRequest = null;
638
            waiting = false;
639
            shutdown = false;
640
            new Thread(new Worker()).start();
641
        }
642 3719 caballero
643 3368 fjp
        public void put(PaintingRequest newPaintRequest)
644
        {
645
            waitingRequest = newPaintRequest;
646
            if (waiting)
647
            {
648
                synchronized (this) {
649
                    notifyAll();
650
                }
651
            }
652
        }
653 3719 caballero
654 3368 fjp
        public PaintingRequest take()
655
        {
656
            if (waitingRequest == null)
657
            {
658
                synchronized (this) {
659
                    waiting = true;
660
                    try {
661
                        wait();
662
                    }
663
                    catch (InterruptedException ie)
664
                    {
665
                        waiting = false;
666
                    }
667
                }
668
            }
669
            paintingRequest = waitingRequest;
670
            waitingRequest = null;
671
            return paintingRequest;
672
        }
673 3719 caballero
674
675 3368 fjp
        private class Worker implements Runnable
676
        {
677
            public void run()
678
            {
679
                while (!shutdown)
680
                {
681
                    PaintingRequest p = take();
682
                    System.out.println("Pintando");
683 4120 caballero
                    if (image != null){
684
                            cancelDrawing();
685 3372 fjp
                        p.paint();
686 4120 caballero
                    } else
687 3372 fjp
                        status = DESACTUALIZADO;
688 3368 fjp
                }
689
            }
690
        }
691
    }
692 3719 caballero
693 1223 fernando
        /**
694
         * Clase utilizada para dibujar las capas.
695
         *
696
         * @author Vicente Caballero Navarro
697
         */
698
        public class Drawer extends Thread {
699 2531 caballero
                //private Graphics g;
700 3331 fjp
                private BufferedImage image = null;
701 1223 fernando
                private CancelDraw cancel;
702 2531 caballero
                //private boolean threadCancel = false;
703 1223 fernando
704
                /**
705
                 * Crea un nuevo Drawer.
706
                 *
707
                 */
708 3331 fjp
                public Drawer(BufferedImage image, CancelDraw cancel)
709
        {
710 1223 fernando
                        this.image = image;
711
                        this.cancel = cancel;
712 3719 caballero
         //   drawerAlive = true;
713 1223 fernando
                }
714
715
                /**
716
                 * @see java.lang.Runnable#run()
717
                 */
718
                public void run() {
719
                        try {
720 2857 jaume
                                // synchronized (Drawer.class) {
721 1282 fjp
                                    Graphics2D g = image.createGraphics();
722 3719 caballero
723 1282 fjp
                                    ViewPort viewPort = mapContext.getViewPort();
724 2946 fjp
                    if (status == DESACTUALIZADO)
725
                    {
726
                                        Color theBackColor = viewPort.getBackColor();
727
                                        if (theBackColor == null)
728
                                            g.setColor(Color.WHITE);
729
                                        else
730
                                            g.setColor(theBackColor);
731
                                            g.fillRect(0, 0, viewPort.getImageWidth(), viewPort.getImageHeight());
732
                        status = ACTUALIZADO;
733
                        mapContext.draw(image, g, cancel,mapContext.getScaleView());
734
                    }
735
                    else if (status == ONLY_GRAPHICS)
736
                    {
737 2951 fjp
                        status = ACTUALIZADO;
738 2946 fjp
                        mapContext.drawGraphics(image, g, cancel,mapContext.getScaleView());
739
                    }
740 3719 caballero
741 1327 fjp
                                        timer.stop();
742 3346 fjp
                    // status = FAST_PAINT;
743 3719 caballero
                  //  drawerAlive = false;
744 1223 fernando
                                        repaint();
745 3719 caballero
746
747
748 2857 jaume
                                // }
749 1223 fernando
                        } catch (Throwable e) {
750 1266 fernando
                            timer.stop();
751 3719 caballero
                                //isCancelled = true;
752 2943 fjp
                e.printStackTrace();
753 1223 fernando
                                throwException(e);
754
                        } finally {
755
                        }
756
                }
757
        }
758
759
        /**
760
         * Clase para cancelar el dibujado.
761
         *
762
         * @author Fernando Gonz?lez Cort?s
763
         */
764
        public class CancelDraw implements Cancellable {
765
                private boolean cancel = false;
766
767
                /**
768
                 * Crea un nuevo CancelDraw.
769
                 */
770
                public CancelDraw() {
771
                }
772
773
                /**
774
                 * Insertar si se debe cancelar el dibujado.
775
                 *
776
                 * @param b true si se debe cancelar el dibujado.
777
                 */
778 4832 fjp
                public void setCanceled(boolean b) {
779 1223 fernando
                        cancel = b;
780
                }
781
782
                /**
783 5317 fjp
                 * @see com.iver.utiles.swing.threads.Cancellable#isCanceled()
784 1223 fernando
                 */
785
                public boolean isCanceled() {
786
                        return cancel;
787
                }
788
        }
789
790 6306 caballero
791 1223 fernando
        /**
792
         * Listener del MapTool.
793
         *
794
         * @author Fernando Gonz?lez Cort?s
795
         */
796
        public class MapToolListener implements MouseListener, MouseWheelListener,
797
                MouseMotionListener {
798 5881 fjp
799
                long t1;
800
                Point2D pReal;
801 1223 fernando
                /**
802
                 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
803
                 */
804
                public void mouseClicked(MouseEvent e) {
805
                        try {
806
                                currentMapTool.mouseClicked(e);
807
                        } catch (BehaviorException t) {
808
                                throwException(t);
809
                        }
810
                }
811
812
                /**
813
                 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
814
                 */
815
                public void mouseEntered(MouseEvent e) {
816
                        try {
817
                                currentMapTool.mouseEntered(e);
818
                        } catch (BehaviorException t) {
819
                                throwException(t);
820
                        }
821
                }
822
823
                /**
824
                 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
825
                 */
826
                public void mouseExited(MouseEvent e) {
827
                        try {
828
                                currentMapTool.mouseExited(e);
829
                        } catch (BehaviorException t) {
830
                                throwException(t);
831
                        }
832
                }
833
834
                /**
835
                 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
836
                 */
837
                public void mousePressed(MouseEvent e) {
838
                        try {
839
                                currentMapTool.mousePressed(e);
840
                        } catch (BehaviorException t) {
841
                                throwException(t);
842
                        }
843
                }
844
845
                /**
846
                 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
847
                 */
848
                public void mouseReleased(MouseEvent e) {
849
                        try {
850
                                currentMapTool.mouseReleased(e);
851
                        } catch (BehaviorException t) {
852
                                throwException(t);
853
                        }
854
                }
855
856
                /**
857
                 * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
858
                 */
859
                public void mouseWheelMoved(MouseWheelEvent e) {
860
                        try {
861
                                currentMapTool.mouseWheelMoved(e);
862 6306 caballero
863 5874 fjp
                                // Si el tool actual no ha consumido el evento
864
                                // entendemos que quiere el comportamiento por defecto.
865
                                if (!e.isConsumed())
866
                                {
867 5881 fjp
                                        // Para usar el primer punto sobre el que queremos centrar
868
                                        // el mapa, dejamos pasar un segundo para considerar el siguiente
869
                                        // punto como v?lido.
870
                                        if (t1 == 0)
871
                                        {
872
                                                t1= System.currentTimeMillis();
873
                                                pReal = vp.toMapPoint(e.getPoint());
874
                                        }
875
                                        else
876
                                        {
877
                                                long t2 = System.currentTimeMillis();
878
                                                if ((t2-t1) > 1000)
879
                                                        t1=0;
880
                                        }
881 5874 fjp
                                        cancelDrawing();
882
                                        ViewPort vp = getViewPort();
883
884 6306 caballero
885 5874 fjp
                                        /* Point2D pReal = new Point2D.Double(vp.getAdjustedExtent().getCenterX(),
886
                                                        vp.getAdjustedExtent().getCenterY()); */
887
                                        int amount = e.getWheelRotation();
888
                                        double nuevoX;
889
                                        double nuevoY;
890
                                        double factor;
891
892 6306 caballero
                                        if (amount < 0) // nos acercamos
893 5874 fjp
                                        {
894
                                                factor = 0.9;
895
                                        } else // nos alejamos
896
                                        {
897
                                                factor = 1.2;
898
                                        }
899
                                        Rectangle2D.Double r = new Rectangle2D.Double();
900
                                        if (vp.getExtent() != null) {
901
                                                nuevoX = pReal.getX()
902
                                                                - ((vp.getExtent().getWidth() * factor) / 2.0);
903
                                                nuevoY = pReal.getY()
904
                                                                - ((vp.getExtent().getHeight() * factor) / 2.0);
905
                                                r.x = nuevoX;
906
                                                r.y = nuevoY;
907
                                                r.width = vp.getExtent().getWidth() * factor;
908
                                                r.height = vp.getExtent().getHeight() * factor;
909
910
                                                vp.setExtent(r);
911
                                        }
912 6306 caballero
913
914 5874 fjp
                                }
915 1223 fernando
                        } catch (BehaviorException t) {
916
                                throwException(t);
917
                        }
918
                }
919
920
                /**
921
                 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
922
                 */
923
                public void mouseDragged(MouseEvent e) {
924
                        try {
925
                                currentMapTool.mouseDragged(e);
926
                        } catch (BehaviorException t) {
927
                                throwException(t);
928
                        }
929
                }
930
931
                /**
932
                 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
933
                 */
934
                public void mouseMoved(MouseEvent e) {
935
                        try {
936
                                currentMapTool.mouseMoved(e);
937
                        } catch (BehaviorException t) {
938
                                throwException(t);
939
                        }
940
                }
941
        }
942
943
        /**
944
         * Listener sobre el MapContext.
945
         *
946
         * @author Fernando Gonz?lez Cort?s
947
         */
948
        public class MapContextListener implements AtomicEventListener {
949
                /**
950
                 * @see com.iver.cit.gvsig.fmap.AtomicEventListener#atomicEvent(com.iver.cit.gvsig.fmap.AtomicEvent)
951
                 */
952
                public void atomicEvent(AtomicEvent e) {
953
                        boolean redraw = false;
954
                        LayerEvent[] layerEvents = e.getLayerEvents();
955
956
                        for (int i = 0; i < layerEvents.length; i++) {
957
                                if (layerEvents[i].getProperty().equals("visible")) {
958
                                        redraw = true;
959
                                }
960
                        }
961
962
                        if (e.getColorEvents().length > 0) {
963
                                redraw = true;
964
                        }
965
966
                        if (e.getExtentEvents().length > 0) {
967
                                redraw = true;
968
                        }
969 6306 caballero
970 5941 jmvivo
                        if (e.getProjectionEvents().length > 0) {
971
                                //redraw = true;
972
                        }
973 1223 fernando
974 6306 caballero
975 1223 fernando
                        if (e.getLayerCollectionEvents().length > 0) {
976
                                redraw = true;
977
                        }
978
979
                        if (e.getLegendEvents().length > 0) {
980
                                redraw = true;
981
                        }
982
983
                        if (e.getSelectionEvents().length > 0) {
984
                                redraw = true;
985
                        }
986
987
                        if (redraw) {
988 3331 fjp
                System.out.println("MapContextListener redraw");
989 3422 fjp
                                MapControl.this.drawMap(false);
990 1223 fernando
                        }
991
                }
992
        }
993
        public ViewPort getViewPort() {
994
                return vp;
995
        }
996 3719 caballero
997 2877 caballero
        /**
998 3719 caballero
         * Returns a HashMap with the tools that have been registered
999 2877 caballero
         * in the Mapcontrol.
1000
         */
1001 2876 caballero
        public HashMap getNamesMapTools() {
1002
                return namesMapTools;
1003
        }
1004 4120 caballero
1005 4142 caballero
        public void commandRepaint() {
1006 4127 caballero
                drawMap(false);
1007 4120 caballero
        }
1008 4127 caballero
1009
        public void commandRefresh() {
1010
                // TODO Auto-generated method stub
1011
        }
1012 4888 caballero
1013
        public void setPrevTool() {
1014
                setTool(prevTool);
1015
        }
1016 6306 caballero
1017 6264 fjp
                public void zoomIn() {
1018
                Behavior mapTool = (Behavior) namesMapTools.get("zoomIn");
1019
                ViewPort vp=getViewPort();
1020
                Rectangle2D r=getViewPort().getAdjustedExtent();
1021
                Point2D pCenter=vp.fromMapPoint(r.getCenterX(),r.getCenterY());
1022
                MouseEvent e=new MouseEvent((Component)this,MouseEvent.MOUSE_RELEASED,MouseEvent.ACTION_EVENT_MASK,MouseEvent.BUTTON1,(int)pCenter.getX(),(int)pCenter.getY(),1,true,MouseEvent.BUTTON1);
1023
                try {
1024
                        mapTool.mousePressed(e);
1025
                        mapTool.mouseReleased(e);
1026
                } catch (BehaviorException t) {
1027
                        throwException(t);
1028
                }
1029
        }
1030
        public void zoomOut() {
1031
                Behavior mapTool = (Behavior) namesMapTools.get("zoomOut");
1032
                ViewPort vp=getViewPort();
1033
                Rectangle2D r=getViewPort().getAdjustedExtent();
1034
                Point2D pCenter=vp.fromMapPoint(r.getCenterX(),r.getCenterY());
1035
                MouseEvent e=new MouseEvent((Component)this,MouseEvent.MOUSE_RELEASED,MouseEvent.ACTION_EVENT_MASK,MouseEvent.BUTTON1,(int)pCenter.getX(),(int)pCenter.getY(),1,true,MouseEvent.BUTTON1);
1036
                try {
1037
                        mapTool.mousePressed(e);
1038
                        mapTool.mouseReleased(e);
1039
                } catch (BehaviorException t) {
1040
                        throwException(t);
1041
                }
1042
        }
1043 6261 fjp
1044 6306 caballero
1045 1223 fernando
}