Statistics
| Revision:

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

History | View | Annotate | Download (13.4 KB)

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

    
26
import java.awt.Color;
27
import java.awt.Dimension;
28
import java.awt.Graphics;
29
import java.awt.Image;
30
import java.awt.Shape;
31
import java.awt.event.MouseEvent;
32
import java.awt.event.MouseListener;
33
import java.awt.event.MouseMotionListener;
34
import java.awt.event.MouseWheelEvent;
35
import java.awt.event.MouseWheelListener;
36
import java.util.ArrayList;
37
import java.util.Iterator;
38

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

    
50
        private ArrayList<DoubleSliderListener> actionCommandListeners = new ArrayList<DoubleSliderListener>();
51

    
52
        private final int LEFT_PAD               = 2;
53
        private final int RIGHT_PAD              = 2;
54

    
55
        private Image     bufferImage            = null;
56
        private int       width                  = 0;
57
        private int       height                 = 0;
58
        private Graphics  bufferGraphics;
59
        private double    x1                     = 0;
60
        private double    x2                     = 100;
61

    
62
        private Color     color1                 = Color.BLACK;
63
        private Color     color2                 = Color.WHITE;
64

    
65
        private double    minimum                = 0;
66
        private double    maximum                = 100;
67

    
68
        private boolean   twoSliders             = true;
69

    
70
        /**
71
         * Crea un DoubleSlider con las opciones por defecto.
72
         */
73
        public DoubleSlider() {
74
                this.setPreferredSize(new Dimension(100, 21));
75
                addMouseMotionListener(this);
76
                addMouseListener(this);
77
                addMouseWheelListener(this);
78
        }
79

    
80
        /**
81
         * Establece el m?ximo valor que puede tomar el componente
82
         * @param value
83
         */
84
        public void setMaximum(int value) {
85
                maximum = value;
86
                validateValues();
87
                refreshImage();
88
        }
89

    
90
        /**
91
         * Establece el m?nimo valor que puede tomar el componente
92
         * @param value
93
         */
94
        public void setMinimum(int value) {
95
                minimum = value;
96
                validateValues();
97
                refreshImage();
98
        }
99

    
100
        /*
101
         * (non-Javadoc)
102
         * @see javax.swing.JComponent#addNotify()
103
         */
104
        public void addNotify() {
105
                super.addNotify();
106

    
107
                refreshImage();
108
        }
109

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

    
123
                if ((width!=width2) || (height!=height2)) {
124
                        bufferImage = createImage(width2, height2);
125
                        if (bufferImage == null) return null;
126
                        bufferGraphics = bufferImage.getGraphics();
127
                }
128

    
129
                width = width2;
130
                height = height2;
131

    
132
                return bufferGraphics;
133
        }
134

    
135
        public Color getColorPosition(int pos) {
136
                int r, g, b, a;
137

    
138
                Color color1 = this.color1;
139
                Color color2 = this.color2;
140
                if (!isEnabled()) {
141
                        r = Color.DARK_GRAY.getRed();
142
                        color1 = new Color(r, r, r);
143
                        r = Color.WHITE.getRed();
144
                        color2 = new Color(r, r, r);
145
                }
146

    
147
                double value = (pixeltovalue(pos) - minimum) / (maximum - minimum);
148
                if (value < 0)
149
                        value = 0;
150
                if (value > 1)
151
                        value = 1;
152

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

    
166
                getBufferGraphics().setColor(this.getBackground());
167
                getBufferGraphics().fillRect(0, 0, width, height);
168

    
169
                int top = (height - 11) / 2;
170
                top -= 6;
171

    
172
                Shape oldClip = getBufferGraphics().getClip();
173
                getBufferGraphics().setClip(LEFT_PAD + 1, top + 1, width - 2 - LEFT_PAD - RIGHT_PAD, 9);
174

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

    
187
                for (int i = LEFT_PAD + 1; i < (width - 1 - RIGHT_PAD); i++) {
188
                        getBufferGraphics().setColor(getColorPosition(i));
189
                        getBufferGraphics().drawLine(i, top, i, top + 10);
190
                }
191
                getBufferGraphics().setClip(oldClip);
192

    
193
                if (!isEnabled())
194
                        getBufferGraphics().setColor(Color.LIGHT_GRAY);
195
                else
196
                        getBufferGraphics().setColor(Color.BLACK);
197
                getBufferGraphics().drawRect(LEFT_PAD, top, width - 1 - LEFT_PAD - RIGHT_PAD, 10);
198

    
199

    
200
                drawTriangle(valuetopixel(x1), top, getColorPosition(valuetopixel(x1)));
201
                if (twoSliders)
202
                        drawTriangle(valuetopixel(x2), top, getColorPosition(valuetopixel(x2)));
203
        }
