Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / MapControl.java @ 13879

History | View | Annotate | Download (28.5 KB)

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 com.iver.cit.gvsig.fmap;
42

    
43
import java.awt.Color;
44
import java.awt.Component;
45
import java.awt.Dimension;
46
import java.awt.Graphics;
47
import java.awt.Graphics2D;
48
import java.awt.event.ActionEvent;
49
import java.awt.event.ActionListener;
50
import java.awt.event.ComponentEvent;
51
import java.awt.event.ComponentListener;
52
import java.awt.event.MouseEvent;
53
import java.awt.event.MouseListener;
54
import java.awt.event.MouseMotionListener;
55
import java.awt.event.MouseWheelEvent;
56
import java.awt.event.MouseWheelListener;
57
import java.awt.geom.Point2D;
58
import java.awt.geom.Rectangle2D;
59
import java.awt.image.BufferedImage;
60
import java.util.HashMap;
61
import java.util.Set;
62

    
63
import javax.swing.JComponent;
64
import javax.swing.Timer;
65

    
66
import org.cresques.cts.IProjection;
67

    
68
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
69
import com.iver.cit.gvsig.fmap.edition.commands.CommandListener;
70
import com.iver.cit.gvsig.fmap.layers.LayerEvent;
71
import com.iver.cit.gvsig.fmap.tools.BehaviorException;
72
import com.iver.cit.gvsig.fmap.tools.CompoundBehavior;
73
import com.iver.cit.gvsig.fmap.tools.Behavior.Behavior;
74
import com.iver.utiles.exceptionHandling.ExceptionHandlingSupport;
75
import com.iver.utiles.exceptionHandling.ExceptionListener;
76
import com.iver.utiles.swing.threads.Cancellable;
77

    
78

    
79
/**
80
 * MapControl.
81
 *
82
 * @author Fernando Gonz?lez Cort?s
83
 */
