OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 93 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
93 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.ui;
15
 
16
import java.awt.event.KeyAdapter;
17
import java.awt.event.KeyEvent;
18
import java.util.Calendar;
19
 
20
import javax.swing.JFrame;
21
import javax.swing.JTextField;
22
import javax.swing.SwingConstants;
23
import javax.swing.event.DocumentEvent;
24
import javax.swing.event.DocumentListener;
25
import javax.swing.text.AbstractDocument;
26
import javax.swing.text.AttributeSet;
27
import javax.swing.text.BadLocationException;
28
import javax.swing.text.Document;
29
import javax.swing.text.DocumentFilter;
30
import javax.swing.text.JTextComponent;
31
import javax.swing.text.NavigationFilter;
32
import javax.swing.text.Position.Bias;
33
 
34
public class TimeTextField extends JTextField {
35
 
36
    public TimeTextField() {
37
        super(6);
38
        init(0, 0);
39
    }
40
 
41
    public TimeTextField(boolean fillWithCurrentTime) {
42
        super(6);
43
        if (fillWithCurrentTime) {
44
            Calendar c = Calendar.getInstance();
45
            init(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE));
46
        } else {
47
            init(0, 0);
48
        }
49
    }
50
 
51
    public TimeTextField(int hour, int minute) {
52
        super(6);
53
        init(hour, minute);
54
    }
55
 
56
    private void init(int hour, int minute) {
57
        setTime(hour, minute);
58
        Document d = getDocument();
59
 
60
        this.addKeyListener(new KeyAdapter() {
61
 
62
            @Override
63
            public void keyPressed(KeyEvent e) {
64
                try {
65
                    if (e.getKeyCode() == KeyEvent.VK_UP) {
66
                        final int caretPosition = getCaretPosition();
67
 
68
                        if (caretPosition < 2) {
69
                            int i = getHours() + 1;
70
                            if (i > 23) {
71
                                i = 0;
72
                            }
73
                            final String valueOf = fill2Char(i);
74
                            ((AbstractDocument) getDocument()).replace(0, 2, valueOf, null);
75
                            setCaretPosition(caretPosition);
76
                        } else if (caretPosition > 2) {
77
                            int i = getMinutes() + 1;
78
                            if (i > 59) {
79
                                i = 0;
80
                            }
81
                            final String valueOf = fill2Char(i);
82
                            ((AbstractDocument) getDocument()).replace(3, 2, valueOf, null);
83
                            setCaretPosition(caretPosition);
84
                        }
85
 
86
                    } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
87
                        final int caretPosition = getCaretPosition();
88
                        if (caretPosition < 2) {
89
                            int i = getHours() - 1;
90
                            if (i < 0) {
91
                                i = 23;
92
                            }
93
                            final String valueOf = fill2Char(i);
94
                            ((AbstractDocument) getDocument()).replace(0, 2, valueOf, null);
95
                            setCaretPosition(caretPosition);
96
                        } else if (caretPosition > 2) {
97
                            int i = getMinutes() - 1;
98
                            if (i < 0) {
99
                                i = 59;
100
                            }
101
                            final String valueOf = fill2Char(i);
102
                            ((AbstractDocument) getDocument()).replace(3, 2, valueOf, null);
103
                            setCaretPosition(caretPosition);
104
                        }
105
                    }
106
                } catch (BadLocationException e1) {
107
                    e1.printStackTrace();
108
                }
109
 
110
            }
111
        });
112
 
113
        final AbstractDocument doc = (AbstractDocument) d;
114
        doc.setDocumentFilter(new DocumentFilter() {
115
 
116
            @Override
117
            public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
118
                if (offset == 2) {
119
                    offset--;
120
                }
121
                super.replace(fb, offset + 1, 0, "0", null);
122
                super.remove(fb, offset, 1);
123
                setCaretPosition(offset);
124
            }
125
 
126
            @Override
127
            public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
128
                if (offset > 4) {
129
                    return;
130
                }
131
                final String actualText = doc.getText(0, 5);
132
                if (length > 0 && text.length() != length) {
133
                    length = 0;
134
                }
135
                final char[] te = actualText.toCharArray();
136
                final int stop = text.length();
137
                for (int i = 0; i < stop; i++) {
138
                    int position = i + offset;
139
                    te[position] = text.charAt(i);
140
                }
141
                for (int i = 0; i < stop; i++) {
142
                    int position = i + offset;
143
                    final char c = text.charAt(i);
144
                    if (!isCharValid(c, position, te)) {
145
                        return;
146
                    }
147
                }
148
 
149
                if (length == 0) {
150
                    super.remove(fb, offset, text.length());
151
                }
152
                super.replace(fb, offset, length, text, attrs);
153
 
154
            }
