Statistics
| Revision:

root / trunk / libraries / libUIComponent / src / org / gvsig / gui / beans / imagenavigator / ImageNavigator.java @ 21577

History | View | Annotate | Download (23.9 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 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
package org.gvsig.gui.beans.imagenavigator;
20

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

    
42
import javax.swing.ImageIcon;
43
import javax.swing.JComponent;
44

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

    
72
        private Image                 image           = null;
73
        private Graphics2D            widgetGraphics  = null;
74
        private Image                 imageCache      = null;
75
        private Graphics2D            cacheGraphics   = null;
76

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

    
91
        private double                initX1          = 0.0;
92
        private double                initY1          = 0.0;
93
        private double                initX2          = 100.0;
94
        private double                initY2          = 100.0;
95
        private double                initZoom        = 1.0;
96
        private boolean               autoAdjusted    = true;
97

    
98
        private boolean               errorDrawing    = false;
99
        private String                errorDrawingMsg = null;
100

    
101

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

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

    
139
        /**
140
         * Centra la imagen
141
         */
142
        public void imageCenter() {
143
                x1 = initX1;
144
                y1 = initY1;
145

    
146
                if (isXInverted())
147
                        x1 -= ((initX2 - initX1) - this.getWidth() / zoom) / 2.0;
148
                else
149
                        x1 += ((initX2 - initX1) - this.getWidth() / zoom) / 2.0;
150
                if (isYInverted())
151
                        y1 -= ((initY2 - initY1) - this.getHeight() / zoom) / 2.0;
152
                else
153
                        y1 += ((initY2 - initY1) - this.getHeight() / zoom) / 2.0;
154
        }
155

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

    
171
                yInverted = (y2 < y1);
172
                if (yInverted) {
173
                        this.initY1 = y2;
174
                        this.initY2 = y1;
175
                }
176

    
177
                xInverted = (x2 < x1);
178
                if (xInverted) {
179
                        this.initX1 = x2;
180
                        this.initX2 = x1;
181
                }
182

    
183
                this.updateDimensions();
184
        }
185

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

    
195
        /**
196
         * Especifica el zoom que usar? por defecto el componente.
197
         * @param zoom
198
         */
199
        public void setZoom(double zoom) {
200
                initZoom = zoom;
201
                this.zoom = initZoom;
202
                autoAdjusted = false;
203
                imageCenter();
204
        }
205

    
206
        /**
207
         * Especifica el zoom que usar? por defecto el componente.
208
         * @param zoom
209
         */
210
        public void setAutoAdjusted() {
211
                autoAdjusted = true;
212
                updateDimensions();
213
                updateImageCache(true);
214
                refreshImage(0, 0);
215
        }
216

    
217
        /*
218
         * (non-Javadoc)
219
         * @see javax.swing.JComponent#addNotify()
220
         */
221
        public void addNotify() {
222
                super.addNotify();
223

    
224
                updateImageCache(true);
225
                refreshImage(0, 0);
226
        }
227

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

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

    
290
        /**
291
         * Mostrar o ocultar la ayuda
292
         *
293
         */
294
        private void callShowHelp() {
295
                showHelp = !showHelp;
296
                updateImageCache(true);
297
                refreshImage(0, 0);
298
        }
299

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

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

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

    
401
                double newY1 = 0.0;
402
                double newY2 = 0.0;
403
                double newX1 = 0.0;
404
                double newX2 = 0.0;
405

    
406
                if (isYInverted()) {
407
                        newY1 = y1 + this.getHeight() / zoom - ((y1 - initY1) * 2.0);
408
                        newY2 = newY1 - this.getHeight() / zoom;
409
                } else {
410
                        newY1 = y1;
411
                        newY2 = y1 + this.getHeight() / zoom;
412
                }