204

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

    
221
                if (isEnabled()) {
222
                        getBufferGraphics().setColor(Color.BLACK);
223
                } else {
224
                        getBufferGraphics().setColor(Color.GRAY);
225
                }
226
                getBufferGraphics().drawLine(x, y + 10, x-3, y + 17);
227
                getBufferGraphics().drawLine(x, y + 10, x+3, y + 17);
228
                getBufferGraphics().drawLine(x-3, y + 17, x+3, y + 17);
229
        }
230

    
231
        /**
232
         * Redibujar el componente en el graphics temporal y representarlo en el
233
         * componente
234
         */
235
        public void refreshImage() {
236
                redrawBuffer();
237
                if (getGraphics() == null)
238
                        return;
239
                if (bufferImage != null)
240
                        getGraphics().drawImage(bufferImage, 0, 0, this);
241
                super.paint(getGraphics());
242
        }
243

    
244
        /**
245
         * Convierte un valor a la coordenada pixel correspondiente
246
         * @param value
247
         * @return
248
         */
249
        private int valuetopixel(double value) {
250
                return (int) (((value - minimum) * (width - 3.0 - LEFT_PAD - RIGHT_PAD) / (maximum - minimum)) + 1.0 + LEFT_PAD);
251
        }
252

    
253
        /**
254
         * Convierte un pixel al valor que deber?a tener
255
         * @param value
256
         * @return
257
         */
258
        private double pixeltovalue(int value) {
259
                return ((((value - 1 - LEFT_PAD) * (maximum - minimum)) / (width - 3.0 - LEFT_PAD - RIGHT_PAD)) + minimum);
260
        }
261

    
262
        /*
263
         * (non-Javadoc)
264
         * @see javax.swing.JComponent#paint(java.awt.Graphics)
265
         */
266
        public void paint(Graphics g) {
267
                redrawBuffer();
268
                g.drawImage(bufferImage, 0, 0, this);
269
                super.paint(g);
270
        }
271

    
272
        int valuePressed = 0;
273

    
274
        /*
275
         * (non-Javadoc)
276
         * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
277
         */
278
        public void mousePressed(MouseEvent e) {
279
                if (!isEnabled())
280
                        return;
281
                if (e.getButton() != MouseEvent.BUTTON1) return;
282

    
283
                double aux = pixeltovalue(e.getX());
284
                double aux2 = aux - x1;
285
                double aux3 = x2 - aux;
286
                if (aux3 < aux2)
287
                        valuePressed = 2;
288
                else
289
                        valuePressed = 1;
290

    
291
                if (!twoSliders)
292
                        valuePressed = 1;
293

    
294
                changeValue(e.getX());
295
                callValueDraggedListeners();
296
        }
297

    
298
        /*
299
         * (non-Javadoc)
300
         * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
301
         */
302
        public void mouseReleased(MouseEvent e) {
303
                valuePressed = 0;
304
                callValueChangedListeners();
305
        }
306

    
307
        /**
308
         * Establecer los l?mites de los valores en caso de que sean incorrectos
309
         */
310
        private void validateValues() {
311
                if (x1 < minimum) x1 = minimum;
312
                if (x1 > maximum) x1 = maximum;
313
                if (twoSliders) {
314
                        if (x2 < minimum) x2 = minimum;
315
                        if (x2 > maximum) x2 = maximum;
316
                }
317
        }
318

    
319
        /**
320
         * Establecer el valor del extremo izquierdo del slider
321
         * @param value
322
         */
323
        public void setX1(int value) {
324
                setX1((double) value);
325
        }
326

    
327
        /**
328
         * Establecer el valor del extremo izquierdo del slider
329
         * @param value
330
         */
331
        public void setX1(double value) {
332
                x1 = value;
333
                if (twoSliders)
334
                        if (x1 > x2)
335
                                x2 = x1;
336
                validateValues();
337
                refreshImage();
338
        }
339

    
340
        /**
341
         * Es lo mismo que setX1()
342
         * @param value
343
         */
344
        public void setValue(int value) {
345
                setX1(value);
346
        }
347

    
348
        /**
349
         * Establecer el valor del extremo derecho del slider
350
         * @param value
351
         */
352
        public void setX2(int value) {
353
                setX2((double) value);
354
        }
355

    
356
        /**
357
         * Establecer el valor del extremo derecho del slider
358
         * @param value
359
         */
360
        public void setX2(double value) {
361
                x2 = value;
362
                if (x2 < x1) x1 = x2;
363
                validateValues();
364
                refreshImage();
365
        }
