Statistics
| Revision:

root / trunk / libraries / libUIComponent / src / org / gvsig / gui / beans / colorslideredition / ColorSliderEdition.java @ 12898

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

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

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

    
44
        private final int LEFT_PAD     = 3;
45
        private final int RIGHT_PAD    = 3;
46

    
47
        private Image     bufferImage  = null;
48
        private int       width        = 0;
49
        private int       height       = 0;
50
        private Graphics  bufferGraphics;
51
        private ArrayList items        = new ArrayList();
52
        private boolean   interpolated = false;
53

    
54
        /**
55
         * Crea un DoubleSlider con las opciones por defecto.
56
         */
57
        public ColorSliderEdition() {
58
                this.setPreferredSize(new Dimension(100, 21));
59
//                items.add(new ItemColorSlider(0, Color.black));
60
//                items.add(new ItemColorSlider(100, new Color(0, 0, 0, 0)));
61
                items.add(new ItemColorSlider(0, Color.black));
62
                items.add(new ItemColorSlider(25, Color.red));
63
                items.add(new ItemColorSlider(50, Color.green));
64
                items.add(new ItemColorSlider(75, Color.blue));
65
                items.add(new ItemColorSlider(100, Color.white));
66
                addMouseListener(this);
67
                addMouseMotionListener(this);
68
        }
69

    
70
        /*
71
         * (non-Javadoc)
72
         * @see javax.swing.JComponent#addNotify()
73
         */
74
        public void addNotify() {
75
                super.addNotify();
76

    
77
                refreshImage();
78
        }
79

    
80

    
81
        /**
82
         * Devuelve un color de interpolacion entre dos colores
83
         * @param value
84
         * @param pos
85
         * @return
86
         */
87
        private Color interpolatedColor(ArrayList newItems, double value, int pos) {
88
                if (newItems.size() <= 0)
89
                        return Color.black;
90

    
91
                if ((pos + 1) == newItems.size())
92
                        return ((ItemColorSlider) newItems.get(pos)).getColor();
93

    
94
                if (value <= ((ItemColorSlider) newItems.get(0)).getValue())
95
                        return ((ItemColorSlider) newItems.get(0)).getColor();
96

    
97
                ItemColorSlider item1 = (ItemColorSlider) newItems.get(pos);
98
                ItemColorSlider item2 = (ItemColorSlider) newItems.get(pos + 1);
99

    
100
                double percValue = ((value - item1.getValue()) * 100) / (item2.getValue() - item1.getValue());
101

    
102
                Color halfColor = new Color(
103
                                (item2.getColor().getRed() + item1.getColor().getRed()) >> 1,
104
                                (item2.getColor().getGreen() + item1.getColor().getGreen()) >> 1,
105
                                (item2.getColor().getBlue() + item1.getColor().getBlue()) >> 1,
106
                                (item2.getColor().getAlpha() + item1.getColor().getAlpha()) >> 1);
107

    
108
                Color color1, color2;
109
                double perc1, perc2;
110

    
111
                if (percValue > item2.getInterpolated()) {
112
                        color1 = halfColor;
113
                        color2 = item2.getColor();
114
                        perc1 = item2.getInterpolated();
115
                        perc2 = 100;
116
                } else {
117
                        color1 = item1.getColor();
118
                        color2 = halfColor;
119
                        perc1 = 0;
120
                        perc2 = item2.getInterpolated();
121
                }
122

    
123
                double percNew = (percValue - perc1) / (perc2 - perc1);
124

    
125
                Color newColor = new Color(
126
                                (int) (color1.getRed() + ((color2.getRed() - color1.getRed()) * percNew)) & 0xff,
127
                                (int) (color1.getGreen() + ((color2.getGreen() - color1.getGreen()) * percNew)) & 0xff,
128
                                (int) (color1.getBlue() + ((color2.getBlue() - color1.getBlue()) * percNew)) & 0xff,
129
                                (int) (color1.getAlpha() + ((color2.getAlpha() - color1.getAlpha()) * percNew)) & 0xff);
130

    
131

    
132
                return newColor;
133
        }
134

    
135
        /**
136
         * Crea un graphics con las dimensiones del componente si no estaba creado y
137
         * lo devuelve para poder usarlo para dibujar en ?l.
138
         * @return Graphics
139
         */