413

    
414
                if (isXInverted()) {
415
                        newX1 = x1 + this.getWidth() / zoom - ((x1 - initX1) * 2.0);
416
                        newX2 = newX1 - this.getWidth() / zoom;
417
                } else {
418
                        newX1 = x1;
419
                        newX2 = x1 + this.getWidth() / zoom;
420
                }
421

    
422
                if ((Double.isNaN(newX1)) || (Double.isNaN(newY1)))
423
                        return;
424

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

    
437
        private Image getWidgetImage() {
438
                int width2 = getBounds().width;
439
                int height2 = getBounds().height;
440
                if (width2 <= 0)
441
                        width2 = 1;
442
                if (height2 <= 0)
443
                        height2=1;
444

    
445
                if ((width != width2) || (height != height2)) {
446
                        image = createImage(width2, height2);
447
                        imageCache = createImage(width2, height2);
448
                        if (image == null)
449
                                return null;
450
                        widgetGraphics = (Graphics2D) image.getGraphics();
451
                        cacheGraphics = (Graphics2D) imageCache.getGraphics();
452

    
453
                        RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
454
                        hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
455
                        cacheGraphics.setRenderingHints(hints);
456
                }
457

    
458
                width = width2;
459
                height = height2;
460
                return image;
461
        }
462

    
463
        private Graphics2D getWidgetGraphics() {
464
                getWidgetImage();
465
                return widgetGraphics;
466
        }
467

    
468
        private Graphics2D getCacheGraphics() {
469
                getWidgetImage();
470
                return cacheGraphics;
471
        }
472

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

    
492
                getWidgetGraphics().drawImage(imageCache, x, y, null);
493

    
494
                if (errorDrawing) {
495
                        paintError((Graphics2D) getWidgetGraphics());
496
                } else {
497
                        if (showHelp) {
498
                                paintHelp((Graphics2D) getWidgetGraphics());
499
                        } else {
500
                                getWidgetGraphics().drawImage(getIconHelp().getImage(), width - getIconHelp().getIconWidth() - 4, 3, null);
501
                        }
502
                }
503
        }
504

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

    
516
                updateImageCache(false);
517

    
518
                redrawBuffer(0, 0);
519

    
520
                if (image != null) {
521
                        if (isEnabled()) {
522
                                g.drawImage(image, 0, 0, this);
523
                        } else {
524
                                // Dibujar en escala de grises y aclarado para cuando esta inactivo
525
                                BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
526

    
527
                                Graphics big = bi.createGraphics();
528
                                big.drawImage(image, 0, 0, this);
529

    
530
                                ColorConvertOp colorConvert = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
531
                                colorConvert.filter(bi, bi);
532

    
533
                                big.setColor(new Color(255, 255, 255, 164));
534
                                big.fillRect(0, 0, width, height);
535

    
536
                                g.drawImage(bi, getVisibleRect().x, getVisibleRect().y, this);
537
                        }
538
                }
539
        }
540

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

    
554
                if (image != null)
555
                        getGraphics().drawImage(image, 0, 0, this);
556
        }
557

    
558
        /**
559
         * Devuelve el icono de cerrar
560
         * @return
561
         */
562
        private ImageIcon getIconClose() {
563
                if (imageIconClose == null) {
564
                        imageIconClose = new ImageIcon(ImageNavigator.class.getResource("images/close.png"));
565
                }
566
                return imageIconClose;
567
        }
568

    
569
        /**
570
         * Devuelve el icono de error
571
         * @return
572
         */
573
        private ImageIcon getIconError() {
574
                if (imageIconError == null) {
575
                        imageIconError = new ImageIcon(ImageNavigator.class.getResource("images/error.png"));
576
                }
577
                return imageIconError;
578
        }
579

    
580
        /**
581
         * Devuelve el icono ayuda
582
         * @return
583
         */
584
        private ImageIcon getIconHelp() {
585
                if (imageIconHelp == null) {
586
                        imageIconHelp = new ImageIcon(ImageNavigator.class.getResource("images/help.png"));
587
                }
588
                return imageIconHelp;
589
        }
