Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.ui / src / main / java / org / gvsig / gui / beans / imagenavigator / ImageNavigator.java @ 40561

History | View | Annotate | Download (24 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.gui.beans.imagenavigator;
25

    
26
import java.awt.AlphaComposite;
27
import java.awt.Color;
28
import java.awt.Cursor;
29
import java.awt.GradientPaint;
30
import java.awt.Graphics;
31
import java.awt.Graphics2D;
32
import java.awt.Image;
33
import java.awt.Point;
34
import java.awt.RenderingHints;
35
import java.awt.color.ColorSpace;
36
import java.awt.event.KeyEvent;
37
import java.awt.event.KeyListener;
38
import java.awt.event.MouseEvent;
39
import java.awt.event.MouseListener;
40
import java.awt.event.MouseMotionListener;
41
import java.awt.event.MouseWheelEvent;
42
import java.awt.event.MouseWheelListener;
43
import java.awt.image.BufferedImage;
44
import java.awt.image.ColorConvertOp;
45
import java.util.ArrayList;
46

    
47
import javax.swing.ImageIcon;
48
import javax.swing.JComponent;
49

    
50
import org.gvsig.gui.beans.Messages;
51
/**
52
 * <code>ImageNavigator</code> es un componente que representa un manejador
53
 * de im?genes. En ?l se puede desplazar, hacer un zoom out o un zoom in a una
54
 * imagen virtual. El componente no trata la imagen en si, solo lanza los
55
 * eventos indicando la nueva posici?n y zoom de la imagen, luego es el usuario
56
 * el que se encargar? de dibujar esa imagen en la posici?n correspondiente.
57
 *
58
 * El modo de uso es el siguiente:
59
 * - Se puede desplazar una imagen con el bot?n izquierdo del rat?n.
60
 * - Se puede hacer zoom in/out con las teclas +/- del teclado.
61
 * - Se puede hacer zoom in/out con la rueda del rat?n teniendo en cuenta la
62
 * posici?n del mismo.
63
 * - Se puede resetear los valores con las teclas 'Espacio' o 0;
64
 * - Las teclas 1, 2, 3, 4 y 5 equivalen a zoom 1, 2, 4, 8 y 16 respectivamente.
65
 * - La tecla C sirve para centrar la imagen.
66
 * - La tecla B sirve para mostrar u ocultar los cuadros del fondo. ?til para
67
 *   mostrar imagenes con transparencia.
68
 * - La tecla H muestra la ayuda.
69
 *
70
 * @version 04/05/2007
71
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
72
 */
73
public class ImageNavigator extends JComponent implements KeyListener, MouseMotionListener, MouseListener, MouseWheelListener {
74
        private static final long serialVersionUID = 1164788214432359272L;
75
        private IClientImageNavigator iClient         = null;
76

    
77
        private Image                 image           = null;
78
        private Graphics2D            widgetGraphics  = null;
79
        private Image                 imageCache      = null;
80
        private Graphics2D            cacheGraphics   = null;
81

    
82
        private double                zoom            = 1.0;
83
        private double                x1              = 0.0;
84
        private double                y1              = 0.0;
85
        private boolean               yInverted       = false;
86
        private boolean               xInverted       = false;
87
        private int                   width           = 0;
88
        private int                   height          = 0;
89
        private boolean               showHelp        = false;
90
        private boolean               showBackground  = false;
91
        private Color                 backgroundColor = new Color(224, 224, 224);
92
        private ImageIcon             imageIconClose  = null;
93
        private ImageIcon             imageIconHelp   = null;
94
        private ImageIcon             imageIconError  = null;
95

    
96
        private double                initX1          = 0.0;
97
        private double                initY1          = 0.0;
98
        private double                initX2          = 100.0;
99
        private double                initY2          = 100.0;
100
        private double                initZoom        = 1.0;
101
        private boolean               autoAdjusted    = true;
102

    
103
        private boolean               errorDrawing    = false;
104
        private String                errorDrawingMsg = null;
105

    
106

    
107
        /**
108
         * Crea un <code>ImageNavigator</code>
109
         */
110
        public ImageNavigator() {
111
                this.setFocusable(true);
112
                this.addKeyListener(this);
113
                this.addMouseMotionListener(this);
114
                this.addMouseListener(this);
115
                this.addMouseWheelListener(this);
116
        }
117
        
118
        /**
119
         * Crea un <code>ImageNavigator</code> especificandole quien pintara el
120
         * componente
121
         * @param iClient
122
         */
123
        public ImageNavigator(IClientImageNavigator iClient) {
124
                this();
125
                setClientImageNavigator(iClient);
126
        }
127
        
128
        public void setClientImageNavigator(IClientImageNavigator iClient) {
129
                this.iClient = iClient;
130
        }
131

    
132
        /**
133
         * Actualiza las dimensiones para ajustar la imagen a los bordes especificados
134
         * con setViewDimensions.
135
         */
136
        private void updateDimensions() {
137
                double factor = this.getWidth() / (initX2 - initX1);
138
                if (factor > (this.getHeight() / (initY2 - initY1)))
139
                        factor = this.getHeight() / (initY2 - initY1);
140
                zoom = factor;
141
                imageCenter();
142
        }
143

    
144
        /**
145
         * Centra la imagen
146
         */
147
        public void imageCenter() {
148
                x1 = initX1;
149
                y1 = initY1;
150

    
151
                if (isXInverted())
152
                        x1 -= ((initX2 - initX1) - this.getWidth() / zoom) / 2.0;
153
                else
154
                        x1 += ((initX2 - initX1) - this.getWidth() / zoom) / 2.0;
155
                if (isYInverted())
156
                        y1 -= ((initY2 - initY1) - this.getHeight() / zoom) / 2.0;
157
                else
158
                        y1 += ((initY2 - initY1) - this.getHeight() / zoom) / 2.0;
159
        }
160

    
161
        /**
162
         * Especifica el rectangulo de la imagen a visualizar, pudiendo tener
163
         * cualquiera de los ejes X e Y invertidos
164
         *
165
         * @param x1 Coordenada izquierda
166
         * @param y1 Coordenada superior
167
         * @param x2 Coordenada derecha
168
         * @param y2 Coordenada inferior
169
         */
170
        public void setViewDimensions(double x1, double y1, double x2, double y2) {
171
                this.initX1 = x1;
172
                this.initX2 = x2;
173
                this.initY1 = y1;
174
                this.initY2 = y2;
175

    
176
                yInverted = (y2 < y1);
177
                if (yInverted) {
178
                        this.initY1 = y2;
179
                        this.initY2 = y1;
180
                }
181

    
182
                xInverted = (x2 < x1);
183
                if (xInverted) {
184
                        this.initX1 = x2;
185
                        this.initX2 = x1;
186
                }
187

    
188
                this.updateDimensions();
189
        }
190

    
191
        /**
192
         * Hace un forzado de pintado del buffer temporal de la imagen. Este m?todo
193
         * forzar? una llamada a la funci?n de pintado del cliente.
194
         */
195
        public void updateBuffer() {
196
                updateImageCache(true);
197
                refreshImage(0, 0);
198
        }
199

    
200
        /**
201
         * Especifica el zoom que usar? por defecto el componente.
202
         * @param zoom
203
         */
204
        public void setZoom(double zoom) {
205
                initZoom = zoom;
206
                this.zoom = initZoom;
207
                autoAdjusted = false;
208
                imageCenter();
209
        }
210

    
211
        /**
212
         * Especifica el zoom que usar? por defecto el componente.
213
         * @param zoom
214
         */
215
        public void setAutoAdjusted() {
216
                autoAdjusted = true;
217
                updateDimensions();
218
                updateImageCache(true);
219
                refreshImage(0, 0);
220
        }
221

    
222
        /*
223
         * (non-Javadoc)
224
         * @see javax.swing.JComponent#addNotify()
225
         */
226
        public void addNotify() {
227
                super.addNotify();
228

    
229
                updateImageCache(true);
230
                refreshImage(0, 0);
231
        }
232

    
233
        /**
234
         * Hace un zoom de aumento en las coordenadas especificadas
235
         * @param x
236
         * @param y
237
         */
238
        private void ZoomIn(double x, double y) {
239
                double xcent = (x / zoom);
240
                double ycent = (y / zoom);
241
                if (isXInverted())
242
                        x1 -= xcent;
243
                else
244
                        x1 += xcent;
245
                if (isYInverted())
246
                        y1 -= ycent;
247
                else
248
                        y1 += ycent;
249
                zoom = zoom * 2.0;
250
                xcent = (x / zoom);
251
                ycent = (y / zoom);
252
                if (isXInverted())
253
                        x1 += xcent;
254
                else
255
                        x1 -= xcent;
256
                if (isYInverted())
257
                        y1 += ycent;
258
                else
259
                        y1 -= ycent;
260
                updateImageCache(true);
261
                refreshImage(0, 0);
262
        }
263

    
264
        /**
265
         * Hace un zoom hacia afuera en las coordenadas especificadas
266
         * @param x
267
         * @param y
268
         */
269
        private void ZoomOut(double x, double y) {
270
                double xcent = (x / zoom);
271
                double ycent = (y / zoom);
272
                if (isXInverted())
273
                        x1 -= xcent;
274
                else
275
                        x1 += xcent;
276
                if (isYInverted())
277
                        y1 -= ycent;
278
                else
279
                        y1 += ycent;
280
                zoom = zoom / 2.0;
281
                xcent = (x / zoom);
282
                ycent = (y / zoom);
283
                if (isXInverted())
284
                        x1 += xcent;
285
                else
286
                        x1 -= xcent;
287
                if (isYInverted())
288
                        y1 += ycent;
289
                else
290
                        y1 -= ycent;
291
                updateImageCache(true);
292
                refreshImage(0, 0);
293
        }
294

    
295
        /**
296
         * Mostrar o ocultar la ayuda
297
         *
298
         */
299
        private void callShowHelp() {
300
                showHelp = !showHelp;
301
                updateImageCache(true);
302
                refreshImage(0, 0);
303
        }
304

    
305
        /*
306
         * (non-Javadoc)
307
         * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
308
         */
309
        public void keyPressed(KeyEvent e) {
310
                switch (e.getKeyChar()) {
311
                        case 'h':
312
                        case 'H':
313
                                callShowHelp();
314
                                break;
315
                        case '+':
316
                                ZoomIn(width / 2.0, height / 2.0);
317
                                autoAdjusted = false;
318
                                break;
319
                        case '-':
320
                                ZoomOut(width / 2.0, height / 2.0);
321
                                autoAdjusted = false;
322
                                break;
323
                        case '1':
324
                                autoAdjusted = false;
325
                                this.zoom = initZoom;
326
                                imageCenter();
327
                                updateImageCache(true);
328
                                refreshImage(0, 0);
329
                                break;
330
                        case '2':
331
                                autoAdjusted = false;
332
                                this.zoom = initZoom * 2.0;
333
                                imageCenter();
334
                                updateImageCache(true);
335
                                refreshImage(0, 0);
336
                                break;
337
                        case '3':
338
                                autoAdjusted = false;
339
                                this.zoom = initZoom * 4.0;
340
                                imageCenter();
341
                                updateImageCache(true);
342
                                refreshImage(0, 0);
343
                                break;
344
                        case '4':
345
                                autoAdjusted = false;
346
                                this.zoom = initZoom * 8.0;
347
                                imageCenter();
348
                                updateImageCache(true);
349
                                refreshImage(0, 0);
350
                                break;
351
                        case '5':
352
                                autoAdjusted = false;
353
                                this.zoom = initZoom * 16.0;
354
                                imageCenter();
355
                                updateImageCache(true);
356
                                refreshImage(0, 0);
357
                                break;
358
                        case 'c':
359
                        case 'C':
360
                                imageCenter();
361
                                updateImageCache(true);
362
                                refreshImage(0, 0);
363
                                break;
364
                        case 'b':
365
                        case 'B':
366
                                setShowBackground(!isShowBackground());
367
                                break;
368
                        case '0':
369
                        case ' ':
370
                                setAutoAdjusted();
371
                                break;
372
                }
373
        }
374

    
375
        double updateWidth = 0;
376
        double updateHeight = 0;
377
        /**
378
         * M?todo que hara la invocaci?n al cliente del pintado del trozo de imagen a
379
         * visualizar
380
         * @param forceUpdate
381
         */
382
        private void updateImageCache(boolean forceUpdate) {
383
                if (getWidgetImage() == null ||
384
                                (updateWidth == getWidgetImage().getWidth(this) &&
385
                                updateHeight == getWidgetImage().getHeight(this) &&
386
                                !forceUpdate))
387
                        return;
388
                updateWidth = getWidgetImage().getWidth(this);
389
                updateHeight = getWidgetImage().getHeight(this);
390

    
391
                if (showBackground) {
392
                        for (int i = 0; (i * 4) <= width; i++) {
393
                                for (int j = 0; (j * 4) <= height; j++) {
394
                                        if ((i + j) % 2 == 0)
395
                                                getCacheGraphics().setColor(Color.white);
396
                                        else
397
                                                getCacheGraphics().setColor(getBackgroundColor());
398
                                        getCacheGraphics().fillRect(i * 4, j * 4, 4, 4);
399
                                }
400
                        }
401
                } else {
402
                        getCacheGraphics().setColor(Color.white);
403
                        getCacheGraphics().fillRect(0, 0, width, height);
404
                }
405

    
406
                double newY1 = 0.0;
407
                double newY2 = 0.0;
408
                double newX1 = 0.0;
409
                double newX2 = 0.0;
410

    
411
                if (isYInverted()) {
412
                        newY1 = y1 + this.getHeight() / zoom - ((y1 - initY1) * 2.0);
413
                        newY2 = newY1 - this.getHeight() / zoom;
414
                } else {
415
                        newY1 = y1;
416
                        newY2 = y1 + this.getHeight() / zoom;
417
                }
418

    
419
                if (isXInverted()) {
420
                        newX1 = x1 + this.getWidth() / zoom - ((x1 - initX1) * 2.0);
421
                        newX2 = newX1 - this.getWidth() / zoom;
422
                } else {
423
                        newX1 = x1;
424
                        newX2 = x1 + this.getWidth() / zoom;
425
                }
426

    
427
                if ((Double.isNaN(newX1)) || (Double.isNaN(newY1)))
428
                        return;
429

    
430
                if (iClient != null)
431
                        try {
432
                                errorDrawing = false;
433
                                iClient.drawImage(getCacheGraphics(), newX1, newY1, newX2, newY2, zoom, this.getWidth(), this.getHeight());
434
                        } catch (ImageUnavailableException e) {
435
                                getCacheGraphics().setColor(new Color(224, 224, 224));
436
                                getCacheGraphics().fillRect(0, 0, width, height);
437
                                errorDrawing = true;
438
                                errorDrawingMsg = e.getMessage();
439
                        }
440
        }
441

    
442
        private Image getWidgetImage() {
443
                int width2 = getBounds().width;
444
                int height2 = getBounds().height;
445
                if (width2 <= 0)
446
                        width2 = 1;
447
                if (height2 <= 0)
448
                        height2=1;
449

    
450
                if ((width != width2) || (height != height2)) {
451
                        image = createImage(width2, height2);
452
                        imageCache = createImage(width2, height2);
453
                        if (image == null)
454
                                return null;
455
                        widgetGraphics = (Graphics2D) image.getGraphics();
456
                        cacheGraphics = (Graphics2D) imageCache.getGraphics();
457

    
458
                        RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
459
                        hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
460
                        cacheGraphics.setRenderingHints(hints);
461
                }
462

    
463
                width = width2;
464
                height = height2;
465
                return image;
466
        }
467

    
468
        private Graphics2D getWidgetGraphics() {
469
                getWidgetImage();
470
                return widgetGraphics;
471
        }
472

    
473
        private Graphics2D getCacheGraphics() {
474
                getWidgetImage();
475
                return cacheGraphics;
476
        }
477

    
478
        /**
479
         * Redibujar el componente en el graphics temporal
480
         */
481
        private void redrawBuffer(int x, int y) {
482
                if (showBackground) {
483
                        for (int i = -2; ((i - 2) * 4) <= width; i++) {
484
                                for (int j = -2; ((j - 2) * 4) <= height; j++) {
485
                                        if ((i + j) % 2 == 0)
486
                                                getWidgetGraphics().setColor(Color.white);
487
                                        else
488
                                                getWidgetGraphics().setColor(getBackgroundColor());
489
                                        getWidgetGraphics().fillRect((i * 4) + (x % 8), (j * 4) + (y % 8), 4, 4);
490
                                }
491
                        }
492
                } else {
493
                        getWidgetGraphics().setColor(Color.white);
494
                        getWidgetGraphics().fillRect(0, 0, width, height);
495
                }
496

    
497
                getWidgetGraphics().drawImage(imageCache, x, y, null);
498

    
499
                if (errorDrawing) {
500
                        paintError((Graphics2D) getWidgetGraphics());
501
                } else {
502
                        if (showHelp) {
503
                                paintHelp((Graphics2D) getWidgetGraphics());
504
                        } else {
505
                                getWidgetGraphics().drawImage(getIconHelp().getImage(), width - getIconHelp().getIconWidth() - 4, 3, null);
506
                        }
507
                }
508
        }
509

    
510
        /*
511
         * (non-Javadoc)
512
         * @see javax.swing.JComponent#paint(java.awt.Graphics)
513
         */
514
        public void paint(Graphics g) {
515
                if (autoAdjusted) updateDimensions();
516
                Graphics2D g2d = (Graphics2D) g;
517
                RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
518
                hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
519
                g2d.setRenderingHints(hints);
520

    
521
                updateImageCache(false);
522

    
523
                redrawBuffer(0, 0);
524

    
525
                if (image != null) {
526
                        if (isEnabled()) {
527
                                g.drawImage(image, 0, 0, this);
528
                        } else {
529
                                // Dibujar en escala de grises y aclarado para cuando esta inactivo
530
                                BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
531

    
532
                                Graphics big = bi.createGraphics();
533
                                big.drawImage(image, 0, 0, this);
534

    
535
                                ColorConvertOp colorConvert = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
536
                                colorConvert.filter(bi, bi);
537

    
538
                                big.setColor(new Color(255, 255, 255, 164));
539
                                big.fillRect(0, 0, width, height);
540

    
541
                                g.drawImage(bi, getVisibleRect().x, getVisibleRect().y, this);
542
                        }
543
                }
544
        }
545

    
546
        /**
547
         * Redibujar el componente en el graphics temporal y representarlo en el
548
         * componente
549
         */
550
        private void refreshImage(int x, int y) {
551
                Graphics2D g2d = (Graphics2D) getGraphics();
552
                if (g2d == null)
553
                        return;
554
                RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
555
                hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
556
                g2d.setRenderingHints(hints);
557
                redrawBuffer(x, y);
558

    
559
                if (image != null)
560
                        getGraphics().drawImage(image, 0, 0, this);
561
        }
562

    
563
        /**
564
         * Devuelve el icono de cerrar
565
         * @return
566
         */
567
        private ImageIcon getIconClose() {
568
                if (imageIconClose == null) {
569
                        imageIconClose = new ImageIcon(ImageNavigator.class.getResource("images/close.png"));
570
                }
571
                return imageIconClose;
572
        }
573

    
574
        /**
575
         * Devuelve el icono de error
576
         * @return
577
         */
578
        private ImageIcon getIconError() {
579
                if (imageIconError == null) {
580
                        imageIconError = new ImageIcon(ImageNavigator.class.getResource("images/error.png"));
581
                }
582
                return imageIconError;
583
        }
584

    
585
        /**
586
         * Devuelve el icono ayuda
587
         * @return
588
         */
589
        private ImageIcon getIconHelp() {
590
                if (imageIconHelp == null) {
591
                        imageIconHelp = new ImageIcon(ImageNavigator.class.getResource("images/help.png"));
592
                }
593
                return imageIconHelp;
594
        }
595

    
596
        private void paintHelp(Graphics2D g) {
597
                int sep = 13;
598
                int pos = sep + 1;
599

    
600
                int alto = sep * 8 + 6;
601

    
602
                Image image2 = createImage(width, alto);
603
                Graphics2D graphics2 = (Graphics2D) image2.getGraphics();
604

    
605
                RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
606
                hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
607
                graphics2.setRenderingHints(hints);
608

    
609
                alto--;
610

    
611
                Color color1 = new Color(255, 255, 178);
612
                Color color2 = new Color(255, 255, 74);
613
                graphics2.setPaint(new GradientPaint(0, 0, color1, 0, alto, color2, false));
614
                graphics2.fillRect(0, 0, width, alto);
615

    
616
                graphics2.setColor(new Color(0, 0, 0));
617

    
618
                graphics2.setFont(new java.awt.Font("Tahoma", 1, sep - 2));
619

    
620
                graphics2.drawString(Messages.getText("teclas") + ":", 10, pos);
621

    
622
                graphics2.setFont(new java.awt.Font("Tahoma", 0, sep - 2));
623
                pos += sep;
624
                graphics2.drawString(Messages.getText("ayuda_c"), 20, pos);
625
                pos += sep;
626
                graphics2.drawString(Messages.getText("ayuda_0"), 20, pos);
627
                pos += sep;
628
                graphics2.drawString(Messages.getText("ayuda_1_5"), 20, pos);
629
                pos += sep;
630
                graphics2.drawString(Messages.getText("ayuda_more_less"), 20, pos);
631
                pos += sep;
632
                graphics2.drawString(Messages.getText("ayuda_wheel"), 20, pos);
633
                pos += sep;
634
                graphics2.drawString(Messages.getText("ayuda_background"), 20, pos);
635
                pos += sep;
636
                graphics2.drawString(Messages.getText("ayuda_h"), 20, pos);
637

    
638
                graphics2.setColor(new Color(185, 185, 185));
639
                graphics2.drawLine(0, alto, width, alto);
640

    
641
                graphics2.drawImage(getIconClose().getImage(), width - getIconClose().getIconWidth() - 4, 3, null);
642

    
643
                AlphaComposite myAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);
644
                g.setComposite(myAlpha);
645

    
646
                g.drawImage(image2, 0, 0, this);
647

    
648
                myAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
649
                g.setComposite(myAlpha);
650
        }
651
        
652
        private ArrayList<String> splitString4Width(Graphics2D g, String msg, int width) {
653
                String words[] = msg.split(" ");
654

    
655
                ArrayList<String> newString = new ArrayList<String>();
656
                String aux = "";
657
                for (int i = 0; i < words.length; i++) {
658
                        if (aux.length() == 0) {
659
                                aux = words[i];
660
                                continue;
661
                        }
662
                        if (g.getFontMetrics().getStringBounds(aux + " " + words[i], g).getWidth() <= width) {
663
                                aux += " " + words[i];
664
                                continue;
665
                        }
666

    
667
                        newString.add(aux);
668
                        aux = words[i];
669
                }
670
                newString.add(aux);
671

    
672
                return newString;
673
        }
674

    
675
        private ArrayList<String> splitString4Intro(Graphics2D g, String msg, int width) {
676
                String words[] = msg.split("\n");
677
                ArrayList<String> newString = new ArrayList<String>();
678
                for (int i = 0; i < words.length; i++) {
679
                        ArrayList<String> more = splitString4Width(g, words[i], width);
680
                        for (int j = 0; j < more.size(); j++) {
681
                                newString.add(more.get(j));
682
                        }
683
                }
684

    
685
                return newString;
686
        }
687
        
688
        private void paintError(Graphics2D g) {
689
                ArrayList<String> errors = splitString4Intro(g, errorDrawingMsg, width - 30);
690

    
691
                int size = errors.size();
692
                if (size < 6)
693
                        size = 6;
694
                
695
                int sep = 13;
696
                int pos = sep + 2;
697

    
698
                int alto = sep * size + 8;
699

    
700
                Image image2 = createImage(width, alto);
701
                Graphics2D graphics2 = (Graphics2D) image2.getGraphics();
702

    
703
                alto--;
704

    
705
                Color color1 = new Color(255, 152, 152);
706
                Color color2 = new Color(255, 100, 100);
707
                graphics2.setPaint(new GradientPaint(0, 0, color1, 0, alto, color2, false));
708
                graphics2.fillRect(0, 0, width, alto);
709

    
710
                graphics2.setColor(new Color(0, 0, 0));
711

    
712
                graphics2.setFont(new java.awt.Font("Tahoma", 0, sep - 2));
713

    
714
                for (int i=0; i<errors.size(); i++) { 
715
                        graphics2.drawString((String) errors.get(i), 24, pos);
716
                        pos+=sep;
717
                }
718
                
719
                graphics2.drawImage(getIconError().getImage(), 4, 4, null);
720

    
721
                graphics2.setColor(new Color(185, 185, 185));
722
                graphics2.drawLine(0, alto, width, alto);
723

    
724
                g.drawImage(image2, 0, 0, this);
725
        }
726

    
727

    
728
        Point mouse = null;
729
        /*
730
         * (non-Javadoc)
731
         * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
732
         */
733
        public void mousePressed(MouseEvent e) {
734
                if (!isInteractiveEnabled())
735
                        return;
736
                requestFocus();
737

    
738
                if ((e.getX() > (width - 20)) && (e.getY() < 20))
739
                        return;
740

    
741
                if ((e.getButton() != MouseEvent.BUTTON1) && (e.getButton() != MouseEvent.BUTTON2))
742
                        return;
743

    
744
                // Oscurece la imagen cuando se mueve
745
                Color gris = new Color(0, 0, 0, 16);
746
                getCacheGraphics().setColor(gris);
747
                getCacheGraphics().fillRect(0, 0, width-1, height-1);
748

    
749
                // Pone un borde a la imagen cuando se mueve
750
                getCacheGraphics().setColor(Color.gray);
751
                getCacheGraphics().drawRect(0, 0, width-1, height-1);
752

    
753
                mouse = new Point(e.getX(), e.getY());
754
                changePos(e.getX(), e.getY());
755
                autoAdjusted = false;
756
        }
757

    
758
        /*
759
         * (non-Javadoc)
760
         * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
761
         */
762
        public void mouseDragged(MouseEvent e) {
763
                if (!isInteractiveEnabled())
764
                        return;
765
                changePos(e.getX(), e.getY());
766
        }
767

    
768
        /*
769
         * (non-Javadoc)
770
         * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
771
         */
772
        public void mouseReleased(MouseEvent e) {
773
                if (!isInteractiveEnabled())
774
                        return;
775
                if (mouse != null) {
776
                        x1 = x1 - ((e.getX() - mouse.getX())/zoom);
777
                        y1 = y1 - ((e.getY() - mouse.getY())/zoom);
778
                        updateImageCache(true);
779
                        refreshImage(0, 0);
780
                }
781
                mouse = null;
782
        }
783

    
784
        private void changePos(int x, int y) {
785
                if (mouse != null)
786
                        refreshImage((int) (x - mouse.getX()), (int) (y - mouse.getY()));
787
        }
788

    
789
        /**
790
         * Evento de la rueda del rat?n para hacer Zoom In o Zoom Out en la posici?n
791
         * del puntero.
792
         */
793
        public void mouseWheelMoved(MouseWheelEvent e) {
794
                if (!isInteractiveEnabled())
795
                        return;
796

    
797
                if (e.getWheelRotation() > 0) {
798
                        ZoomOut(isXInverted() ? this.getWidth() - e.getX() : e.getX(), isYInverted() ? this.getHeight() - e.getY() : e.getY());
799
                        autoAdjusted = false;
800
                }
801
                if (e.getWheelRotation() < 0) {
802
                        ZoomIn(isXInverted() ? this.getWidth() - e.getX() : e.getX(), isYInverted() ? this.getHeight() - e.getY() : e.getY());
803
                        autoAdjusted = false;
804
                }
805
        }
806

    
807
        /**
808
         * Obtener si el eje de las Y esta invertido
809
         * @return
810
         */
811
        private boolean isYInverted() {
812
                return yInverted;
813
        }
814

    
815
        /**
816
         * Obtener si el eje de las X esta invertido
817
         * @return
818
         */
819
        private boolean isXInverted() {
820
                return xInverted;
821
        }
822

    
823
        /*
824
         * (non-Javadoc)
825
         * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
826
         */
827
        public void mouseMoved(MouseEvent e) {
828
                if (!isInteractiveEnabled())
829
                        return;
830
                if ((e.getX() > (width - 20)) && (e.getY() < 20)) {
831
                        setCursor(new Cursor(Cursor.HAND_CURSOR));
832
                        if (showHelp)
833
                                setToolTipText(Messages.getText("cerrar"));
834
                        else
835
                                setToolTipText(Messages.getText("ayuda"));
836
                } else {
837
                        setCursor(new Cursor(Cursor.MOVE_CURSOR));
838
                        setToolTipText(null);
839
                }
840
        }
841

    
842
        /*
843
         * (non-Javadoc)
844
         * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
845
         */
846
        public void mouseClicked(MouseEvent e) {
847
                if (!isInteractiveEnabled())
848
                        return;
849
                if ((e.getX() > (width - 20)) && (e.getY() < 20))
850
                        callShowHelp();
851
        }
852

    
853
        public void keyReleased(KeyEvent e) {}
854
        public void keyTyped(KeyEvent e) {}
855
        public void mouseEntered(MouseEvent e) {}
856
        public void mouseExited(MouseEvent e) {}
857

    
858
        /**
859
         * Define el color de los recuadros del fondo
860
         *
861
         * @param backgroundColor the backgroundColor to set
862
         */
863
        public void setBackgroundColor(Color backgroundColor) {
864
                this.backgroundColor = backgroundColor;
865
        }
866

    
867
        /**
868
         * Devuelve el color de los recuadros del fondo
869
         * @return the backgroundColor
870
         */
871
        public Color getBackgroundColor() {
872
                return backgroundColor;
873
        }
874

    
875
        /**
876
         * Devuelve si se esta mostrando o no la cuadricula de fondo.
877
         * @return the showBackground
878
         */
879
        public boolean isShowBackground() {
880
                return showBackground;
881
        }
882

    
883
        /**
884
         * Define si se muestra o no la cuadricula de fondo. Util para imagenes
885
         * transparentes
886
         * @param showBackground the showBackground to set
887
         */
888
        public void setShowBackground(boolean showBackground) {
889
                this.showBackground = showBackground;
890
                updateImageCache(true);
891
                refreshImage(0, 0);
892
        }
893
        
894
        /**
895
         * Devuelve si se pueden gestionar los eventos segun el estado del componente
896
         * @return
897
         */
898
        private boolean isInteractiveEnabled() {
899
                if (isEnabled() && !errorDrawing)
900
                        return true;
901
                return false;
902
        }
903

    
904
        /* (non-Javadoc)
905
         * @see javax.swing.JComponent#setEnabled(boolean)
906
         */
907
        public void setEnabled(boolean enabled) {
908
                super.setEnabled(enabled);
909
                updateImageCache(true);
910
                refreshImage(0, 0);
911
        }
912
}