366

    
367
        /**
368
         * Obtener el valor del extremo izquierdo del componente
369
         * @return
370
         */
371
        public int getX1() {
372
                return (int) x1;
373
        }
374

    
375
        /**
376
         * Devuelve lo mismo que getX1()
377
         * @return
378
         */
379
        public int getValue() {
380
                return getX1();
381
        }
382

    
383
        /**
384
         * Obtener el valor del extremo derecho del componente
385
         * @return
386
         */
387
        public int getX2() {
388
                return (int) x2;
389
        }
390

    
391
        /**
392
         * M?todo usado por los eventos del rat?n para establecer una nueva posici?n
393
         * del slider
394
         * @param pos
395
         */
396
        private void changeValue(int pos) {
397
                if (!isEnabled())
398
                        return;
399
                if (valuePressed == 0) return;
400

    
401
                double aux = pixeltovalue(pos);
402

    
403
                if (valuePressed == 1) setX1(aux);
404
                if (valuePressed == 2) setX2(aux);
405
        }
406

    
407
        /*
408
         * (non-Javadoc)
409
         * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
410
         */
411
        public void mouseDragged(MouseEvent arg0) {
412
                if (!isEnabled())
413
                        return;
414
                changeValue(arg0.getX());
415
                callValueDraggedListeners();
416
        }
417

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

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

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

    
439
        /*
440
         * (non-Javadoc)
441
         * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
442
         */
443
        public void mouseExited(MouseEvent e) {
444
        }
445

    
446
        /**
447
         * A?adir un listener a la lista de eventos
448
         * @param listener
449
         */
450
        public void addValueChangedListener(DoubleSliderListener listener) {
451
                if (!actionCommandListeners.contains(listener))
452
                        actionCommandListeners.add(listener);
453
        }
454

    
455
        /**
456
         * Borrar un listener de la lista de eventos
457
         * @param listener
458
         */
459
        public void removeValueChangedListener(DoubleSliderListener listener) {
460
                actionCommandListeners.remove(listener);
461
        }
462

    
463
        /**
464
         * Invocar a los eventos asociados al componente
465
         */
466
        private void callValueChangedListeners() {
467
                Iterator<DoubleSliderListener> iterator = actionCommandListeners.iterator();
468
                while (iterator.hasNext()) {
469
                        DoubleSliderListener listener = iterator.next();
470
                        listener.actionValueChanged(new DoubleSliderEvent(this));
471
                }
472
        }
473

    
474
        /**
475
         * Invocar a los eventos asociados al componente
476
         */
477
        private void callValueDraggedListeners() {
478
                Iterator<DoubleSliderListener> iterator = actionCommandListeners.iterator();
479
                while (iterator.hasNext()) {
480
                        DoubleSliderListener listener = iterator.next();
481
                        listener.actionValueDragged(new DoubleSliderEvent(this));
482
                }
483
        }
484

    
485
        /**
486
         * @return the twoSliders
487
         */
488
        public boolean isTwoSliders() {
489
                return twoSliders;
490
        }
491

    
492
        /**
493
         * @param twoSliders the twoSliders to set
494
         */
495
        public void setTwoSliders(boolean twoSliders) {
496
                this.twoSliders = twoSliders;
497
                refreshImage();
498
        }
499

    
500
        /**
501
         * @param color1 the color1 to set
502
         */
503
        public void setColor1(Color color1, boolean refresh) {
504
                this.color1 = color1;
505
                if (refresh)
506
                        refreshImage();
507
        }
508

    
509
        /**
510
         * @param color2 the color2 to set
511
         */
512
        public void setColor2(Color color2, boolean refresh) {
513
                this.color2 = color2;
514
                if (refresh)
515
                        refreshImage();
516
        }
517

    
518
        /* (non-Javadoc)
519
         * @see javax.swing.JComponent#setEnabled(boolean)
520
         */
521
        public void setEnabled(boolean enabled) {
522
                super.setEnabled(enabled);
523
                refreshImage();
524
        }
525

    
526
        public void mouseWheelMoved(MouseWheelEvent e) {
527
                if (!isEnabled())
528
                        return;
529

    
530
                double aux = pixeltovalue(e.getX());
531
                double aux2 = aux - x1;
532
                double aux3 = x2 - aux;
533
                if (aux3 < aux2)
534
                        valuePressed = 2;
535
                else
536
                        valuePressed = 1;
537

    
538
                if (!twoSliders)
539
                        valuePressed = 1;
540

    
541
                if (valuePressed == 1)
542
                        setX1(getX1() - e.getWheelRotation());
543
                else
544
                        setX2(getX2() - e.getWheelRotation());
545
                valuePressed = 0;
546

    
547
                callValueChangedListeners();
548
        }
549
}