590

    
591
        private void paintHelp(Graphics2D g) {
592
                int sep = 13;
593
                int pos = sep + 1;
594

    
595
                int alto = sep * 8 + 6;
596

    
597
                Image image2 = createImage(width, alto);
598
                Graphics2D graphics2 = (Graphics2D) image2.getGraphics();
599

    
600
                RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
601
                hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
602
                graphics2.setRenderingHints(hints);
603

    
604
                alto--;
605

    
606
                Color color1 = new Color(255, 255, 178);
607
                Color color2 = new Color(255, 255, 74);
608
                graphics2.setPaint(new GradientPaint(0, 0, color1, 0, alto, color2, false));
609
                graphics2.fillRect(0, 0, width, alto);
610

    
611
                graphics2.setColor(new Color(0, 0, 0));
612

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

    
615
                graphics2.drawString(Messages.getText("teclas") + ":", 10, pos);
616

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

    
633
                graphics2.setColor(new Color(185, 185, 185));
634
                graphics2.drawLine(0, alto, width, alto);
635

    
636
                graphics2.drawImage(getIconClose().getImage(), width - getIconClose().getIconWidth() - 4, 3, null);
637

    
638
                AlphaComposite myAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);
639
                g.setComposite(myAlpha);
640

    
641
                g.drawImage(image2, 0, 0, this);
642

    
643
                myAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
644
                g.setComposite(myAlpha);
645
        }
646
        
647
        private ArrayList<String> splitString4Width(Graphics2D g, String msg, int width) {
648
                String words[] = msg.split(" ");
649

    
650
                ArrayList<String> newString = new ArrayList<String>();
651
                String aux = "";
652
                for (int i = 0; i < words.length; i++) {
653
                        if (aux.length() == 0) {
654
                                aux = words[i];
655
                                continue;
656
                        }
657
                        if (g.getFontMetrics().getStringBounds(aux + " " + words[i], g).getWidth() <= width) {
658
                                aux += " " + words[i];
659
                                continue;
660
                        }
661

    
662
                        newString.add(aux);
663
                        aux = words[i];
664
                }
665
                newString.add(aux);
666

    
667
                return newString;
668
        }
669

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

    
680
                return newString;
681
        }
682
        
683
        private void paintError(Graphics2D g) {
684
                ArrayList<String> errors = splitString4Intro(g, errorDrawingMsg, width - 30);
685

    
686
                int size = errors.size();
687
                if (size < 6)
688
                        size = 6;
689
                
690
                int sep = 13;
691
                int pos = sep + 2;
692

    
693
                int alto = sep * size + 8;
694

    
695
                Image image2 = createImage(width, alto);
696
                Graphics2D graphics2 = (Graphics2D) image2.getGraphics();
697

    
698
                alto--;
699

    
700
                Color color1 = new Color(255, 152, 152);
701
                Color color2 = new Color(255, 100, 100);
702
                graphics2.setPaint(new GradientPaint(0, 0, color1, 0, alto, color2, false));
703
                graphics2.fillRect(0, 0, width, alto);
704

    
705
                graphics2.setColor(new Color(0, 0, 0));
706

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

    
709
                for (int i=0; i<errors.size(); i++) { 
710
                        graphics2.drawString((String) errors.get(i), 24, pos);
711
                        pos+=sep;
712
                }
713
                
714
                graphics2.drawImage(getIconError().getImage(), 4, 4, null);
715

    
716
                graphics2.setColor(new Color(185, 185, 185));
717
                graphics2.drawLine(0, alto, width, alto);
718

    
719
                g.drawImage(image2, 0, 0, this);
720
        }
721

    
722

    
723
        Point mouse = null;
724
        /*
725
         * (non-Javadoc)
726
         * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
727
         */