140
        private Graphics getBufferGraphics() {
141
                int width2 = getBounds().width;
142
                int height2 = getBounds().height;
143
                if (width2 <= 0)
144
                        width2 = 1;
145
                if (height2 <= 0)
146
                        height2 = 1;
147

    
148
                if ((width!=width2) || (height!=height2)) {
149
                        bufferImage = createImage(width2, height2);
150
                        if (bufferImage == null) return null;
151
                        bufferGraphics = bufferImage.getGraphics();
152
                }
153

    
154
                width = width2;
155
                height = height2;
156

    
157
                return bufferGraphics;
158
        }
159

    
160
        private void sortItems() {
161
                for (int i = 0; i < items.size(); i++) {
162
                        for (int j = i + 1; j < items.size(); j++) {
163
                                if (((ItemColorSlider) items.get(j)).getValue() < ((ItemColorSlider) items.get(i)).getValue()) {
164
                                        Object aux = items.get(i);
165
                                        items.set(i, items.get(j));
166
                                        items.set(j, aux);
167
                                }
168
                        }
169
                }
170
        }
171

    
172
        private int getPosForValue(double value, ArrayList newArray) {
173
                int pos = 0;
174
                for (int j = 1; j <= newArray.size(); j++) {
175
                        if (j < newArray.size()) {
176
                                if (value < ((ItemColorSlider) newArray.get(j)).getValue()) {
177
                                        pos = j - 1;
178
                                        break;
179
                                }
180
                        } else {
181
                                pos = j - 1;
182
                                break;
183
                        }
184
                }
185
                return pos;
186
        }
187

    
188
        /**
189
         * Redibujar el componente en el graphics temporal
190
         */
191
        private void redrawBuffer() {
192
                if (getBufferGraphics() == null) return;
193

    
194
                sortItems();
195

    
196
                getBufferGraphics().setColor(this.getBackground());
197

    
198
                getBufferGraphics().fillRect(0,0,width,height);
199

    
200
                getBufferGraphics().setColor(Color.black);
201
                getBufferGraphics().drawRect(LEFT_PAD, 0, width - 1 - LEFT_PAD - RIGHT_PAD, height - 18);
202

    
203
                Shape oldClip = getBufferGraphics().getClip();
204
                getBufferGraphics().setClip(LEFT_PAD + 2, 2, width - 4 - LEFT_PAD - RIGHT_PAD, height - 21);
205
                for (int i = 0; (i * 4 + 2) <= (width - 3 - LEFT_PAD - RIGHT_PAD); i++) {
206
                        for (int j = 0; (j * 4 + 2) <= (height - 20); j++) {
207
                                if ((i + j) % 2 == 0)
208
                                        getBufferGraphics().setColor(Color.white);
209
                                else
210
                                        getBufferGraphics().setColor(new Color(204, 204, 204));
211
                                getBufferGraphics().fillRect(i * 4 + 2 + LEFT_PAD, j * 4 + 2, 4, 4);
212
                        }
213
                }
214

    
215
                ArrayList newArray = (ArrayList) items.clone();
216
                for (int i = newArray.size() - 1; i>=0; i--) {
217
                        if (((ItemColorSlider) newArray.get(i)).isVisible() == false)
218
                                newArray.remove(i);
219
                }
220
                for (int i = LEFT_PAD + 2; i <= width - 2 - RIGHT_PAD; i++) {
221

    
222
                        int pos = getPosForValue(pixelToValue(i), newArray);
223

    
224
                        if (isInterpolated()) {
225
                                getBufferGraphics().setColor(interpolatedColor(newArray, pixelToValue(i), pos));
226
                        } else {
227
                                if ((pos + 1) < newArray.size()) {
228
                                        double min = ((ItemColorSlider) newArray.get(pos)).getValue();
229
                                        double max = ((ItemColorSlider) newArray.get(pos + 1)).getValue();
230
                                        if ((min + ((max - min) * ((ItemColorSlider) newArray.get(pos + 1)).getInterpolated() / 100)) < pixelToValue(i))
231
                                                pos++;
232
                                }
233
                                getBufferGraphics().setColor(((ItemColorSlider) newArray.get(pos)).getColor());
234
                        }
235
                        getBufferGraphics().drawLine(i, 2, i, height - 18);
236
                }
237

    
238
                getBufferGraphics().setClip(oldClip);
239

    
240
                boolean paintNext = false;
241
                for (int i = 0; i < items.size(); i++) {
242
                        ItemColorSlider aux = (ItemColorSlider) items.get(i);
243
                        if (!aux.isVisible())
244
                                continue;
245
                        // Dibujar los deslizadores de la interpolacion
246
                        if (aux.getSelected() != -1)
247
                                paintNext = true;
248
                        if (paintNext) {
249
                                if (i != 0) {
250
                                        double value = ((ItemColorSlider) items.get(i - 1)).getValue() + ((((ItemColorSlider) items.get(i)).getValue() - ((ItemColorSlider) items.get(i - 1)).getValue()) * ((ItemColorSlider) items.get(i)).getInterpolated() / 100);
251

    
252
                                        drawSliderInterpolation(valueToPixel(value), height - 17, aux.getColor(), (aux.getSelected() == 2));
253
                                }
254
                                paintNext = false;
255
                        }
256
                        if (aux.getSelected() == 1)
257
                                paintNext = true;
258
                }
259

    
260
                for (int i = items.size() - 1; i >=0; i--) {
261
                        ItemColorSlider aux = (ItemColorSlider) items.get(i);
262
                        if (!aux.isVisible())
263
                                continue;
264
                        drawSliderColor(valueToPixel(aux.getValue()), height - 17, aux.getColor(), (aux.getSelected() == 1));
265
                }
266
        }
