OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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