728
        public void mousePressed(MouseEvent e) {
729
                if (!isInteractiveEnabled())
730
                        return;
731
                requestFocus();
732

    
733
                if ((e.getX() > (width - 20)) && (e.getY() < 20))
734
                        return;
735

    
736
                if ((e.getButton() != MouseEvent.BUTTON1) && (e.getButton() != MouseEvent.BUTTON2))
737
                        return;
738

    
739
                // Oscurece la imagen cuando se mueve
740
                Color gris = new Color(0, 0, 0, 16);
741
                getCacheGraphics().setColor(gris);
742
                getCacheGraphics().fillRect(0, 0, width-1, height-1);
743

    
744
                // Pone un borde a la imagen cuando se mueve
745
                getCacheGraphics().setColor(Color.gray);
746
                getCacheGraphics().drawRect(0, 0, width-1, height-1);
747

    
748
                mouse = new Point(e.getX(), e.getY());
749
                changePos(e.getX(), e.getY());
750
                autoAdjusted = false;
751
        }
752

    
753
        /*
754
         * (non-Javadoc)
755
         * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
756
         */
757
        public void mouseDragged(MouseEvent e) {
758
                if (!isInteractiveEnabled())
759
                        return;
760
                changePos(e.getX(), e.getY());
761
        }
762

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

    
779
        private void changePos(int x, int y) {
780
                if (mouse != null)
781
                        refreshImage((int) (x - mouse.getX()), (int) (y - mouse.getY()));
782
        }
783

    
784
        /**
785
         * Evento de la rueda del rat?n para hacer Zoom In o Zoom Out en la posici?n
786
         * del puntero.
787
         */
788
        public void mouseWheelMoved(MouseWheelEvent e) {
789
                if (!isInteractiveEnabled())
790
                        return;
791

    
792
                if (e.getWheelRotation() > 0) {
793
                        ZoomOut(isXInverted() ? this.getWidth() - e.getX() : e.getX(), isYInverted() ? this.getHeight() - e.getY() : e.getY());
794
                        autoAdjusted = false;
795
                }
796
                if (e.getWheelRotation() < 0) {
797
                        ZoomIn(isXInverted() ? this.getWidth() - e.getX() : e.getX(), isYInverted() ? this.getHeight() - e.getY() : e.getY());
798
                        autoAdjusted = false;
799
                }
800
        }
801

    
802
        /**
803
         * Obtener si el eje de las Y esta invertido
804
         * @return
805
         */
806
        private boolean isYInverted() {
807
                return yInverted;
808
        }
809

    
810
        /**
811
         * Obtener si el eje de las X esta invertido
812
         * @return
813
         */
814
        private boolean isXInverted() {
815
                return xInverted;
816
        }
817

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

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

    
848
        public void keyReleased(KeyEvent e) {}
849
        public void keyTyped(KeyEvent e) {}
850
        public void mouseEntered(MouseEvent e) {}
851
        public void mouseExited(MouseEvent e) {}
852

    
853
        /**
854
         * Define el color de los recuadros del fondo
855
         *
856
         * @param backgroundColor the backgroundColor to set
857
         */
858
        public void setBackgroundColor(Color backgroundColor) {
859
                this.backgroundColor = backgroundColor;
860
        }
861

    
862
        /**
863
         * Devuelve el color de los recuadros del fondo
864
         * @return the backgroundColor
865
         */
866
        public Color getBackgroundColor() {
867
                return backgroundColor;
868
        }
869

    
870
        /**
871
         * Devuelve si se esta mostrando o no la cuadricula de fondo.
872
         * @return the showBackground
873
         */
874
        public boolean isShowBackground() {
875
                return showBackground;
876
        }
877

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

    
899
        /* (non-Javadoc)
900
         * @see javax.swing.JComponent#setEnabled(boolean)
901
         */
902
        public void setEnabled(boolean enabled) {
903
                super.setEnabled(enabled);
904
                updateImageCache(true);
905
                refreshImage(0, 0);
906
        }
907
}