267

    
268
        /**
269
         * Convierte un porcentaje al valor pixel en X
270
         * @param value
271
         * @return
272
         */
273
        private int valueToPixel(double value) {
274
                if (value < 0)
275
                        value = 0;
276
                if (value > 100)
277
                        value = 100;
278
                return (int) (((width - 5 - LEFT_PAD - RIGHT_PAD) * value) / 100) + 2 + LEFT_PAD;
279
        }
280

    
281
        /**
282
         * Convierte un valor en X en porcentaje
283
         * @param value
284
         * @return
285
         */
286
        private double pixelToValue(int value) {
287
                double aux = value - LEFT_PAD - 1;
288
                return (aux * 100.0f) / (width - LEFT_PAD - RIGHT_PAD - 4.0f);
289
        }
290

    
291
        /**
292
         * Dibujar un triangulo, un triangulo es un deslizador del componente. Puedes
293
         * indicarle que color tendra y en que posici?n estar?.
294
         * @param x
295
         * @param color
296
         */
297
        private void drawSliderColor(int x, int y, Color color, boolean isSelected) {
298
                Polygon p = new Polygon();
299
                p.addPoint(x, y);
300
                p.addPoint(x - 5, y + 6);
301
                p.addPoint(x - 5, y + 16);
302
                p.addPoint(x + 5, y + 16);
303
                p.addPoint(x + 5, y + 6);
304
                if (!isSelected) {
305
                        getBufferGraphics().setColor(this.getBackground());
306
                        getBufferGraphics().fillPolygon(p);
307
                        getBufferGraphics().setColor(new Color(172, 168, 153));
308
                        getBufferGraphics().drawLine(x + 1, y + 2, x + 4, y + 6);
309
                        getBufferGraphics().drawLine(x - 4, y + 6, x + 4, y + 6);
310
                }
311
                else {
312
                        getBufferGraphics().setColor(Color.black);
313
                        getBufferGraphics().fillPolygon(p);
314
                }
315

    
316
                getBufferGraphics().setColor(Color.black);
317
                getBufferGraphics().drawPolygon(p);
318

    
319
                getBufferGraphics().setColor(new Color(172, 168, 153));
320
                getBufferGraphics().drawLine(x - 3, y + 15, x + 4, y + 15);
321
                getBufferGraphics().drawLine(x + 4, y + 8, x + 4, y + 15);
322

    
323
                getBufferGraphics().setColor(Color.white);
324
                getBufferGraphics().drawLine(x - 4, y + 7, x - 4, y + 15);
325
                getBufferGraphics().drawLine(x - 4, y + 7, x + 4, y + 7);
326

    
327
                getBufferGraphics().setColor(new Color(color.getRed(), color.getGreen(), color.getBlue()));
328
                getBufferGraphics().fillRect(x - 3, y + 8, 7, 7);
329
        }