155
 
156
        });
157
        // Move cusor to not be on ':'
158
        this.setNavigationFilter(new NavigationFilter() {
159
            @Override
160
            public int getNextVisualPositionFrom(JTextComponent text, int pos, Bias bias, int direction, Bias[] biasRet) throws BadLocationException {
161
                if (pos == 1 && direction == SwingConstants.EAST) {
162
                    pos++;
163
                }
164
                if (pos == 3 && direction == SwingConstants.WEST) {
165
                    pos--;
166
                }
167
                return super.getNextVisualPositionFrom(text, pos, bias, direction, biasRet);
168
            }
169
 
170
            @Override
171
            public void moveDot(FilterBypass fb, int dot, Bias bias) {
172
                if (dot == 2) {
173
                    dot = 3;
174
                }
175
                super.moveDot(fb, dot, bias);
176
            }
177
 
178
            @Override
179
            public void setDot(FilterBypass fb, int dot, Bias bias) {
180
                if (dot == 2) {
181
                    dot = 3;
182
                }
183
                super.setDot(fb, dot, bias);
184
            }
185
        });
186
        doc.addDocumentListener(new DocumentListener() {
187
 
188
            @Override
189
            public void removeUpdate(DocumentEvent e) {
190
                changedUpdate(e);
191
 
192
            }
193
 
194
            @Override
195
            public void insertUpdate(DocumentEvent e) {
196
                changedUpdate(e);
197
 
198
            }
199
 
200
            @Override
201
            public void changedUpdate(DocumentEvent e) {
202
                if (getText().length() == 5) {
203
                    // Fire only on end of value update
204
                    firePropertyChange("value", null, getText());
205
                }
206
            }
207
        });
208
    }
209
 
210
    public void setTime(int hour, int minute) {
211
        if (hour < 0 || hour > 23) {
212
            throw new IllegalArgumentException("Hour must be betwen 0 and 23 but is " + hour);
213
        }
214
        if (minute < 0 || minute > 59) {
215
            throw new IllegalArgumentException("Minute must be betwen 0 and 59 but is " + minute);
216
        }
217
        String s = "";
218
        if (hour < 10) {
219
            s += "0";
220
        }
221
        s += hour + ":";
222
        if (minute < 10) {
223
            s += "0";
224
        }
225
        s += minute;
226
        setText(s);
227
    }
228
 
229
    public int getHours() {
230
        final String s = getText().substring(0, 2);
231
        return Integer.parseInt(s);
232
    }
233
 
234
    public int getMinutes() {
235
        final String s = getText().substring(3, 5);
236
        return Integer.parseInt(s);
237
    }
238
 
239
    protected String fill2Char(int i) {
240
        if (i < 10) {
241
            return "0" + i;
242
        }
243
        return String.valueOf(i);
244
    }
245
 
246
    @Override
247
    public void setCaretPosition(int position) {
248
        if (position == 2) {
249
            position++;
250
        }
251
        super.setCaretPosition(position);
252
    }
253
 
254
    public boolean isCharValid(char c, int position, char[] actualText) {
255
        switch (position) {
256
        case 0:
257
            if (c >= '0' && c <= '1')
258
                return true;
259
            char c1 = actualText[1];
260
            if (c == '2' && c1 <= '3')
261
                return true;
262
            break;
263
        case 1:
264
            if (c >= '0' && c <= '3')
265
                return true;
266
            char c0 = actualText[0];
267
            if (c >= '4' && c <= '9' && (c0 == '0' || c0 == '1'))
268
                return true;
269
            break;
270
        case 2:
271
            if (c == ':')
272
                return true;
273
            break;
274
        case 3:
275
            if (c >= '0' && c <= '5')
276
                return true;
277
            break;
278
        case 4:
279
            if (c >= '0' && c <= '9')
280
                return true;
281
            break;
282
        }
283
        return false;
284
 
285
    }
286
 
287
    public static void main(String[] args) {
288
        final JFrame f = new JFrame();
289
        final TimeTextField time = new TimeTextField(true);
290
        time.setTime(10, 59);
291
        f.setContentPane(time);
292
        f.pack();
293
        f.setLocationRelativeTo(null);
294
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
295
        f.setVisible(true);
296
    }
297
}