Statistics
| Revision:

root / trunk / libraries / libUI / src / org / gvsig / gui / beans / swing / JIncrementalNumberField.java @ 13133

History | View | Annotate | Download (8.71 KB)

1 11734 jaume
/* 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
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.gui.beans.swing;
42
43
import java.awt.BasicStroke;
44
import java.awt.BorderLayout;
45
import java.awt.Color;
46
import java.awt.Component;
47
import java.awt.Dimension;
48
import java.awt.Graphics;
49
import java.awt.Graphics2D;
50
import java.awt.event.ActionEvent;
51
import java.awt.event.ActionListener;
52
import java.awt.event.MouseEvent;
53
import java.awt.event.MouseListener;
54 11849 jaume
import java.util.ArrayList;
55 11734 jaume
import java.util.Timer;
56
import java.util.TimerTask;
57
58
import javax.swing.BorderFactory;
59
import javax.swing.Icon;
60
import javax.swing.JButton;
61
import javax.swing.JPanel;
62
import javax.swing.SwingConstants;
63
64
import org.gvsig.gui.beans.Messages;
65
import org.gvsig.gui.beans.swing.ValidatingTextField.Cleaner;
66
import org.gvsig.gui.beans.swing.ValidatingTextField.Validator;
67
68
/**
69 12958 jaume
 * This class represents a JTextField-like component that allows to input numbers
70
 * and featuring a built-in increment or decrease of the number using the mouse.
71 11734 jaume
 * @author jaume dominguez faus - jaume.dominguez@iver.es
72
 */