330

    
331
        /**
332
         * Dibujar un triangulo, un triangulo es un deslizador del componente. Puedes
333
         * indicarle que color tendra y en que posici?n estar?.
334
         * @param x
335
         * @param color
336
         */
337
        private void drawSliderInterpolation(int x, int y, Color color, boolean isSelected) {
338
                Polygon p = new Polygon();
339
                p.addPoint(x, y);
340
                p.addPoint(x - 3, y + 3);
341
                p.addPoint(x, y + 6);
342
                p.addPoint(x + 3, y + 3);
343
                if (isSelected)
344
                        getBufferGraphics().setColor(new Color(color.getRed(), color.getGreen(), color.getBlue()));
345
                else
346
                        getBufferGraphics().setColor(this.getBackground());
347

    
348
                getBufferGraphics().fillPolygon(p);
349

    
350
                getBufferGraphics().setColor(Color.black);
351
                getBufferGraphics().drawPolygon(p);
352
        }
353

    
354
        /**
355
         * Redibujar el componente en el graphics temporal y representarlo en el
356
         * componente
357
         */
358
        private void refreshImage() {
359
                redrawBuffer();
360
                if (bufferImage != null)
361
                        getGraphics().drawImage(bufferImage, 0, 0, this);
362
                super.paint(getGraphics());
363
        }
364

    
365
        /*
366
         * (non-Javadoc)
367
         * @see javax.swing.JComponent#paint(java.awt.Graphics)
368
         */
369
        public void paint(Graphics g) {
370
                redrawBuffer();
371
                g.drawImage(bufferImage, 0, 0, this);
372
                super.paint(g);
373
        }
374

    
375
        /*
376
         * (non-Javadoc)
377
         * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
378
         */
379
        public void mousePressed(MouseEvent e) {
380
                int onmask = MouseEvent.BUTTON1_DOWN_MASK;
381
                if ((e.getModifiersEx() & onmask) != onmask)
382
                        return;
383
                onmask = MouseEvent.ALT_DOWN_MASK;
384
                boolean newItem = false;
385
                if ((e.getModifiersEx() & onmask) == onmask)
386
                        newItem = true;
387

    
388
                if ((e.getY() > height) || (e.getY() < (height - 18))) {
389
                        clearSelected();
390
                        refreshImage();
391
                        return;
392
                }
393

    
394
                int type = 1;
395
                ItemColorSlider itemSelected = getItem(e.getX(), e.getY());
396
                if ((itemSelected == null) || (newItem)) {
397
                        itemSelected = getItemInterpolated(e.getX(), e.getY());
398
                        if ((itemSelected == null) || (newItem)) {
399
                                int pos = getPosForValue(pixelToValue(e.getX()), items);
400

    
401
                                Color newColor = interpolatedColor(items, pixelToValue(e.getX()), pos);
402

    
403
                                itemSelected = new ItemColorSlider(pixelToValue(e.getX()), newColor);
404
                                items.add(itemSelected);
405
                        } else {
406
                                type = 2;
407
                        }
408
                }
409
                setItemSelected(itemSelected, type);
410

    
411
                refreshImage();
412
        }
413

    
414
        private void clearSelected() {
415
                for (int i = items.size() - 1; i >= 0; i--)
416
                        ((ItemColorSlider) items.get(i)).setSelected(-1);
417
        }
418

    
419
        private void setItemSelected(ItemColorSlider aux, int type) {
420
                clearSelected();
421
                aux.setSelected(type);
422
        }
423

    
424
        /*
425
         * (non-Javadoc)
426
         * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
427
         */
428
        public void mouseReleased(MouseEvent e) {
429
                for (int i = items.size() - 1; i >= 0; i--) {
430
                        if (items.size() <= 2)
431
                                return;
432
                        if (((ItemColorSlider) items.get(i)).isVisible() == false)
433
                                items.remove(i);
434
                }
435
        }
436

    
437
        public ItemColorSlider getSelectedItem() {
438
                for (int i = 0; i < items.size(); i++) {
439
                        if (((ItemColorSlider) items.get(i)).getSelected() != -1)
440
                                return (ItemColorSlider) items.get(i);
441
                }
442
                return null;
443
        }
