OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 94 | 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;
156 ilm 139
                    if (position < te.length) {
140
                        te[position] = text.charAt(i);
141
                    }
93 ilm 142
                }
143
                for (int i = 0; i < stop; i++) {
144
                    int position = i + offset;
145
                    final char c = text.charAt(i);
146
                    if (!isCharValid(c, position, te)) {
147
                        return;
148
                    }
149
                }
150
 
151
                if (length == 0) {
152
                    super.remove(fb, offset, text.length());
153
                }
154
                super.replace(fb, offset, length, text, attrs);
155
 
156
            }
157
 
158
        });
159
        // Move cusor to not be on ':'
160
        this.setNavigationFilter(new NavigationFilter() {
156 ilm 161
 
93 ilm 162
            @Override
163
            public int getNextVisualPositionFrom(JTextComponent text, int pos, Bias bias, int direction, Bias[] biasRet) throws BadLocationException {
164
                if (pos == 1 && direction == SwingConstants.EAST) {
165
                    pos++;
166
                }
167
                if (pos == 3 && direction == SwingConstants.WEST) {
168
                    pos--;
169
                }
170
                return super.getNextVisualPositionFrom(text, pos, bias, direction, biasRet);
171
            }
172
 
173
            @Override
174
            public void moveDot(FilterBypass fb, int dot, Bias bias) {
175
                if (dot == 2) {
176
                    dot = 3;
177
                }
178
                super.moveDot(fb, dot, bias);
179
            }
180
 
181
            @Override
182
            public void setDot(FilterBypass fb, int dot, Bias bias) {
183
                if (dot == 2) {
184
                    dot = 3;
185
                }
186
                super.setDot(fb, dot, bias);
187
            }
188
        });
189
        doc.addDocumentListener(new DocumentListener() {
190
 
191
            @Override
192
            public void removeUpdate(DocumentEvent e) {
193
                changedUpdate(e);
194
 
195
            }
196
 
197
            @Override
198
            public void insertUpdate(DocumentEvent e) {
199
                changedUpdate(e);
200
 
201
            }
202
 
203
            @Override
204
            public void changedUpdate(DocumentEvent e) {
205
                if (getText().length() == 5) {
206
                    // Fire only on end of value update
207
                    firePropertyChange("value", null, getText());
208
                }
209
            }
210
        });
211
    }
212
 
213
    public void setTime(int hour, int minute) {
214
        if (hour < 0 || hour > 23) {
215
            throw new IllegalArgumentException("Hour must be betwen 0 and 23 but is " + hour);
216
        }
217
        if (minute < 0 || minute > 59) {
218
            throw new IllegalArgumentException("Minute must be betwen 0 and 59 but is " + minute);
219
        }
220
        String s = "";
221
        if (hour < 10) {
222
            s += "0";
223
        }
224
        s += hour + ":";
225
        if (minute < 10) {
226
            s += "0";
227
        }
228
        s += minute;
229
        setText(s);
230
    }
231
 
232
    public int getHours() {
233
        final String s = getText().substring(0, 2);
234
        return Integer.parseInt(s);
235
    }
236
 
237
    public int getMinutes() {
238
        final String s = getText().substring(3, 5);
239
        return Integer.parseInt(s);
240
    }
241
 
242
    protected String fill2Char(int i) {
243
        if (i < 10) {
244
            return "0" + i;
245
        }
246
        return String.valueOf(i);
247
    }
248
 
249
    @Override
250
    public void setCaretPosition(int position) {
251
        if (position == 2) {
252
            position++;
253
        }
254
        super.setCaretPosition(position);
255
    }
256
 
257
    public boolean isCharValid(char c, int position, char[] actualText) {
258
        switch (position) {
259
        case 0:
260
            if (c >= '0' && c <= '1')
261
                return true;
262
            char c1 = actualText[1];
263
            if (c == '2' && c1 <= '3')
264
                return true;
265
            break;
266
        case 1:
267
            if (c >= '0' && c <= '3')
268
                return true;
269
            char c0 = actualText[0];
270
            if (c >= '4' && c <= '9' && (c0 == '0' || c0 == '1'))
271
                return true;
272
            break;
273
        case 2:
274
            if (c == ':')
275
                return true;
276
            break;
277
        case 3:
278
            if (c >= '0' && c <= '5')
279
                return true;
280
            break;
281
        case 4:
282
            if (c >= '0' && c <= '9')
283
                return true;
284
            break;
285
        }
286
        return false;
287
 
288
    }
289
 
290
    public static void main(String[] args) {
291
        final JFrame f = new JFrame();
292
        final TimeTextField time = new TimeTextField(true);
293
        time.setTime(10, 59);
294
        f.setContentPane(time);
295
        f.pack();
296
        f.setLocationRelativeTo(null);
297
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
298
        f.setVisible(true);
299
    }
300
}