Statistics
| Revision:

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

History | View | Annotate | Download (14.9 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

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

    
62
import org.cresques.cts.IProjection;
63
import org.cresques.cts.ProjectionPool;
64

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

    
73

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

    
83
        /** Cuando la vista est? desactualizada. */
84
        public static final int DESACTUALIZADO = 1;
85
        //private static Logger logger = Logger.getLogger(MapControl.class.getName());
86
        private FMap mapContext = null;
87
        private HashMap namesMapTools = new HashMap();
88
        private Behavior currentMapTool = null;
89
        private int status = DESACTUALIZADO;
90
        private BufferedImage image = null;
91
        private String currentTool;
92
        private CancelDraw canceldraw;
93
        private boolean isCancelled = true;
94
        private Timer timer;
95
        protected ViewPort vp;
96
        private Drawer drawer;
97
        private MapToolListener mapToolListener = new MapToolListener();
98
        private MapContextListener mapContextListener = new MapContextListener();
99
        private ExceptionHandlingSupport exceptionHandlingSupport = new ExceptionHandlingSupport();
100

    
101
        /**
102
         * Crea un nuevo NewMapControl.
103
         */
104
        public MapControl() {
105
                setDoubleBuffered(false);
106
                setOpaque(true);
107
                status = DESACTUALIZADO;
108

    
109
                //Clase usada para cancelar el dibujado
110
                canceldraw = new CancelDraw();
111

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

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

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

    
144
                mapContext = model;
145

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

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

    
155
                mapContext.addAtomicEventListener(mapContextListener);
156

    
157
                status = DESACTUALIZADO;
158
        }
159

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

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

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

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

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

    
215
        /**
216
         * Devuelve el nombre de la herramienta seleccionada.
217
         *
218
         * @return nombre.
219
         */
220
        public String getTool() {
221
                return currentTool;
222
        }
223

    
224
        /**
225
         * Cancela el dibujado. Se espera a que la cancelaci?n surta efecto
226
         */
227
        public void cancelDrawing() {
228
                if (drawer != null) {
229
                        if (!drawer.isAlive()) {
230
                                return;
231
                        }
232
                }
233

    
234
                canceldraw.setCancel(true);
235

    
236
                while (!isCancelled) {
237
                        if (!drawer.isAlive()) {
238
                            // Si hemos llegado aqu? con un thread vivo, seguramente
239
                            // no estamos actualizados.
240

    
241
                                break;
242
                        }
243
                    
244
                }
245
                canceldraw.setCancel(false);
246
                isCancelled = false;
247
        }
248

    
249
        /**
250
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
251
         */
252
        protected void paintComponent(Graphics g) {
253
                if (status == ACTUALIZADO) {
254
                        // LWS logger.debug("Dibujando la imagen obtenida");
255

    
256
                        /*
257
                         * Si hay un behaviour y la imagen es distinta de null se delega el dibujado
258
                         * en dicho behaviour
259
                         */
260
                        if ((currentMapTool != null) && (image != null)) {
261
                                currentMapTool.paintComponent(g);                           
262
                                // LWS System.out.println("Pinto ACTUALIZADO");
263
                        }
264
                } else if (status == DESACTUALIZADO) {
265
                        // LWS System.out.println("DESACTUALIZADO: Obteniendo la imagen de la cartograf?a");
266
                        /* if (isOpaque())
267
                        {
268
                            if (image==null)
269
                            {
270
                                g.setColor(vp.getBackColor());
271
                                g.fillRect(0,0,getWidth(), getHeight());                        
272
                            } 
273
                            // else g.drawImage(image,0,0,null);
274
                        } */
275

    
276
                        //Se crea la imagen con el color de fonde deseado
277
                        if (image == null)
278
                        {
279
                                image = new BufferedImage(this.getWidth(), this.getHeight(),
280
                                                BufferedImage.TYPE_INT_ARGB);
281
                                vp.setImageSize(new Dimension(getWidth(), getHeight()));
282
                                Graphics gTemp = image.createGraphics();
283
                            Color theBackColor = vp.getBackColor();
284
                            if (theBackColor == null)
285
                                gTemp.setColor(Color.WHITE);
286
                            else
287
                                gTemp.setColor(theBackColor);
288
                                
289
                                gTemp.fillRect(0,0,getWidth(), getHeight());
290
                                gTemp.dispose();
291
                                // g.drawImage(image,0,0,null);
292
                                System.out.println("Imagen con null en DESACTUALIZADO");
293
                        }
294
                        g.drawImage(image,0,0,null);
295
                        
296
                        Graphics imgg = image.createGraphics();
297

    
298
                        //Se cancela el dibujado anterior
299
                        cancelDrawing();
300

    
301
                        drawer = new Drawer(image, (Graphics2D) imgg, canceldraw);
302
                        drawer.start();
303
                        //Se lanza el tread de dibujado
304
                        timer.start();
305
                        
306
                        status = ACTUALIZADO;
307

    
308
                        // repaint();
309
                }
310
        }
311

    
312
        /**
313
         * Devuelve la imagen de la vista.
314
         *
315
         * @return imagen.
316
         */
317
        public BufferedImage getImage() {
318
                return image;
319
        }
320

    
321
        /**
322
         * Marca el mapa para que en el pr?ximo redibujado se acceda a la
323
         * cartograf?a para reobtener la imagen
324
         * @param doClear TODO
325
         */
326
        public void drawMap(boolean doClear) {
327
                status = DESACTUALIZADO;
328
                if (doClear) image = null; // Se usa para el PAN
329
                repaint();
330
        }
331

    
332
        /**
333
         * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
334
         */
335
        public void componentHidden(ComponentEvent e) {
336
        }
337

    
338
        /**
339
         * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
340
         */
341
        public void componentMoved(ComponentEvent e) {
342
        }
343

    
344
        /**
345
         * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
346
         */
347
        public void componentResized(ComponentEvent e) {
348
                /* image = new BufferedImage(this.getWidth(), this.getHeight(),
349
                                BufferedImage.TYPE_INT_ARGB);                
350
                Graphics gTemp = image.createGraphics();
351
                gTemp.setColor(vp.getBackColor());
352
                gTemp.fillRect(0,0,getWidth(), getHeight()); */
353
            image = null;
354
            vp.setImageSize(new Dimension(getWidth(), getHeight()));
355
                getMapContext().getViewPort().setScale();
356
                drawMap(false);
357
        }
358

    
359
        /**
360
         * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
361
         */
362
        public void componentShown(ComponentEvent e) {
363
        }
364

    
365
        /**
366
         * A?ade un listener de tipo ExceptionListener.
367
         *
368
         * @param o ExceptionListener.
369
         */
370
        public void addExceptionListener(ExceptionListener o) {
371
                exceptionHandlingSupport.addExceptionListener(o);
372
        }
373

    
374
        /**
375
         * Borra la ExceptioListener que se pasa como par?metro.
376
         *
377
         * @param o ExceptionListener.
378
         *
379
         * @return True si se borra correctamente.
380
         */
381
        public boolean removeExceptionListener(ExceptionListener o) {
382
                return exceptionHandlingSupport.removeExceptionListener(o);
383
        }
384

    
385
        /**
386
         * Lanza una Excepci?n.
387
         *
388
         * @param t Excepci?n.
389
         */
390
        private void throwException(Throwable t) {
391
                exceptionHandlingSupport.throwException(t);
392
        }
393

    
394
        /**
395
         * Clase utilizada para dibujar las capas.
396
         *
397
         * @author Vicente Caballero Navarro
398
         */
399
        public class Drawer extends Thread {
400
                //private Graphics g;
401
                private BufferedImage image;
402
                private CancelDraw cancel;
403
                //private boolean threadCancel = false;
404

    
405
                /**
406
                 * Crea un nuevo Drawer.
407
                 *
408
                 * @param image
409
                 * @param g
410
                 * @param cancel
411
                 */
412
                public Drawer(BufferedImage image, Graphics g, CancelDraw cancel) {
413
                        //this.g = g;
414
                        this.image = image;
415
                        this.cancel = cancel;
416
                }
417

    
418
                /**
419
                 * @see java.lang.Runnable#run()
420
                 */
421
                public void run() {
422
                        try {
423
                                synchronized (Drawer.class) {
424
                                    Graphics2D g = image.createGraphics();
425
                                    ViewPort viewPort = mapContext.getViewPort();
426
                                    Color theBackColor = viewPort.getBackColor();
427
                                    if (theBackColor == null)
428
                                        g.setColor(Color.WHITE);
429
                                    else
430
                                        g.setColor(theBackColor);
431
                                        g.fillRect(0, 0, viewPort.getImageWidth(), viewPort.getImageHeight());
432

    
433
                                        mapContext.draw(image, g, cancel,mapContext.getScaleView());
434

    
435
                                        isCancelled = true;
436
                                        timer.stop();
437
                                        repaint();
438
                                    
439
                                }
440
                        } catch (Throwable e) {
441
                            timer.stop();
442
                                isCancelled = true;
443
                                throwException(e);
444
                        } finally {
445
                        }
446
                }
447
        }
448

    
449
        /**
450
         * Clase para cancelar el dibujado.
451
         *
452
         * @author Fernando Gonz?lez Cort?s
453
         */
454
        public class CancelDraw implements Cancellable {
455
                private boolean cancel = false;
456

    
457
                /**
458
                 * Crea un nuevo CancelDraw.
459
                 */
460
                public CancelDraw() {
461
                }
462

    
463
                /**
464
                 * Insertar si se debe cancelar el dibujado.
465
                 *
466
                 * @param b true si se debe cancelar el dibujado.
467
                 */
468
                public void setCancel(boolean b) {
469
                        cancel = b;
470
                }
471

    
472
                /**
473
                 * @see com.iver.cit.gvsig.fmap.operations.Cancellable#isCanceled()
474
                 */
475
                public boolean isCanceled() {
476
                        return cancel;
477
                }
478
        }
479

    
480
        /**
481
         * Listener del MapTool.
482
         *
483
         * @author Fernando Gonz?lez Cort?s
484
         */
485
        public class MapToolListener implements MouseListener, MouseWheelListener,
486
                MouseMotionListener {
487
                /**
488
                 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
489
                 */
490
                public void mouseClicked(MouseEvent e) {
491
                        try {
492
                                currentMapTool.mouseClicked(e);
493
                        } catch (BehaviorException t) {
494
                                throwException(t);
495
                        }
496
                }
497

    
498
                /**
499
                 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
500
                 */
501
                public void mouseEntered(MouseEvent e) {
502
                        try {
503
                                currentMapTool.mouseEntered(e);
504
                        } catch (BehaviorException t) {
505
                                throwException(t);
506
                        }
507
                }
508

    
509
                /**
510
                 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
511
                 */
512
                public void mouseExited(MouseEvent e) {
513
                        try {
514
                                currentMapTool.mouseExited(e);
515
                        } catch (BehaviorException t) {
516
                                throwException(t);
517
                        }
518
                }
519

    
520
                /**
521
                 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
522
                 */
523
                public void mousePressed(MouseEvent e) {
524
                        try {
525
                                currentMapTool.mousePressed(e);
526
                        } catch (BehaviorException t) {
527
                                throwException(t);
528
                        }
529
                }
530

    
531
                /**
532
                 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
533
                 */
534
                public void mouseReleased(MouseEvent e) {
535
                        try {
536
                                currentMapTool.mouseReleased(e);
537
                        } catch (BehaviorException t) {
538
                                throwException(t);
539
                        }
540
                }
541

    
542
                /**
543
                 * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
544
                 */
545
                public void mouseWheelMoved(MouseWheelEvent e) {
546
                        try {
547
                                currentMapTool.mouseWheelMoved(e);
548
                        } catch (BehaviorException t) {
549
                                throwException(t);
550
                        }
551
                }
552

    
553
                /**
554
                 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
555
                 */
556
                public void mouseDragged(MouseEvent e) {
557
                        try {
558
                                currentMapTool.mouseDragged(e);
559
                        } catch (BehaviorException t) {
560
                                throwException(t);
561
                        }
562
                }
563

    
564
                /**
565
                 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
566
                 */
567
                public void mouseMoved(MouseEvent e) {
568
                        try {
569
                                currentMapTool.mouseMoved(e);
570
                        } catch (BehaviorException t) {
571
                                throwException(t);
572
                        }
573
                }
574
        }
575

    
576
        /**
577
         * Listener sobre el MapContext.
578
         *
579
         * @author Fernando Gonz?lez Cort?s
580
         */
581
        public class MapContextListener implements AtomicEventListener {
582
                /**
583
                 * @see com.iver.cit.gvsig.fmap.AtomicEventListener#atomicEvent(com.iver.cit.gvsig.fmap.AtomicEvent)
584
                 */
585
                public void atomicEvent(AtomicEvent e) {
586
                        boolean redraw = false;
587
                        LayerEvent[] layerEvents = e.getLayerEvents();
588

    
589
                        for (int i = 0; i < layerEvents.length; i++) {
590
                                if (layerEvents[i].getProperty().equals("visible")) {
591
                                        redraw = true;
592
                                }
593
                        }
594

    
595
                        if (e.getColorEvents().length > 0) {
596
                                redraw = true;
597
                        }
598

    
599
                        if (e.getExtentEvents().length > 0) {
600
                                redraw = true;
601
                        }
602

    
603
                        if (e.getLayerCollectionEvents().length > 0) {
604
                                redraw = true;
605
                        }
606

    
607
                        if (e.getLegendEvents().length > 0) {
608
                                redraw = true;
609
                        }
610

    
611
                        if (e.getSelectionEvents().length > 0) {
612
                                redraw = true;
613
                        }
614

    
615
                        if (redraw) {
616
                                MapControl.this.drawMap(false);
617
                        }
618
                }
619
        }
620
        public ViewPort getViewPort() {
621
                return vp;
622
        }
623
}