444

    
445
        /*
446
         * (non-Javadoc)
447
         * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
448
         */
449
        public void mouseDragged(MouseEvent e) {
450
                ItemColorSlider aux = getSelectedItem();
451
                if (aux != null) {
452
                        if (aux.getSelected() == 1) {
453
                                aux.setValue(pixelToValue(e.getX()));
454
                                refreshImage();
455
                                setMouseCursor(e.getX(), e.getY());
456
                                aux.setVisible((e.getY() <= height) && (e.getY() >= 0) || items.size() <= 2);
457
                                return;
458
                        }
459
                        if (aux.getSelected() == 2) {
460
                                int pos = -1;
461
                                for (int i = 0; i < items.size(); i++) {
462
                                        if (items.get(i) == aux)
463
                                                pos = i;
464
                                }
465
                                if (pos > 0) {
466
                                        double min = ((ItemColorSlider) items.get(pos - 1)).getValue();
467
                                        double max = ((ItemColorSlider) items.get(pos)).getValue();
468

    
469
                                        double newValue = 100 * (pixelToValue(e.getX()) - min) / (max - min);
470

    
471
                                        aux.setInterpolated(newValue);
472
                                        refreshImage();
473
                                        setMouseCursor(e.getX(), e.getY());
474
                                }
475
                                return;
476
                        }
477
                }
478
        }
479

    
480
        private ItemColorSlider getItem(int x, int y) {
481
                for (int i = 0; i < items.size(); i++) {
482
                        if ((x >= (valueToPixel(((ItemColorSlider) items.get(i)).getValue()) - 5)) &&
483
                                        (x <= (valueToPixel(((ItemColorSlider) items.get(i)).getValue()) + 5)) &&
484
                                        (y <= height) &&
485
                                        (y >= (height - 18))) {
486
                                return (ItemColorSlider) items.get(i);
487
                        }
488
                }
489
                return null;
490
        }
491

    
492
        private ItemColorSlider getItemInterpolated(int x, int y) {
493
                for (int i = 1; i < items.size(); i++) {
494
                        int value = valueToPixel(((ItemColorSlider) items.get(i - 1)).getValue() + ((((ItemColorSlider) items.get(i)).getValue() - ((ItemColorSlider) items.get(i - 1)).getValue()) * ((ItemColorSlider) items.get(i)).getInterpolated() / 100));
495

    
496
                        if ((x >= value - 3) &&
497
                                        (x <= value + 3) &&
498
                                        (y <= (height - 11)) &&
499
                                        (y >= (height - 18))) {
500
                                if (((ItemColorSlider) items.get(i)).getSelected() != -1)
501
                                        return (ItemColorSlider) items.get(i);
502
                                if (((ItemColorSlider) items.get(i - 1)).getSelected() == 1)
503
                                        return (ItemColorSlider) items.get(i);
504
                        }
505
                }
506
                return null;
507
        }
508

    
509
        private void setMouseCursor(int x, int y) {
510
                if (getItem(x, y) != null) {
511
                        setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
512
                        return;
513
                }
514
                if (getItemInterpolated(x, y) != null) {
515
                        setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
516
                        return;
517
                }
518
                if ((y <= height) && (y >= (height - 18))) {
519
                        setCursor(new Cursor(Cursor.HAND_CURSOR));
520
                        return;
521
                }
522
                setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
523
                return;
524
        }
525

    
526
        /*
527
         * (non-Javadoc)
528
         * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
529
         */
530
        public void mouseMoved(MouseEvent e) {
531
                setMouseCursor(e.getX(), e.getY());
532
        }
533

    
534
        /**
535
         * @return the interpolated
536
         */
537
        public boolean isInterpolated() {
538
                return interpolated;
539
        }
540

    
541
        /**
542
         * @param interpolated the interpolated to set
543
         */
544
        public void setInterpolated(boolean interpolated) {
545
                this.interpolated = interpolated;
546
                refreshImage();
547
        }
548

    
549
        public void mouseClicked(MouseEvent e) {}
550
        public void mouseEntered(MouseEvent e) {}
551
        public void mouseExited(MouseEvent e) {}
552
}