73
public class JIncrementalNumberField extends JPanel {
74 12560 jaume
75
        private static final long serialVersionUID = 5225633490545230468L;
76 11734 jaume
        private boolean acceptsDoubles;
77
        private ValidatingTextField vtf;
78
        private double step;
79 12560 jaume
        private double maxValue;
80
        private double minValue;
81 11734 jaume
82
83
        private ActionListener accum = new ActionListener() {
84
                public void actionPerformed(ActionEvent e) {
85
                        String command = e.getActionCommand();
86
                        if ("UP".equals(command)) {
87
                                if (acceptsDoubles) {
88
                                        double v = getDouble() + step;
89 12560 jaume
                                        if (v>maxValue)
90
                                                v = maxValue;
91 11734 jaume
                                        setDouble(v);
92
                                } else {
93
                                        int v = getInteger() + (int) Math.round(step);
94 12560 jaume
                                        if (v>maxValue)
95
                                                v = (int) maxValue;
96 11734 jaume
                                        setInteger(v);
97
                                }
98
                        } else if ("DOWN".equals(command)) {
99
                                if (acceptsDoubles) {
100
                                        double v = getDouble() - step;
101 12560 jaume
                                        if (v<minValue)
102
                                                v = minValue;
103 11734 jaume
                                        setDouble(v);
104 11849 jaume
105 11734 jaume
                                } else {
106
                                        int v = getInteger() - (int) Math.round(step);
107 12560 jaume
                                        if (v<minValue)
108
                                                v = (int) minValue;
109 11734 jaume
                                        setInteger(v);
110
                                }
111
                        }
112 11849 jaume
                        fireActionPerformed();
113 11734 jaume
                }
114
        };
115 11920 jaume
116 11734 jaume
        private JButton down;
117
        private JButton up;
118 11849 jaume
        private ArrayList listeners = new ArrayList();
119 11734 jaume
120
        private class MousePressedTask extends TimerTask {
121
                private MouseEvent e;
122
                private ButtonMouseListener ml;
123
124
                private MousePressedTask(ButtonMouseListener ml, MouseEvent e){
125
                        super();
126
                        this.ml = ml;
127
                        this.e = e;
128
                }
129
130
                public void run() {
131
                        JButton b = (JButton) e.getComponent();
132
133
                        long time = System.currentTimeMillis();
134
                        long delay = 200;
135
136
                        while (ml.pressed) {
137
                                if (ml.in) {
138
                                        accum.actionPerformed(new ActionEvent(b, 12431, b.getActionCommand()));
139
140
                                        long currTime = System.currentTimeMillis();
141 13133 jaume
                                        /*
142
                                         * each 1000 milliseconds the delay between value change
143
                                         * will be reduced to a half until it reaches 20 millis of
144
                                         * minimum delay, so it speeds up the increase/decrease
145
                                         * process to let the user to reach far values in less time
146
                                         * by keeping the button pressed.
147
                                         */
148
                                        if (delay > 20 && ((currTime - time) > 1000)) {
149 11734 jaume
                                                delay /= 2;
150
                                                time = currTime;
151
                                        }
152
                                } else time = System.currentTimeMillis();
153
                                try {
154
                                        Thread.sleep(delay);
155
                                } catch (InterruptedException e1) {
156
                                        e.consume();
157
                                }
158
159
                        }
160 11889 jaume
                        e.consume();
161 11734 jaume
                }
162
        }
163
164
        private class ButtonMouseListener implements MouseListener{
165
                boolean in = false;
166
                boolean pressed = false;
167
168
                public void mouseClicked(MouseEvent e) { /* nothing (managed by the ActionListener) */ }
169
170
                public void mouseEntered(MouseEvent e) {
171
                        in = true;
172
                }
173
174
                public void mouseExited(MouseEvent e) {
175
                        in = false;
176
                }
177
178
                public void mousePressed(MouseEvent e) {
179 11889 jaume
                        MousePressedTask task;
180
                        synchronized (this) {
181
                                pressed = true;
182
                                Timer timer = new Timer();
183
                                task = new MousePressedTask(this, e);
184
                                timer.schedule(task, 500);
185 11734 jaume
186 11889 jaume
                        }
187
                        if (!pressed) {
188
                                task.cancel();
189
                        }
190
191 11734 jaume
                }
192
193
                public void mouseReleased(MouseEvent e) {
194
                        pressed = false;
195
                }
196
197
        };
198
199
200
        public JIncrementalNumberField() {
201
                this("");
202
        }
203
204
        public JIncrementalNumberField(String text) {
205
                this(text, 7);
206
        }
207
208
        public JIncrementalNumberField(String text, int columns) {
209
                this(text, columns, ValidatingTextField.DOUBLE_VALIDATOR, ValidatingTextField.NUMBER_CLEANER, -Double.MAX_VALUE, Double.MAX_VALUE, 1);
210
        }
211
212
        public JIncrementalNumberField(String text, int columns, double minValue, double maxValue, double step) {
213
                this(text, columns, ValidatingTextField.DOUBLE_VALIDATOR, ValidatingTextField.NUMBER_CLEANER, minValue, maxValue, step);
214
        }
215
216
        public JIncrementalNumberField(String text, int columns, Validator validator, Cleaner cleaner, double minValue, double maxValue, double step) {
217
                super();
218
                if (text == null) text = "";
219
220 12560 jaume
                this.minValue = minValue;
221
                this.maxValue = maxValue;
222 11734 jaume
                this.step = step;
223
                acceptsDoubles = validator.getClass().equals(ValidatingTextField.DOUBLE_VALIDATOR.getClass());
224
225
                JPanel lateralButtons = new JPanel();
226
                Icon upIcon = new Icon() {
227
228
                        public int getIconHeight() {
229
                                return 5;
230
                        }
231
232
                        public int getIconWidth() {
233
                                return 9;
234
                        }
235
236
                        public void paintIcon(Component c, Graphics g, int x, int y) {
237
                                g.setColor(Color.DARK_GRAY);
238
                                ((Graphics2D) g).setStroke(new BasicStroke(2));
239
                                g.drawLine(3, 6, 5, 3);
240
                                g.drawLine(5, 3, 8, 6);
241
242
                        }
243
                };
244
                Icon downIcon = new Icon() {
245
                        public int getIconHeight() {
246
                                return 5;
247
                        }
248
249
                        public int getIconWidth() {
250
                                return 9;
251
                        }
252
253
                        public void paintIcon(Component c, Graphics g, int x, int y) {
254
                                g.setColor(Color.DARK_GRAY);
255
                                ((Graphics2D) g).setStroke(new BasicStroke(2));
256
                                g.drawLine(3, 3, 5, 6);
257
                                g.drawLine(5, 6, 8, 3);
258
259
260
                        }
261
                };
262
                up = new JButton(upIcon);
263
                up.setActionCommand("UP");
264
                up.addActionListener(accum);
265
                up.addMouseListener(new ButtonMouseListener());
266 12957 jaume
                up.setBounds(0, 0, 11, 11);
267 11734 jaume
268
                down = new JButton(downIcon);
269
                down.setActionCommand("DOWN");
270
                down.addActionListener(accum);
271
                down.addMouseListener(new ButtonMouseListener());
272 12957 jaume
                down.setBounds(0, 11, 11, 11);
273 11734 jaume
274
275
276
                lateralButtons.setLayout(null);
277 12957 jaume
                lateralButtons.setSize(13, 20);
278 11734 jaume
                lateralButtons.add(up);
279
                lateralButtons.add(down);
280
                lateralButtons.setSize(new Dimension(11, 22));
281
                lateralButtons.setPreferredSize(new Dimension(11, 22));
282
                lateralButtons.setBorder(BorderFactory.createLineBorder(Color.GREEN));
283
                vtf = new ValidatingTextField(
284
                                text,
285
                                columns,
286
                                SwingConstants.RIGHT,
287
                                validator,
288
                                cleaner) ;
289
                setLayout(new BorderLayout(0, 0));
290
                add(vtf, BorderLayout.CENTER);
291
                add(lateralButtons, BorderLayout.EAST);
292
        }
293
294
        public int getInteger() {
295
                return vtf.getInteger();
296
        }
297
298
        public double getDouble() {
299
                if (!acceptsDoubles)
300
                        throw new Error(Messages.getText(
301
                                        "cannot_get_double_value_from_an_integer_number_field_use_getInteger()_instead"));
302
                return vtf.getDouble();
303
        }
304
305
        public void setDouble(double v) {
306
                if (!acceptsDoubles)
307
                        throw new Error(Messages.getText(
308
                                        "cannot_set_a_double_value_from_an_integer_number_field_use_setInteger(int)_instead"));
309
                vtf.setText(String.valueOf(v));
310
        }
311
312
        public void setInteger(int v) {
313
                vtf.setText(String.valueOf(v));
314
        }
315
316
        public void addActionListener(ActionListener l) {
317
                vtf.addActionListener(l);
318 11849 jaume
                listeners .add(l);
319 11734 jaume
        }
320 11849 jaume
321
        private void fireActionPerformed() {
322
                ActionEvent evt = new ActionEvent(this, 0, null);
323
                for (int i = 0; i < listeners.size(); i++) {
324
                        ((ActionListener) listeners.get(i)).actionPerformed(evt);
325
                }
326
        }
327 12560 jaume
328
        public double getMaxValue() {
329
                return maxValue;
330
        }
331
332
        public void setMaxValue(double maxValue) {
333
                this.maxValue = maxValue;
334
        }
335
336
        public double getMinValue() {
337
                return minValue;
338
        }
339
340
        public void setMinValue(double minValue) {
341
                this.minValue = minValue;
342
        }
343
344
        public double getStep() {
345
                return step;
346
        }
347
348
        public void setStep(double step) {
349
                this.step = step;
350
        }
351 11734 jaume
}