Statistics
| Revision:

root / trunk / libraries / libUIComponent / src / org / gvsig / gui / beans / doubleslider / DoubleSlider.java @ 12939

History | View | Annotate | Download (13.2 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.doubleslider;
20

    
21
import java.awt.Color;
22
import java.awt.Dimension;
23
import java.awt.Graphics;
24
import java.awt.Image;
25
import java.awt.Shape;
26
import java.awt.event.MouseEvent;
27
import java.awt.event.MouseListener;
28
import java.awt.event.MouseMotionListener;
29
import java.awt.event.MouseWheelEvent;
30
import java.awt.event.MouseWheelListener;
31
import java.util.ArrayList;
32
import java.util.Iterator;
33

    
34
import javax.swing.JComponent;
35
/**
36
 * <code>DoubleSlider</code> representa un componente que tiene dos
37
 * deslizadores. Se puede definir un m?ximo y un m?nimo.
38
 *
39
 * @version 04/05/2007
40
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
41
 */
42
public class DoubleSlider extends JComponent implements MouseMotionListener, MouseListener, MouseWheelListener {
43
        private static final long serialVersionUID = 663355422780987493L;
44

    
45
        private ArrayList actionCommandListeners = new ArrayList();
46

    
47
        private final int LEFT_PAD               = 2;
48
        private final int RIGHT_PAD              = 2;
49

    
50
        private Image     bufferImage            = null;
51
        private int       width                  = 0;
52
        private int       height                 = 0;
53
        private Graphics  bufferGraphics;
54
        private double    x1                     = 0;
55
        private double    x2                     = 100;
56

    
57
        private Color     color1                 = Color.BLACK;
58
        private Color     color2                 = Color.WHITE;
59

    
60
        private double    minimum                = 0;
61
        private double    maximum                = 100;
62

    
63
        private boolean   twoSliders             = true;
64

    
65
        /**
66
         * Crea un DoubleSlider con las opciones por defecto.
67
         */
68
        public DoubleSlider() {
69
                this.setPreferredSize(new Dimension(100, 21));
70
                addMouseMotionListener(this);
71
                addMouseListener(this);
72
                addMouseWheelListener(this);
73
        }
74

    
75
        /**
76
         * Establece el m?ximo valor que puede tomar el componente
77
         * @param value
78
         */
79
        public void setMaximum(int value) {
80
                maximum = value;
81
                validateValues();
82
                refreshImage();
83
        }
84

    
85
        /**
86
         * Establece el m?nimo valor que puede tomar el componente
87
         * @param value
88
         */
89
        public void setMinimum(int value) {
90
                minimum = value;
91
                validateValues();
92
                refreshImage();
93
        }
94

    
95
        /*
96
         * (non-Javadoc)
97
         * @see javax.swing.JComponent#addNotify()
98
         */
99
        public void addNotify() {
100
                super.addNotify();
101

    
102
                refreshImage();
103
        }
104

    
105
        /**
106
         * Crea un graphics con las dimensiones del componente si no estaba creado y
107
         * lo devuelve para poder usarlo para dibujar en ?l.
108
         * @return Graphics
109
         */
110
        private Graphics getBufferGraphics() {
111
                int width2 = getBounds().width;
112
                int height2 = getBounds().height;
113
                if (width2 <= 0)
114
                        width2 = 1;
115
                if (height2 <= 0)
116
                        height2 = 1;
117

    
118
                if ((width!=width2) || (height!=height2)) {
119
                        bufferImage = createImage(width2, height2);
120
                        if (bufferImage == null) return null;
121
                        bufferGraphics = bufferImage.getGraphics();
122
                }
123

    
124
                width = width2;
125
                height = height2;
126

    
127
                return bufferGraphics;
128
        }
129

    
130
        public Color getColorPosition(int pos) {
131
                int r, g, b, a;
132

    
133
                Color color1 = this.color1;
134
                Color color2 = this.color2;
135
                if (!isEnabled()) {
136
                        r = Color.DARK_GRAY.getRed();
137
                        color1 = new Color(r, r, r);
138
                        r = Color.WHITE.getRed();
139
                        color2 = new Color(r, r, r);
140
                }
141

    
142
                double value = (pixeltovalue(pos) - minimum) / (maximum - minimum);
143
                if (value < 0)
144
                        value = 0;
145
                if (value > 1)
146
                        value = 1;
147

    
148
                r = (int) (color1.getRed() + ((color2.getRed() - color1.getRed()) * value));
149
                g = (int) (color1.getGreen() + ((color2.getGreen() - color1.getGreen()) * value));
150
                b = (int) (color1.getBlue() + ((color2.getBlue() - color1.getBlue()) * value));
151
                a = (int) (color1.getAlpha() + ((color2.getAlpha() - color1.getAlpha()) * value));
152
                return new Color(r, g, b, a);
153
        }
154
        /**
155
         * Redibujar el componente en el graphics temporal
156
         */
157
        public void redrawBuffer() {
158
                if (getBufferGraphics() == null)
159
                        return;
160

    
161
                getBufferGraphics().setColor(this.getBackground());
162
                getBufferGraphics().fillRect(0, 0, width, height);
163

    
164
                int top = (height - 11) / 2;
165
                top -= 6;
166

    
167
                Shape oldClip = getBufferGraphics().getClip();
168
                getBufferGraphics().setClip(LEFT_PAD + 1, top + 1, width - 2 - LEFT_PAD - RIGHT_PAD, 9);
169

    
170
                if ((color1.getAlpha() != 255) || (color2.getAlpha() != 255)) {
171
                        for (int i = 0; (i * 4) <= (width - 1 - RIGHT_PAD); i++) {
172
                                for (int j = 0; (j * 4) <= (top + 6); j++) {
173
                                        if ((i + j) % 2 == 0)
174
                                                getBufferGraphics().setColor(Color.white);
175
                                        else
176
                                                getBufferGraphics().setColor(new Color(204, 204, 204));
177
                                        getBufferGraphics().fillRect(LEFT_PAD + 1 + i * 4, top + 1 + j * 4, 4, 4);
178
                                }
179
                        }
180
                }
181

    
182
                for (int i = LEFT_PAD + 1; i < (width - 1 - RIGHT_PAD); i++) {
183
                        getBufferGraphics().setColor(getColorPosition(i));
184
                        getBufferGraphics().drawLine(i, top, i, top + 10);
185
                }
186
                getBufferGraphics().setClip(oldClip);
187

    
188
                if (!isEnabled())
189
                        getBufferGraphics().setColor(Color.LIGHT_GRAY);
190
                else
191
                        getBufferGraphics().setColor(Color.BLACK);
192
                getBufferGraphics().drawRect(LEFT_PAD, top, width - 1 - LEFT_PAD - RIGHT_PAD, 10);
193

    
194

    
195
                drawTriangle(valuetopixel(x1), top, getColorPosition(valuetopixel(x1)));
196
                if (twoSliders)
197
                        drawTriangle(valuetopixel(x2), top, getColorPosition(valuetopixel(x2)));
198
        }
199

    
200
        /**
201
         * Dibujar un triangulo, un triangulo es un deslizador del componente. Puedes
202
         * indicarle que color tendra y en que posici?n estar?.
203
         * @param x
204
         * @param color
205
         */
206
        private void drawTriangle(int x, int y, Color color) {
207
                if (isEnabled()) {
208
                        getBufferGraphics().setColor(color);
209
                        getBufferGraphics().drawLine(x, y + 12, x, y + 16);
210
                        getBufferGraphics().drawLine(x-1, y + 14, x-1, y + 16);
211
                        getBufferGraphics().drawLine(x+1, y + 14, x+1, y + 16);
212
                        getBufferGraphics().drawLine(x-2, y + 16, x-2, y + 16);
213
                        getBufferGraphics().drawLine(x+2, y + 16, x+2, y + 16);
214
                }
215

    
216
                if (isEnabled()) {
217
                        getBufferGraphics().setColor(Color.BLACK);
218
                } else {
219
                        getBufferGraphics().setColor(Color.GRAY);
220
                }
221
                getBufferGraphics().drawLine(x, y + 10, x-3, y + 17);
222
                getBufferGraphics().drawLine(x, y + 10, x+3, y + 17);
223
                getBufferGraphics().drawLine(x-3, y + 17, x+3, y + 17);
224
        }
225

    
226
        /**
227
         * Redibujar el componente en el graphics temporal y representarlo en el
228
         * componente
229
         */
230
        public void refreshImage() {
231
                redrawBuffer();
232
                if (bufferImage != null)
233
                        getGraphics().drawImage(bufferImage, 0, 0, this);
234
                super.paint(getGraphics());
235
        }
236

    
237
        /**
238
         * Convierte un valor a la coordenada pixel correspondiente
239
         * @param value
240
         * @return
241
         */
242
        private int valuetopixel(double value) {
243
                return (int) (((value - minimum) * (width - 3.0 - LEFT_PAD - RIGHT_PAD) / (maximum - minimum)) + 1.0 + LEFT_PAD);
244
        }
245

    
246
        /**
247
         * Convierte un pixel al valor que deber?a tener
248
         * @param value
249
         * @return
250
         */
251
        private double pixeltovalue(int value) {
252
                return ((((value - 1 - LEFT_PAD) * (maximum - minimum)) / (width - 3.0 - LEFT_PAD - RIGHT_PAD)) + minimum);
253
        }
254

    
255
        /*
256
         * (non-Javadoc)
257
         * @see javax.swing.JComponent#paint(java.awt.Graphics)
258
         */
259
        public void paint(Graphics g) {
260
                redrawBuffer();
261
                g.drawImage(bufferImage, 0, 0, this);
262
                super.paint(g);
263
        }
264

    
265
        int valuePressed = 0;
266

    
267
        /*
268
         * (non-Javadoc)
269
         * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
270
         */
271
        public void mousePressed(MouseEvent e) {
272
                if (!isEnabled())
273
                        return;
274
                if (e.getButton() != MouseEvent.BUTTON1) return;
275

    
276
                double aux = pixeltovalue(e.getX());
277
                double aux2 = aux - x1;
278
                double aux3 = x2 - aux;
279
                if (aux3 < aux2)
280
                        valuePressed = 2;
281
                else
282
                        valuePressed = 1;
283

    
284
                if (!twoSliders)
285
                        valuePressed = 1;
286

    
287
                changeValue(e.getX());
288
                callValueDraggedListeners();
289
        }
290

    
291
        /*
292
         * (non-Javadoc)
293
         * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
294
         */
295
        public void mouseReleased(MouseEvent e) {
296
                valuePressed = 0;
297
                callValueChangedListeners();
298
        }
299

    
300
        /**
301
         * Establecer los l?mites de los valores en caso de que sean incorrectos
302
         */
303
        private void validateValues() {
304
                if (x1 < minimum) x1 = minimum;
305
                if (x1 > maximum) x1 = maximum;
306
                if (twoSliders) {
307
                        if (x2 < minimum) x2 = minimum;
308
                        if (x2 > maximum) x2 = maximum;
309
                }
310
        }
311

    
312
        /**
313
         * Establecer el valor del extremo izquierdo del slider
314
         * @param value
315
         */
316
        public void setX1(int value) {
317
                setX1((double) value);
318
        }
319

    
320
        /**
321
         * Establecer el valor del extremo izquierdo del slider
322
         * @param value
323
         */
324
        public void setX1(double value) {
325
                x1 = value;
326
                if (twoSliders)
327
                        if (x1 > x2)
328
                                x2 = x1;
329
                validateValues();
330
                refreshImage();
331
        }
332

    
333
        /**
334
         * Es lo mismo que setX1()
335
         * @param value
336
         */
337
        public void setValue(int value) {
338
                setX1(value);
339
        }
340

    
341
        /**
342
         * Establecer el valor del extremo derecho del slider
343
         * @param value
344
         */
345
        public void setX2(int value) {
346
                setX2((double) value);
347
        }
348

    
349
        /**
350
         * Establecer el valor del extremo derecho del slider
351
         * @param value
352
         */
353
        public void setX2(double value) {
354
                x2 = value;
355
                if (x2 < x1) x1 = x2;
356
                validateValues();
357
                refreshImage();
358
        }
359

    
360
        /**
361
         * Obtener el valor del extremo izquierdo del componente
362
         * @return
363
         */
364
        public int getX1() {
365
                return (int) x1;
366
        }
367

    
368
        /**
369
         * Devuelve lo mismo que getX1()
370
         * @return
371
         */
372
        public int getValue() {
373
                return getX1();
374
        }
375

    
376
        /**
377
         * Obtener el valor del extremo derecho del componente
378
         * @return
379
         */
380
        public int getX2() {
381
                return (int) x2;
382
        }
383

    
384
        /**
385
         * M?todo usado por los eventos del rat?n para establecer una nueva posici?n
386
         * del slider
387
         * @param pos
388
         */
389
        private void changeValue(int pos) {
390
                if (!isEnabled())
391
                        return;
392
                if (valuePressed == 0) return;
393

    
394
                double aux = pixeltovalue(pos);
395

    
396
                if (valuePressed == 1) setX1(aux);
397
                if (valuePressed == 2) setX2(aux);
398
        }
399

    
400
        /*
401
         * (non-Javadoc)
402
         * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
403
         */
404
        public void mouseDragged(MouseEvent arg0) {
405
                if (!isEnabled())
406
                        return;
407
                changeValue(arg0.getX());
408
                callValueDraggedListeners();
409
        }
410

    
411
        /*
412
         * (non-Javadoc)
413
         * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
414
         */
415
        public void mouseMoved(MouseEvent e) {
416
        }
417

    
418
        /*
419
         * (non-Javadoc)
420
         * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
421
         */
422
        public void mouseClicked(MouseEvent e) {
423
        }
424

    
425
        /*
426
         * (non-Javadoc)
427
         * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
428
         */
429
        public void mouseEntered(MouseEvent e) {
430
        }
431

    
432
        /*
433
         * (non-Javadoc)
434
         * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
435
         */
436
        public void mouseExited(MouseEvent e) {
437
        }
438

    
439
        /**
440
         * A?adir un listener a la lista de eventos
441
         * @param listener
442
         */
443
        public void addValueChangedListener(DoubleSliderListener listener) {
444
                if (!actionCommandListeners.contains(listener))
445
                        actionCommandListeners.add(listener);
446
        }
447

    
448
        /**
449
         * Borrar un listener de la lista de eventos
450
         * @param listener
451
         */
452
        public void removeValueChangedListener(DoubleSliderListener listener) {
453
                actionCommandListeners.remove(listener);
454
        }
455

    
456
        /**
457
         * Invocar a los eventos asociados al componente
458
         */
459
        private void callValueChangedListeners() {
460
                Iterator acIterator = actionCommandListeners.iterator();
461
                while (acIterator.hasNext()) {
462
                        DoubleSliderListener listener = (DoubleSliderListener) acIterator.next();
463
                        listener.actionValueChanged(new DoubleSliderEvent(this));
464
                }
465
        }
466

    
467
        /**
468
         * Invocar a los eventos asociados al componente
469
         */
470
        private void callValueDraggedListeners() {
471
                Iterator acIterator = actionCommandListeners.iterator();
472
                while (acIterator.hasNext()) {
473
                        DoubleSliderListener listener = (DoubleSliderListener) acIterator.next();
474
                        listener.actionValueDragged(new DoubleSliderEvent(this));
475
                }
476
        }
477

    
478
        /**
479
         * @return the twoSliders
480
         */
481
        public boolean isTwoSliders() {
482
                return twoSliders;
483
        }
484

    
485
        /**
486
         * @param twoSliders the twoSliders to set
487
         */
488
        public void setTwoSliders(boolean twoSliders) {
489
                this.twoSliders = twoSliders;
490
                refreshImage();
491
        }
492

    
493
        /**
494
         * @param color1 the color1 to set
495
         */
496
        public void setColor1(Color color1, boolean refresh) {
497
                this.color1 = color1;
498
                if (refresh)
499
                        refreshImage();
500
        }
501

    
502
        /**
503
         * @param color2 the color2 to set
504
         */
505
        public void setColor2(Color color2, boolean refresh) {
506
                this.color2 = color2;
507
                if (refresh)
508
                        refreshImage();
509
        }
510

    
511
        /* (non-Javadoc)
512
         * @see javax.swing.JComponent#setEnabled(boolean)
513
         */
514
        public void setEnabled(boolean enabled) {
515
                super.setEnabled(enabled);
516
                refreshImage();
517
        }
518

    
519
        public void mouseWheelMoved(MouseWheelEvent e) {
520
                if (!isEnabled())
521
                        return;
522

    
523
                double aux = pixeltovalue(e.getX());
524
                double aux2 = aux - x1;
525
                double aux3 = x2 - aux;
526
                if (aux3 < aux2)
527
                        valuePressed = 2;
528
                else
529
                        valuePressed = 1;
530

    
531
                if (!twoSliders)
532
                        valuePressed = 1;
533

    
534
                if (valuePressed == 1)
535
                        setX1(getX1() - e.getWheelRotation());
536
                else
537
                        setX2(getX2() - e.getWheelRotation());
538
                valuePressed = 0;
539

    
540
                callValueChangedListeners();
541
        }
542
}