84
public class MapControl extends JComponent implements ComponentListener,
85
                        CommandListener {
86
        /** Cuando la vista est? actualizada. */
87
        public static final int ACTUALIZADO = 0;
88

    
89
        /** Cuando la vista est? desactualizada. */
90
        public static final int DESACTUALIZADO = 1;
91
    public static final int ONLY_GRAPHICS = 2;
92
    private static int drawFrameRate = 3;
93
    private static boolean drawAnimationEnabled = true;
94

    
95
    // public static final int FAST_PAINT = 3;
96
        //private static Logger logger = Logger.getLogger(MapControl.class.getName());
97
        private MapContext mapContext = null;
98
    //private boolean drawerAlive = false;
99
        protected HashMap namesMapTools = new HashMap();
100
        protected Behavior currentMapTool = null;
101
        private int status = DESACTUALIZADO;
102
        private BufferedImage image = null;
103
        protected String currentTool;
104
        private CancelDraw canceldraw;
105
        //private boolean isCancelled = true;
106
        private Timer timer;
107
        protected ViewPort vp;
108
        //private Drawer drawer;
109
    private Drawer2 drawer2;
110
    // private boolean firstDraw = true;
111
        protected MapToolListener mapToolListener = new MapToolListener();
112
        private MapContextListener mapContextListener = new MapContextListener();
113
        private ExceptionHandlingSupport exceptionHandlingSupport = new ExceptionHandlingSupport();
114

    
115
        protected String prevTool;
116

    
117
        /**
118
     * We need this to avoid not wanted refresh. REMEMBER TO SET TO TRUE!!
119
     */
120
    // private boolean paintEnabled = false;
121

    
122
        /**
123
         * Crea un nuevo NewMapControl.
124
         */
125
        public MapControl() {
126
                this.setName("MapControl");
127
                setDoubleBuffered(false);
128
                setOpaque(true);
129
                status = DESACTUALIZADO;
130

    
131
                //Clase usada para cancelar el dibujado
132
                canceldraw = new CancelDraw();
133

    
134
                //Modelo de datos y ventana del mismo
135
                // TODO: Cuando creamos un mapControl, deber?amos asignar
136
                // la projecci?n por defecto con la que vayamos a trabajar.
137
                // 23030 es el c?digo EPSG del UTM30 elipsoide ED50
138
                vp = new ViewPort(CRSFactory.getCRS("EPSG:23030"));
139
                setMapContext(new MapContext(vp));
140

    
141
                //eventos
142
                this.addComponentListener(this);
143
                this.addMouseListener(mapToolListener);
144
                this.addMouseMotionListener(mapToolListener);
145
                this.addMouseWheelListener(mapToolListener);
146

    
147
        this.drawer2 = new Drawer2();
148
                //Timer para mostrar el redibujado mientras se dibuja
149
                timer = new Timer(1000/drawFrameRate,
150
                                new ActionListener() {
151
                                        public void actionPerformed(ActionEvent e) {
152
                                                
153
                                                if (drawAnimationEnabled) {
154
                                                        MapControl.this.repaint();
155
                                                }
156
                                        }
157
                                });
158
        }
159

    
160
        /**
161
         * Inserta el modelo.
162
         *
163
         * @param model FMap.
164
         */
165
        public void setMapContext(MapContext model) {
166
                if (mapContext != null) {
167
                        mapContext.removeAtomicEventListener(mapContextListener);
168
                }
169

    
170
                mapContext = model;
171

    
172
                if (mapContext.getViewPort() == null) {
173
                        mapContext.setViewPort(vp);
174
                } else {
175
                        vp = mapContext.getViewPort();
176

    
177
                        // vp.setImageSize(new Dimension(getWidth(), getHeight()));
178
                        //System.err.println("Viewport en setMapContext:" + vp);
179
                }
180

    
181
                mapContext.addAtomicEventListener(mapContextListener);
182

    
183
                status = DESACTUALIZADO;
184
        }
185

    
186
        /**
187
         * Devuelve la proyecci?n.
188
         *
189
         * @return Proyecci?n.
190
         */
191
        public IProjection getProjection() {
192
                return getMapContext().getProjection();
193
        }
194

    
195
        /**
196
         * Inserta una proyecci?n.
197
         *
198
         * @param proj Proyecci?n.
199
         */
200
        public void setProjection(IProjection proj) {
201
                getMapContext().setProjection(proj);
202
        }
203

    
204
        /**
205
         * Devuelve el modelo.
206
         *
207
         * @return FMap.
208
         */
209
        public MapContext getMapContext() {
210
                return mapContext;
211
        }
212

    
213
        /**
214
         * Registra una herramienta (tool).
215
         *
216
         * @param name Nombre de la herramienta.
217
         * @param tool Herramienta.
218
         */
219
        public void addMapTool(String name, Behavior tool) {
220
                namesMapTools.put(name, tool);
221
                tool.setMapControl(this);
222
        }
223

    
224
        public void addMapTool(String name, Behavior[] tools){
225
                CompoundBehavior tool = new CompoundBehavior(tools);
226
                addMapTool(name, tool);
227
        }
228

    
229
        /**
230
         * Devuelve una herramienta (tool) registrada.
231
         *
232
         * @param name Nombre de la herramienta.
233
         * @return tool Herramienta.
234
         */
235
        public Behavior getMapTool(String name) {
236
                return (Behavior)namesMapTools.get(name);
237
        }
238

    
239
        /**
240
         * Devuelve los nombres de herramientas (tool) registradas.
241
         *
242
         * @return Set (String) nombres de las herramientas.
243
         */
244
        public Set getMapToolsKeySet() {
245
                return namesMapTools.keySet();
246
        }
247

    
248

    
249
        /**
250
         * Returns true if this map control contains a tool named with the value
251
         * passed in the toolName parameter. If you have added two tools with the
252
         * same name, the last tool will overwrite the previous ones.
253
         * @param toolName
254
         * @return true if the map control contains a tool with the same name than
255
         *                 toolName. False, otherwise.
256
         */
257
        public boolean hasTool(String toolName) {
258
                return namesMapTools.containsKey(toolName);
259
        }
260
        /**
261
         * DOCUMENT ME!
262
         *
263
         * @param toolName DOCUMENT ME!
264
         */
265
        public void setTool(String toolName) {
266
                prevTool=getCurrentTool();
267
                Behavior mapTool = (Behavior) namesMapTools.get(toolName);
268
                currentMapTool = mapTool;
269
                currentTool = toolName;
270
                this.setCursor(mapTool.getCursor());
271
        }
272
        public Behavior getCurrentMapTool(){
273
                return currentMapTool;
274
        }
275
        /**
276
         * Returns the name of the current selected tool on this MapControl
277
         *
278
         * @return A tool name.
279
         */
280
        public String getCurrentTool() {
281
                return currentTool;
282
        }
283

    
284

    
285
        /**
286
         * Cancela el dibujado. Se espera a que la cancelaci?n surta efecto
287
         */
288
        public void cancelDrawing() {
289
                /* if (drawer != null) {
290
                        if (!drawer.isAlive()) {
291
                                return;
292
                        }
293
                }
294
                */
295
                canceldraw.setCanceled(true);
296

    
297
                /* while (!isCancelled) {
298
                        if (!drawer.isAlive()) {
299
                            // Si hemos llegado aqu? con un thread vivo, seguramente
300
                            // no estamos actualizados.
301

302
                                break;
303
                        }
304

305
                }
306
                canceldraw.setCancel(false);
307
                isCancelled = false;
308
        drawerAlive = false; */
309
        }
310

    
311
    private boolean adaptToImageSize()
312
    {
313
        if ((image == null) || (vp.getImageWidth() != this.getWidth()) || (vp.getImageHeight() != this.getHeight()))
314
        {
315
            image = new BufferedImage(this.getWidth(), this.getHeight(),
316
                    BufferedImage.TYPE_INT_ARGB);
317
            // ESTILO MAC
318
//                image = GraphicsEnvironment.getLocalGraphicsEnvironment()
319
//                                .getDefaultScreenDevice().getDefaultConfiguration()
320
//                                .createCompatibleImage(this.getWidth(), this.getHeight());
321
            vp.setImageSize(new Dimension(getWidth(), getHeight()));
322
            getMapContext().getViewPort().refreshExtent();
323

    
324

    
325
            Graphics gTemp = image.createGraphics();
326
            Color theBackColor = vp.getBackColor();
327
            if (theBackColor == null)
328
                gTemp.setColor(Color.WHITE);
329
            else
330
                gTemp.setColor(theBackColor);
331

    
332
            gTemp.fillRect(0,0,getWidth(), getHeight());
333
            gTemp.dispose();
334
            status = DESACTUALIZADO;
335
            // g.drawImage(image,0,0,null);
336
            return true;
337
        }
338
        return false;
339
    }
340

    
341
        /*
342
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
343
         */
344
        protected void paintComponent(Graphics g) {
345
        adaptToImageSize();
346
        /* if (status == FAST_PAINT) {
347
            System.out.println("FAST_PAINT");
348
            g.drawImage(image,0,0,null);
349
            status = ACTUALIZADO;
350
            return;
351
        } */
352
        // System.out.println("PINTANDO MAPCONTROL" + this);
353
                if (status == ACTUALIZADO) {
354
                        // LWS logger.debug("Dibujando la imagen obtenida");
355

    
356
                        /*
357
                         * Si hay un behaviour y la imagen es distinta de null se delega el dibujado
358
                         * en dicho behaviour
359
                         */
360
            if (image != null)
361
            {
362
                if (currentMapTool != null)
363
                    currentMapTool.paintComponent(g);
364
                else
365
                    g.drawImage(image,0,0,null);
366

    
367
                                // System.out.println("Pinto ACTUALIZADO");
368
                        }
369
                } else if ((status == DESACTUALIZADO)
370
                || (status == ONLY_GRAPHICS)) {
371
                        // LWS System.out.println("DESACTUALIZADO: Obteniendo la imagen de la cartograf?a");
372
                        /* if (isOpaque())
373
                        {
374
                            if (image==null)
375
                            {
376
                                g.setColor(vp.getBackColor());
377
                                g.fillRect(0,0,getWidth(), getHeight());
378
                            }
379
                            // else g.drawImage(image,0,0,null);
380
                        } */
381
            // cancelDrawing();
382
                        //Se crea la imagen con el color de fonde deseado
383
                        /* if (image == null)
384
                        {
385
                                image = new BufferedImage(this.getWidth(), this.getHeight(),
386
                                                BufferedImage.TYPE_INT_ARGB);
387
                                vp.setImageSize(new Dimension(getWidth(), getHeight()));
388
                                Graphics gTemp = image.createGraphics();
389
                            Color theBackColor = vp.getBackColor();
390
                            if (theBackColor == null)
391
                                gTemp.setColor(Color.WHITE);
392
                            else
393
                                gTemp.setColor(theBackColor);
394

395
                                gTemp.fillRect(0,0,getWidth(), getHeight());
396
                                gTemp.dispose();
397
                                // g.drawImage(image,0,0,null);
398
                                System.out.println("Imagen con null en DESACTUALIZADO. Width = " + this.getWidth());
399
                        } */
400
            // else
401
            // {
402

    
403

    
404
            // if (image != null)
405
            //  {
406
                g.drawImage(image,0,0,null);
407

    
408
                drawer2.put(new PaintingRequest());
409
                timer.start();
410
            /* }
411
            else
412
                return; */
413
            // }
414

    
415
            /* if (drawerAlive == false)
416
            {
417
                drawer = new Drawer(image, canceldraw);
418
                drawer.start();
419
                        //Se lanza el tread de dibujado
420
            } */
421

    
422
                        // status = ACTUALIZADO;
423
                }
424
        }
425

    
426
        /**
427
         * Devuelve la imagen de la vista.
428
         *
429
         * @return imagen.
430
         */
431
        public BufferedImage getImage() {
432
                return image;
433
        }
434

    
435
        /**
436
         * Marca el mapa para que en el pr?ximo redibujado se acceda a la
437
         * cartograf?a para reobtener la imagen
438
         * @param doClear Solo deber?a ser true cuando se llama desde pan
439
         */
440
        public void drawMap(boolean doClear) {
441
                cancelDrawing();
442
                //System.out.println("drawMap con doClear=" + doClear);
443
        status = DESACTUALIZADO;
444
        getMapContext().getLayers().setDirty(true);
445
                if (doClear)
446
        {
447
            // image = null; // Se usa para el PAN
448
            if (image != null)
449
            {
450
                Graphics2D g = image.createGraphics();
451
                Color theBackColor = vp.getBackColor();
452
                if (theBackColor == null)
453
                    g.setColor(Color.WHITE);
454
                else
455
                    g.setColor(theBackColor);
456
                g.fillRect(0, 0, vp.getImageWidth(), vp.getImageHeight());
457
                g.dispose();
458
            }
459
        }
460
                repaint();
461
        }
462

    
463
        public void rePaintDirtyLayers()
464
        {
465
                cancelDrawing();
466
        status = DESACTUALIZADO;
467
        repaint();
468
        }
469

    
470
    public void drawGraphics() {
471
        status = ONLY_GRAPHICS;
472
        repaint();
473
    }
474

    
475
        /**
476
         * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
477
         */
478
        public void componentHidden(ComponentEvent e) {
479
        }
480

    
481
        /**
482
         * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
483
         */
484
        public void componentMoved(ComponentEvent e) {
485
        }
486

    
487
        /**
488
         * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
489
         */
490
        public void componentResized(ComponentEvent e) {
491
                /* image = new BufferedImage(this.getWidth(), this.getHeight(),
492
                                BufferedImage.TYPE_INT_ARGB);
493
                Graphics gTemp = image.createGraphics();
494
                gTemp.setColor(vp.getBackColor());
495
                gTemp.fillRect(0,0,getWidth(), getHeight());
496
        System.out.println("MapControl resized");
497
            // image = null;
498
            vp.setImageSize(new Dimension(getWidth(), getHeight()));
499
                getMapContext().getViewPort().setScale(); */
500
                // drawMap(true);
501
        }
502

    
503
        /**
504
         * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
505
         */
506
        public void componentShown(ComponentEvent e) {
507
        }
508

    
509
        /**
510
         * A?ade un listener de tipo ExceptionListener.
511
         *
512
         * @param o ExceptionListener.
513
         */
514
        public void addExceptionListener(ExceptionListener o) {
515
                exceptionHandlingSupport.addExceptionListener(o);
516
        }
517

    
518
        /**
519
         * Borra la ExceptioListener que se pasa como par?metro.
520
         *
521
         * @param o ExceptionListener.
522
         *
523
         * @return True si se borra correctamente.
524
         */
525
        public boolean removeExceptionListener(ExceptionListener o) {
526
                return exceptionHandlingSupport.removeExceptionListener(o);
527
        }
528

    
529
        /**
530
         * Lanza una Excepci?n.
531
         *
532
         * @param t Excepci?n.
533
         */
534
        protected void throwException(Throwable t) {
535
                exceptionHandlingSupport.throwException(t);
536
        }
537

    
538

    
539
    private class PaintingRequest
540
    {
541

    
542
        public PaintingRequest()
543
        {
544
        }
545

    
546
        public void paint()
547
        {
548
            try
549
            {
550
                    canceldraw.setCanceled(false);
551
                /* if (image == null)
552
                {
553
                    image = new BufferedImage(vp.getImageWidth(), vp.getImageHeight(),
554
                            BufferedImage.TYPE_INT_ARGB);
555
                    Graphics gTemp = image.createGraphics();
556
                    Color theBackColor = vp.getBackColor();
557
                    if (theBackColor == null)
558
                        gTemp.setColor(Color.WHITE);
559
                    else
560
                        gTemp.setColor(theBackColor);
561

562
                    gTemp.fillRect(0,0,getWidth(), getHeight());
563
                    gTemp.dispose();
564
                    // g.drawImage(image,0,0,null);
565
                    System.out.println("Imagen con null en DESACTUALIZADO. Width = " + this.getWidth());
566
                } */
567
                Graphics2D g = image.createGraphics();
568

    
569
                ViewPort viewPort = mapContext.getViewPort();
570

    
571
                if (status == DESACTUALIZADO)
572
                {
573
                        Graphics2D gTemp = image.createGraphics();
574
                    Color theBackColor = viewPort.getBackColor();
575
                    if (theBackColor == null)
576
                        gTemp.setColor(Color.WHITE);
577
                    else
578
                        gTemp.setColor(theBackColor);
579
                    gTemp.fillRect(0, 0, viewPort.getImageWidth(), viewPort.getImageHeight());
580
                    status = ACTUALIZADO;
581
                    // ESTILO MAC
582
//                    BufferedImage imgMac = new BufferedImage(vp.getImageWidth(), vp.getImageHeight(),
583
//                            BufferedImage.TYPE_INT_ARGB);
584
//
585
//                    mapContext.draw(imgMac, g, canceldraw, mapContext.getScaleView());
586
//                    g.drawImage(imgMac, 0, 0, null);
587
                    // FIN ESTILO MAC
588
                    // SIN MAC:
589
                    
590
                    mapContext.draw(image, g, canceldraw, mapContext.getScaleView());
591

    
592
                }
593
                else if (status == ONLY_GRAPHICS)
594
                {
595
                    status = ACTUALIZADO;
596
                    mapContext.drawGraphics(image, g, canceldraw,mapContext.getScaleView());
597

    
598
                }
599

    
600

    
601
                // status = FAST_PAINT;
602
              //  drawerAlive = false;
603
                timer.stop();
604
                repaint();
605

    
606

    
607
            } catch (Throwable e) {
608
                timer.stop();
609
              //  isCancelled = true;
610
                e.printStackTrace();
611
                throwException(e);
612
            } finally {
613
            }
614

    
615
        }
616

    
617
    }
618

    
619
    /**
620
     * @author fjp
621
     *
622
     * Basasdo en el patr?n WorkerThread
623
     *
624
     */
625
    public class Drawer2
626
    {
627
        // Una mini cola de 2. No acumulamos peticiones de dibujado
628
        // dibujamos solo lo ?ltimo que nos han pedido.
629
        private PaintingRequest paintingRequest;
630
        private PaintingRequest waitingRequest;
631

    
632
        private boolean waiting;
633
        private boolean shutdown;
634

    
635
        public void setShutdown(boolean isShutdown)
636
        {
637
            shutdown = isShutdown;
638
        }
639

    
640
        public Drawer2()
641
        {
642
            paintingRequest = null;
643
            waitingRequest = null;
644
            waiting = false;
645
            shutdown = false;
646
            new Thread(new Worker()).start();
647
        }
648

    
649
        public void put(PaintingRequest newPaintRequest)
650
        {
651
            waitingRequest = newPaintRequest;
652
            if (waiting)
653
            {
654
                synchronized (this) {
655
                    notifyAll();
656
                }
657
            }
658
        }
659

    
660
        public PaintingRequest take()
661
        {
662
            if (waitingRequest == null)
663
            {
664
                synchronized (this) {
665
                    waiting = true;
666
                    try {
667
                        wait();
668
                    }
669
                    catch (InterruptedException ie)
670
                    {
671
                        waiting = false;
672
                    }
673
                }
674
            }
675
            paintingRequest = waitingRequest;
676
            waitingRequest = null;
677
            return paintingRequest;
678
        }
679

    
680

    
681
        private class Worker implements Runnable
682
        {
683
            public void run()
684
            {
685
                while (!shutdown)
686
                {
687
                    PaintingRequest p = take();
688
                    //System.out.println("Pintando");
689
                    if (image != null){
690
                            cancelDrawing();
691
                        p.paint();
692
                    } else
693
                        status = DESACTUALIZADO;
694
                }
695
            }
696
        }
697
    }
698

    
699
        /**
700
         * Clase utilizada para dibujar las capas.
701
         *
702
         * @author Vicente Caballero Navarro
703
         */
704
        public class Drawer extends Thread {
705
                //private Graphics g;
706
                private BufferedImage image = null;
707
                private CancelDraw cancel;
708
                //private boolean threadCancel = false;
709

    
710
                /**
711
                 * Crea un nuevo Drawer.
712
                 *
713
                 */
714
                public Drawer(BufferedImage image, CancelDraw cancel)
715
        {
716
                        this.image = image;
717
                        this.cancel = cancel;
718
         //   drawerAlive = true;
719
                }
720

    
721
                /**
722
                 * @see java.lang.Runnable#run()
723
                 */
724
                public void run() {
725
                        try {
726
                                // synchronized (Drawer.class) {
727
                                    Graphics2D g = image.createGraphics();
728

    
729
                                    ViewPort viewPort = mapContext.getViewPort();
730
                    if (status == DESACTUALIZADO)
731
                    {
732
                                        Color theBackColor = viewPort.getBackColor();
733
                                        if (theBackColor == null)
734
                                            g.setColor(Color.WHITE);
735
                                        else
736
                                            g.setColor(theBackColor);
737
                                            g.fillRect(0, 0, viewPort.getImageWidth(), viewPort.getImageHeight());
738
                        status = ACTUALIZADO;
739
                        mapContext.draw(image, g, cancel,mapContext.getScaleView());
740
                    }
741
                    else if (status == ONLY_GRAPHICS)
742
                    {
743
                        status = ACTUALIZADO;
744
                        mapContext.drawGraphics(image, g, cancel,mapContext.getScaleView());
745
                    }
746

    
747
                                        timer.stop();
748
                    // status = FAST_PAINT;
749
                  //  drawerAlive = false;
750
                                        repaint();
751

    
752

    
753

    
754
                                // }
755
                        } catch (Throwable e) {
756
                            timer.stop();
757
                                //isCancelled = true;
758
                e.printStackTrace();
759
                                throwException(e);
760
                        } finally {
761
                        }
762
                }
763
        }
764

    
765
        /**
766
         * Clase para cancelar el dibujado.
767
         *
768
         * @author Fernando Gonz?lez Cort?s
769
         */
770
        public class CancelDraw implements Cancellable {
771
                private boolean cancel = false;
772

    
773
                /**
774
                 * Crea un nuevo CancelDraw.
775
                 */
776
                public CancelDraw() {
777
                }
778

    
779
                /**
780
                 * Insertar si se debe cancelar el dibujado.
781
                 *
782
                 * @param b true si se debe cancelar el dibujado.
783
                 */
784
                public void setCanceled(boolean b) {
785
                        cancel = b;
786
                }
787

    
788
                /**
789
                 * @see com.iver.utiles.swing.threads.Cancellable#isCanceled()
790
                 */
791
                public boolean isCanceled() {
792
                        return cancel;
793
                }
794
        }
795

    
796

    
797
        /**
798
         * Listener del MapTool.
799
         *
800
         * @author Fernando Gonz?lez Cort?s
801
         */
802
        public class MapToolListener implements MouseListener, MouseWheelListener,
803
                MouseMotionListener {
804

    
805
                long t1;
806
                Point2D pReal;
807
                /**
808
                 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
809
                 */
810
                public void mouseClicked(MouseEvent e) {
811
                        try {
812
                                if (currentMapTool != null)
813
                                    currentMapTool.mouseClicked(e);
814
                        } catch (BehaviorException t) {
815
                                throwException(t);
816
                        }
817
                }
818

    
819
                /**
820
                 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
821
                 */
822
                public void mouseEntered(MouseEvent e) {
823
                        try {
824
                                if (currentMapTool != null)
825
                                        currentMapTool.mouseEntered(e);
826
                        } catch (BehaviorException t) {
827
                                throwException(t);
828
                        }
829
                }
830

    
831
                /**
832
                 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
833
                 */
834
                public void mouseExited(MouseEvent e) {
835
                        try {
836
                                if (currentMapTool != null)
837
                                    currentMapTool.mouseExited(e);
838
                        } catch (BehaviorException t) {
839
                                throwException(t);
840
                        }
841
                }
842

    
843
                /**
844
                 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
845
                 */
846
                public void mousePressed(MouseEvent e) {
847
                        try {
848
                                if (currentMapTool != null)
849
                                        currentMapTool.mousePressed(e);
850
                        } catch (BehaviorException t) {
851
                                throwException(t);
852
                        }
853
                }
854

    
855
                /**
856
                 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
857
                 */
858
                public void mouseReleased(MouseEvent e) {
859
                        try {
860
                                if (currentMapTool != null)
861
                                        currentMapTool.mouseReleased(e);
862
                        } catch (BehaviorException t) {
863
                                throwException(t);
864
                        }
865
                }
866

    
867
                /**
868
                 * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
869
                 */
870
                public void mouseWheelMoved(MouseWheelEvent e) {
871
                        try {
872
                                if (currentMapTool == null)
873
                                        return;
874
                                
875
                                currentMapTool.mouseWheelMoved(e);
876

    
877
                                // Si el tool actual no ha consumido el evento
878
                                // entendemos que quiere el comportamiento por defecto.
879
                                if (!e.isConsumed())
880
                                {
881
                                        // Para usar el primer punto sobre el que queremos centrar
882
                                        // el mapa, dejamos pasar un segundo para considerar el siguiente
883
                                        // punto como v?lido.
884
                                        if (t1 == 0)
885
                                        {
886
                                                t1= System.currentTimeMillis();
887
                                                pReal = vp.toMapPoint(e.getPoint());
888
                                        }
889
                                        else
890
                                        {
891
                                                long t2 = System.currentTimeMillis();
892
                                                if ((t2-t1) > 1000)
893
                                                        t1=0;
894
                                        }
895
                                        cancelDrawing();
896
                                        ViewPort vp = getViewPort();
897

    
898

    
899
                                        /* Point2D pReal = new Point2D.Double(vp.getAdjustedExtent().getCenterX(),
900
                                                        vp.getAdjustedExtent().getCenterY()); */
901
                                        int amount = e.getWheelRotation();
902
                                        double nuevoX;
903
                                        double nuevoY;
904
                                        double factor;
905

    
906
                                        if (amount < 0) // nos acercamos
907
                                        {
908
                                                factor = 0.9;
909
                                        } else // nos alejamos
910
                                        {
911
                                                factor = 1.2;
912
                                        }
913
                                        Rectangle2D.Double r = new Rectangle2D.Double();
914
                                        if (vp.getExtent() != null) {
915
                                                nuevoX = pReal.getX()
916
                                                                - ((vp.getExtent().getWidth() * factor) / 2.0);
917
                                                nuevoY = pReal.getY()
918
                                                                - ((vp.getExtent().getHeight() * factor) / 2.0);
919
                                                r.x = nuevoX;
920
                                                r.y = nuevoY;
921
                                                r.width = vp.getExtent().getWidth() * factor;
922
                                                r.height = vp.getExtent().getHeight() * factor;
923

    
924
                                                vp.setExtent(r);
925
                                        }
926

    
927

    
928
                                }
929
                        } catch (BehaviorException t) {
930
                                throwException(t);
931
                        }
932
                }
933

    
934
                /**
935
                 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
936
                 */
937
                public void mouseDragged(MouseEvent e) {
938
                        try {
939
                                if (currentMapTool != null)
940
                                        currentMapTool.mouseDragged(e);
941
                        } catch (BehaviorException t) {
942
                                throwException(t);
943
                        }
944
                }
945

    
946
                /**
947
                 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
948
                 */
949
                public void mouseMoved(MouseEvent e) {
950
                        try {
951
                                if (currentMapTool != null)
952
                                        currentMapTool.mouseMoved(e);
953
                        } catch (BehaviorException t) {
954
                                throwException(t);
955
                        }
956
                }
957
        }
958

    
959
        /**
960
         * Listener sobre el MapContext.
961
         *
962
         * @author Fernando Gonz?lez Cort?s
963
         */
964
        public class MapContextListener implements AtomicEventListener {
965
                /**
966
                 * @see com.iver.cit.gvsig.fmap.AtomicEventListener#atomicEvent(com.iver.cit.gvsig.fmap.AtomicEvent)
967
                 */
968
                public void atomicEvent(AtomicEvent e) {
969
                        boolean redraw = false;
970
                        LayerEvent[] layerEvents = e.getLayerEvents();
971

    
972
                        for (int i = 0; i < layerEvents.length; i++) {
973
                                if (layerEvents[i].getProperty().equals("visible")) {
974
                                        redraw = true;
975
                                }
976
                        }
977

    
978
                        if (e.getColorEvents().length > 0) {
979
                                redraw = true;
980
                        }
981

    
982
                        if (e.getExtentEvents().length > 0) {
983
                                redraw = true;
984
                        }
985

    
986
                        if (e.getProjectionEvents().length > 0) {
987
                                //redraw = true;
988
                        }
989

    
990

    
991
                        if (e.getLayerCollectionEvents().length > 0) {
992
                                redraw = true;
993
                        }
994

    
995
                        if (e.getLegendEvents().length > 0) {
996
                                redraw = true;
997
                        }
998

    
999
                        if (e.getSelectionEvents().length > 0) {
1000
                                redraw = true;
1001
                        }
1002

    
1003
                        if (redraw) {
1004
                //System.out.println("MapContextListener redraw");
1005
                                MapControl.this.drawMap(false);
1006
                        }
1007
                }
1008
        }
1009
        public ViewPort getViewPort() {
1010
                return vp;
1011
        }
1012

    
1013
        /**
1014
         * Returns a HashMap with the tools that have been registered
1015
         * in the Mapcontrol.
1016
         */
1017
        public HashMap getNamesMapTools() {
1018
                return namesMapTools;
1019
        }
1020

    
1021
        public void commandRepaint() {
1022
                drawMap(false);
1023
        }
1024

    
1025
        public void commandRefresh() {
1026
                // TODO Auto-generated method stub
1027
        }
1028

    
1029
        public void setPrevTool() {
1030
                setTool(prevTool);
1031
        }
1032

    
1033
        public void zoomIn() {
1034
                getMapContext().clearAllCachingImageDrawnLayers();
1035
                Behavior mapTool = (Behavior) namesMapTools.get("zoomIn");
1036
                ViewPort vp=getViewPort();
1037
                Rectangle2D r=getViewPort().getAdjustedExtent();
1038
                Point2D pCenter=vp.fromMapPoint(r.getCenterX(),r.getCenterY());
1039
                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);
1040
                try {
1041
                        mapTool.mousePressed(e);
1042
                        mapTool.mouseReleased(e);
1043
                } catch (BehaviorException t) {
1044
                        throwException(t);
1045
                }
1046
        }
