Statistics
| Revision:

root / branches / FMap_piloto_CAD_Layout_version / libraries / libFMap / src / com / iver / cit / gvsig / fmap / MapControl.java @ 1762

History | View | Annotate | Download (16 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.Dimension;
45
import java.awt.Graphics;
46
import java.awt.Graphics2D;
47
import java.awt.event.ActionEvent;
48
import java.awt.event.ActionListener;
49
import java.awt.event.ComponentEvent;
50
import java.awt.event.ComponentListener;
51
import java.awt.event.MouseEvent;
52
import java.awt.event.MouseListener;
53
import java.awt.event.MouseMotionListener;
54
import java.awt.event.MouseWheelEvent;
55
import java.awt.event.MouseWheelListener;
56
import java.awt.image.BufferedImage;
57
import java.util.HashMap;
58
import java.util.Stack;
59

    
60
import javax.swing.JComponent;
61
import javax.swing.Timer;
62

    
63
import org.apache.log4j.Logger;
64
import org.cresques.cts.IProjection;
65
import org.cresques.cts.ProjectionPool;
66

    
67
import com.iver.cit.gvsig.fmap.layers.LayerEvent;
68
import com.iver.cit.gvsig.fmap.operations.Cancellable;
69
import com.iver.cit.gvsig.fmap.tools.BehaviorException;
70
import com.iver.cit.gvsig.fmap.tools.CompoundBehavior;
71
import com.iver.cit.gvsig.fmap.tools.Behavior.Behavior;
72
import com.iver.utiles.exceptionHandling.ExceptionHandlingSupport;
73
import com.iver.utiles.exceptionHandling.ExceptionListener;
74

    
75

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

    
85
        /** Cuando la vista est? desactualizada. */
86
        public static final int DESACTUALIZADO = 1;
87
        private static Logger logger = Logger.getLogger(MapControl.class.getName());
88
        private FMap mapContext = null;
89
        private HashMap namesMapTools = new HashMap();
90
        private Stack toolStack = new Stack();
91
        private int status = DESACTUALIZADO;
92
        private BufferedImage image = null;
93
        private CancelDraw canceldraw;
94
        private boolean isCancelled = true;
95
        private Timer timer;
96
        protected ViewPort vp;
97
        private Drawer drawer;
98
        private MapToolListener mapToolListener = new MapToolListener();
99
        private MapContextListener mapContextListener = new MapContextListener();
100
        private ExceptionHandlingSupport exceptionHandlingSupport = new ExceptionHandlingSupport();
101
        private CadGrid grid = new CadGrid();
102
        private Behavior returnBehavior;
103
        /**
104
         * Crea un nuevo NewMapControl.
105
         */
106
        public MapControl() {
107
                setDoubleBuffered(false);
108
                setOpaque(true);
109
                status = DESACTUALIZADO;
110

    
111
                //Clase usada para cancelar el dibujado
112
                canceldraw = new CancelDraw();
113

    
114
                //Modelo de datos y ventana del mismo
115
                // TODO: Cuando creamos un mapControl, deber?amos asignar
116
                // la projecci?n por defecto con la que vayamos a trabajar.
117
                // 23030 es el c?digo EPSG del UTM30 elipsoide ED50
118
                vp = new ViewPort(ProjectionPool.get("EPSG:23030"));
119
                setMapContext(new FMap(vp));
120
                
121
                //eventos
122
                this.addComponentListener(this);
123
                this.addMouseListener(mapToolListener);
124
                this.addMouseMotionListener(mapToolListener);
125
                this.addMouseWheelListener(mapToolListener);
126

    
127
                //Timer para mostrar el redibujado mientras se dibuja
128
                timer = new Timer(300,
129
                                new ActionListener() {
130
                                        public void actionPerformed(ActionEvent e) {
131
                                                MapControl.this.repaint();
132
                                        }
133
                                });
134
        }
135

    
136
        /**
137
         * Inserta el modelo.
138
         *
139
         * @param model FMap.
140
         */
141
        public void setMapContext(FMap model) {
142
                if (mapContext != null) {
143
                        mapContext.removeAtomicEventListener(mapContextListener);
144
                }
145

    
146
                mapContext = model;
147

    
148
                if (mapContext.getViewPort() == null) {
149
                        mapContext.setViewPort(vp);
150
                } else {
151
                        vp = mapContext.getViewPort();
152

    
153
                        // vp.setImageSize(new Dimension(getWidth(), getHeight()));
154
                        //System.err.println("Viewport en setMapContext:" + vp);
155
                }
156

    
157
                mapContext.addAtomicEventListener(mapContextListener);
158

    
159
                status = DESACTUALIZADO;
160
        }
161

    
162
        /**
163
         * Devuelve la proyecci?n.
164
         *
165
         * @return Proyecci?n.
166
         */
167
        public IProjection getProjection() {
168
                return getMapContext().getProjection();
169
        }
170

    
171
        /**
172
         * Inserta una proyecci?n.
173
         *
174
         * @param proj Proyecci?n.
175
         */
176
        public void setProjection(IProjection proj) {
177
                getMapContext().setProjection(proj);
178
        }
179

    
180
        /**
181
         * Devuelve el modelo.
182
         *
183
         * @return FMap.
184
         */
185
        public FMap getMapContext() {
186
                return mapContext;
187
        }
188

    
189
        /**
190
         * Registra una herramienta (tool).
191
         *
192
         * @param name Nombre de la herramienta.
193
         * @param tool Herramienta.
194
         */
195
        public void addMapTool(String name, Behavior tool) {
196
                namesMapTools.put(name, tool);
197
                tool.setMapControl(this);
198
        }
199

    
200
        public void addMapTool(String name, Behavior[] tools){
201
                CompoundBehavior tool = new CompoundBehavior(tools);
202
                addMapTool(name, tool);
203
        }
204
        
205
        /**
206
         * DOCUMENT ME!
207
         *
208
         * @param toolName DOCUMENT ME!
209
         */
210
        public void pushTool(String toolName) {
211
                Behavior mapTool = (Behavior) namesMapTools.get(toolName);
212
                toolStack.push(mapTool);
213
                this.setCursor(mapTool.getCursor());
214
        }
215

    
216
        public void popTool(){
217
                toolStack.pop();
218
                this.setCursor(((Behavior)toolStack.peek()).getCursor());
219
        }
220
        
221
        public void setTool(String toolName){
222
                popTool();
223
                pushTool(toolName);
224
        }
225
        
226
        public Behavior getCurrentMapTool() {
227
                return (Behavior)toolStack.peek();
228
        }
229
        /**
230
         * Cancela el dibujado. Se espera a que la cancelaci?n surta efecto
231
         */
232
        public void cancelDrawing() {
233
                if (drawer != null) {
234
                        if (!drawer.isAlive()) {
235
                                return;
236
                        }
237
                }
238

    
239
                canceldraw.setCancel(true);
240

    
241
                while (!isCancelled) {
242
                        if (!drawer.isAlive()) {
243
                            // Si hemos llegado aqu? con un thread vivo, seguramente
244
                            // no estamos actualizados.
245

    
246
                                break;
247
                        }
248
                    
249
                }
250
                canceldraw.setCancel(false);
251
                isCancelled = false;
252
        }
253

    
254
        /**
255
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
256
         */
257
        protected void paintComponent(Graphics g) {
258
                if (status == ACTUALIZADO) {
259
                        logger.debug("Dibujando la imagen obtenida");
260
                        
261
                        /*
262
                         * Si hay un behaviour y la imagen es distinta de null se delega el dibujado
263
                         * en dicho behaviour
264
                         */
265
                        if (((Behavior)toolStack.peek() != null) && (image != null)) {
266
                                ((Behavior)toolStack.peek()).paintComponent(g);                           
267
                                System.out.println("Pinto ACTUALIZADO");
268
                        }
269
                        
270
                        
271
                } else if (status == DESACTUALIZADO) {
272
                        System.out.println("DESACTUALIZADO: Obteniendo la imagen de la cartograf?a");
273
                        /* if (isOpaque())
274
                        {
275
                            if (image==null)
276
                            {
277
                                g.setColor(vp.getBackColor());
278
                                g.fillRect(0,0,getWidth(), getHeight());                        
279
                            } 
280
                            // else g.drawImage(image,0,0,null);
281
                        } */
282

    
283
                        //Se crea la imagen con el color de fonde deseado
284
                        if (image == null)
285
                        {
286
                                image = new BufferedImage(this.getWidth(), this.getHeight(),
287
                                                BufferedImage.TYPE_INT_ARGB);
288
                                vp.setImageSize(new Dimension(getWidth(), getHeight()));
289
                                Graphics gTemp = image.createGraphics();
290
                                
291
                                Color theBackColor = vp.getBackColor();
292
                            
293
                                if (theBackColor == null)
294
                                gTemp.setColor(Color.WHITE);
295
                            else
296
                                gTemp.setColor(theBackColor);
297
                           
298
                                gTemp.fillRect(0,0,getWidth(), getHeight());
299
                                grid.drawGrid(gTemp);
300
                                
301
                                gTemp.dispose();
302
                                
303
                                System.out.println("Imagen con null en DESACTUALIZADO");
304
                        }
305
                        g.drawImage(image,0,0,null);
306
                        
307
                        Graphics imgg = image.createGraphics();
308
                        
309
                        //Se cancela el dibujado anterior
310
                        cancelDrawing();
311

    
312
                        drawer = new Drawer(image, (Graphics2D) imgg, canceldraw);
313
                        
314
                        drawer.start();
315
                        //Se lanza el tread de dibujado
316
                        timer.start();
317
                        
318
                        status = ACTUALIZADO;
319

    
320
                        // repaint();
321
                }
322
        }
323

    
324
        /**
325
         * Devuelve la imagen de la vista.
326
         *
327
         * @return imagen.
328
         */
329
        public BufferedImage getImage() {
330
                return image;
331
        }
332

    
333
        /**
334
         * Marca el mapa para que en el pr?ximo redibujado se acceda a la
335
         * cartograf?a para reobtener la imagen
336
         * @param doClear TODO
337
         */
338
        public void drawMap(boolean doClear) {
339
                status = DESACTUALIZADO;
340
                if (doClear) image = null; // Se usa para el PAN
341
                repaint();
342
        }
343

    
344
        /**
345
         * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
346
         */
347
        public void componentHidden(ComponentEvent e) {
348
        }
349

    
350
        /**
351
         * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
352
         */
353
        public void componentMoved(ComponentEvent e) {
354
        }
355

    
356
        /**
357
         * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
358
         */
359
        public void componentResized(ComponentEvent e) {
360
                /* image = new BufferedImage(this.getWidth(), this.getHeight(),
361
                                BufferedImage.TYPE_INT_ARGB);                
362
                Graphics gTemp = image.createGraphics();
363
                gTemp.setColor(vp.getBackColor());
364
                gTemp.fillRect(0,0,getWidth(), getHeight()); */
365
            image = null;
366
            vp.setImageSize(new Dimension(getWidth(), getHeight()));
367
                getMapContext().getViewPort().setScale();
368
                drawMap(false);
369
        }
370

    
371
        /**
372
         * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
373
         */
374
        public void componentShown(ComponentEvent e) {
375
        }
376

    
377
        /**
378
         * A?ade un listener de tipo ExceptionListener.
379
         *
380
         * @param o ExceptionListener.
381
         */
382
        public void addExceptionListener(ExceptionListener o) {
383
                exceptionHandlingSupport.addExceptionListener(o);
384
        }
385

    
386
        /**
387
         * Borra la ExceptioListener que se pasa como par?metro.
388
         *
389
         * @param o ExceptionListener.
390
         *
391
         * @return True si se borra correctamente.
392
         */
393
        public boolean removeExceptionListener(ExceptionListener o) {
394
                return exceptionHandlingSupport.removeExceptionListener(o);
395
        }
396

    
397
        /**
398
         * Lanza una Excepci?n.
399
         *
400
         * @param t Excepci?n.
401
         */
402
        private void throwException(Throwable t) {
403
                exceptionHandlingSupport.throwException(t);
404
        }
405

    
406
        /**
407
         * Clase utilizada para dibujar las capas.
408
         *
409
         * @author Vicente Caballero Navarro
410
         */
411
        public class Drawer extends Thread {
412
                private Graphics g;
413
                private BufferedImage image;
414
                private CancelDraw cancel;
415
                private boolean threadCancel = false;
416

    
417
                /**
418
                 * Crea un nuevo Drawer.
419
                 *
420
                 * @param image
421
                 * @param g
422
                 * @param cancel
423
                 */
424
                public Drawer(BufferedImage image, Graphics g, CancelDraw cancel) {
425
                        this.g = g;
426
                        this.image = image;
427
                        this.cancel = cancel;
428
                }
429

    
430
                /**
431
                 * @see java.lang.Runnable#run()
432
                 */
433
                public void run() {
434
                        try {
435
                                synchronized (Drawer.class) {
436
                                    Graphics2D g = image.createGraphics();
437
                                    ViewPort viewPort = mapContext.getViewPort();
438
                                    Color theBackColor = viewPort.getBackColor();
439
                                    if (theBackColor == null)
440
                                        g.setColor(Color.WHITE);
441
                                    else
442
                                        g.setColor(theBackColor);
443
                                        g.fillRect(0, 0, viewPort.getImageWidth(), viewPort.getImageHeight());
444
                                        grid.drawGrid(g);
445
                                        mapContext.draw(image, g, cancel);
446

    
447
                                        isCancelled = true;
448
                                        timer.stop();
449
                                        repaint();
450
                                    
451
                                }
452
                        } catch (Throwable e) {
453
                            timer.stop();
454
                                isCancelled = true;
455
                                throwException(e);
456
                        } finally {
457
                        }
458
                }
459
        }
460

    
461
        /**
462
         * Clase para cancelar el dibujado.
463
         *
464
         * @author Fernando Gonz?lez Cort?s
465
         */
466
        public class CancelDraw implements Cancellable {
467
                private boolean cancel = false;
468

    
469
                /**
470
                 * Crea un nuevo CancelDraw.
471
                 */
472
                public CancelDraw() {
473
                }
474

    
475
                /**
476
                 * Insertar si se debe cancelar el dibujado.
477
                 *
478
                 * @param b true si se debe cancelar el dibujado.
479
                 */
480
                public void setCancel(boolean b) {
481
                        cancel = b;
482
                }
483

    
484
                /**
485
                 * @see com.iver.cit.gvsig.fmap.operations.Cancellable#isCanceled()
486
                 */
487
                public boolean isCanceled() {
488
                        return cancel;
489
                }
490
        }
491

    
492
        /**
493
         * Listener del MapTool.
494
         *
495
         * @author Fernando Gonz?lez Cort?s
496
         */
497
        public class MapToolListener implements MouseListener, MouseWheelListener,
498
                MouseMotionListener {
499
                /**
500
                 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
501
                 */
502
                public void mouseClicked(MouseEvent e) {
503
                        try {
504
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
505
                                for (int i = 0; i < b.length; i++) {
506
                                        b[i].mouseClicked(e);
507
                                }
508
                        } catch (BehaviorException t) {
509
                                throwException(t);
510
                        }
511
                }
512

    
513
                /**
514
                 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
515
                 */
516
                public void mouseEntered(MouseEvent e) {
517
                        try {
518
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
519
                                for (int i = 0; i < b.length; i++) {
520
                                        b[i].mouseEntered(e);
521
                                }
522
                        } catch (BehaviorException t) {
523
                                throwException(t);
524
                        }
525
                }
526

    
527
                /**
528
                 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
529
                 */
530
                public void mouseExited(MouseEvent e) {
531
                        try {
532
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
533
                                for (int i = 0; i < b.length; i++) {
534
                                        b[i].mouseExited(e);
535
                                }
536
                        } catch (BehaviorException t) {
537
                                throwException(t);
538
                        }
539
                }
540

    
541
                /**
542
                 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
543
                 */
544
                public void mousePressed(MouseEvent e) {
545
                        try {
546
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
547
                                for (int i = 0; i < b.length; i++) {
548
                                        b[i].mousePressed(e);
549
                                }
550
                        } catch (BehaviorException t) {
551
                                throwException(t);
552
                        }
553
                }
554

    
555
                /**
556
                 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
557
                 */
558
                public void mouseReleased(MouseEvent e) {
559
                        try {
560
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
561
                                for (int i = 0; i < b.length; i++) {
562
                                        b[i].mouseReleased(e);
563
                                }
564
                        } catch (BehaviorException t) {
565
                                throwException(t);
566
                        }
567
                }
568

    
569
                /**
570
                 * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
571
                 */
572
                public void mouseWheelMoved(MouseWheelEvent e) {
573
                        try {
574
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
575
                                for (int i = 0; i < b.length; i++) {
576
                                        b[i].mouseWheelMoved(e);
577
                                }
578
                        } catch (BehaviorException t) {
579
                                throwException(t);
580
                        }
581
                }
582

    
583
                /**
584
                 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
585
                 */
586
                public void mouseDragged(MouseEvent e) {
587
                        try {
588
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
589
                                for (int i = 0; i < b.length; i++) {
590
                                        b[i].mouseDragged(e);
591
                                }
592
                        } catch (BehaviorException t) {
593
                                throwException(t);
594
                        }
595
                }
596

    
597
                /**
598
                 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
599
                 */
600
                public void mouseMoved(MouseEvent e) {
601
                        try {
602
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
603
                                for (int i = 0; i < b.length; i++) {
604
                                        b[i].mouseMoved(e);
605
                                }
606
                        } catch (BehaviorException t) {
607
                                throwException(t);
608
                        }
609
                }
610
        }
611

    
612
        /**
613
         * Listener sobre el MapContext.
614
         *
615
         * @author Fernando Gonz?lez Cort?s
616
         */
617
        public class MapContextListener implements AtomicEventListener {
618
                /**
619
                 * @see com.iver.cit.gvsig.fmap.AtomicEventListener#atomicEvent(com.iver.cit.gvsig.fmap.AtomicEvent)
620
                 */
621
                public void atomicEvent(AtomicEvent e) {
622
                        boolean redraw = false;
623
                        LayerEvent[] layerEvents = e.getLayerEvents();
624

    
625
                        for (int i = 0; i < layerEvents.length; i++) {
626
                                if (layerEvents[i].getProperty().equals("visible")) {
627
                                        redraw = true;
628
                                }
629
                        }
630

    
631
                        if (e.getColorEvents().length > 0) {
632
                                redraw = true;
633
                        }
634

    
635
                        if (e.getExtentEvents().length > 0) {
636
                                redraw = true;
637
                        }
638

    
639
                        if (e.getLayerCollectionEvents().length > 0) {
640
                                redraw = true;
641
                        }
642

    
643
                        if (e.getLegendEvents().length > 0) {
644
                                redraw = true;
645
                        }
646

    
647
                        if (e.getSelectionEvents().length > 0) {
648
                                redraw = true;
649
                        }
650

    
651
                        if (redraw) {
652
                                MapControl.this.drawMap(false);
653
                        }
654
                }
655
        }
656
        public ViewPort getViewPort() {
657
                return vp;
658
        }
659
        public CadGrid getGrid(){
660
                return grid;
661
        }
662
        public void setGrid(CadGrid cg){
663
                grid=cg;
664
        }
665
}