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 | 40561 | jjdelcerro | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | 40435 | jjdelcerro | *
|
4 | 40561 | jjdelcerro | * Copyright (C) 2007-2013 gvSIG Association.
|
5 | 40435 | jjdelcerro | *
|
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 | 40561 | jjdelcerro | * as published by the Free Software Foundation; either version 3
|
9 | 40435 | jjdelcerro | * 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 | 40561 | jjdelcerro | * 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 | 40435 | jjdelcerro | */
|
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 | } |