1047
        public void zoomOut() {
1048
                getMapContext().clearAllCachingImageDrawnLayers();
1049
                Behavior mapTool = (Behavior) namesMapTools.get("zoomOut");
1050
                ViewPort vp=getViewPort();
1051
                Rectangle2D r=getViewPort().getAdjustedExtent();
1052
                Point2D pCenter=vp.fromMapPoint(r.getCenterX(),r.getCenterY());
1053
                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);
1054
                try {
1055
                        mapTool.mousePressed(e);
1056
                        mapTool.mouseReleased(e);
1057
                } catch (BehaviorException t) {
1058
                        throwException(t);
1059
                }
1060
        }
1061
        public MapToolListener getMapToolListener() {
1062
                return mapToolListener;
1063
        }
1064
//         mapTool can be null, for instance, in 3D's navigation tools
1065
        public void setCurrentMapTool(Behavior mapTool ){
1066
                currentMapTool = mapTool;
1067
        }
1068
        
1069
        public void applyFrameRate() {
1070
                if (getDrawFrameRate()>0) {
1071
                        timer.setDelay(1000/getDrawFrameRate());
1072
                }
1073
        }
1074

    
1075
        public static int getDrawFrameRate() {
1076
                return drawFrameRate;
1077
        }
1078

    
1079
        public static void setDrawFrameRate(int drawFrameRate) {
1080
                MapControl.drawFrameRate = drawFrameRate;
1081
        }
1082

    
1083
        public static boolean isDrawAnimationEnabled() {
1084
                return drawAnimationEnabled;
1085
        }
1086

    
1087
        public static void setDrawAnimationEnabled(boolean drawAnimationEnabled) {
1088
                MapControl.drawAnimationEnabled = drawAnimationEnabled;
1089
        }
1090
}