Source code: org/fudaa/fudaa/sinavi/DureeField.java
1 /*
2 * @file DureeField.java
3 * @creation 2001-05-17
4 * @modification $Date: 2001/09/11 14:24:42 $
5 * @license GNU General Public License 2
6 * @copyright (c)1998-2001 CETMEF 2 bd Gambetta F-60231 Compiegne
7 * @mail devel@fudaa.org
8 */
9
10 package org.fudaa.fudaa.sinavi;
11
12 import java.lang.*;
13 import java.awt.*;
14 import java.util.*;
15 import java.awt.event.*;
16 import java.beans.*;
17
18 import javax.swing.*;
19 import javax.swing.border.*;
20
21 import com.memoire.bu.*;
22 import org.fudaa.fudaa.commun.*;
23
24 /**
25 * Composant permettant de saisir des durées sous différents formats. Le format
26 * des données est controle par des validateur. Principe de convertion
27 * automatique (chaine vers nombre de minutes et vise versa) :<br>
28 * 60 minutes : 1 heure <br>
29 * 24 heures : 1 jour <br>
30 * 31 jours : 1 mois<br>
31 * 31 :nombre de jours de janvier<br>
32 * 31+28 jours :2 mois ( = nombre de jours de janv. + fevrier ).
33 *
34 * @version $Revision: 1.7 $ $Date: 2001/09/11 14:24:42 $ by $Author: deniger $
35 * @author Aline Marechalle , Franck Lejeune
36 */
37 public class DureeField extends JComponent implements FocusListener
38 {
39
40 /**
41 * Caractères valides pour les durées : numéro ou deux points.
42 */
43 final BuCharValidator CHAR_DUREE =new BuCharValidator()
44 {
45 /**
46 * retourne la valeur CharValid de DureeField object
47 *
48 * @param _char
49 * @return La valeur CharValid
50 */
51 public boolean isCharValid(char _char)
52 {
53
54 if(_char == ':')
55 {
56 String chaine = zoneTexte.getText();
57 StringTokenizer token = new StringTokenizer(chaine, ":");
58 int nbElts = token.countTokens();
59 if(nbElts < nbEltsMax)
60 {
61 return true;
62 }
63 }
64 else if(Character.isDigit(_char))
65 {
66 return true;
67 }
68
69 return false;
70 }
71 };
72
73 /**
74 * ....
75 */
76 final BuValueValidator VALUE_DUREE =new BuValueValidator()
77 {
78 /**
79 * retourne la valeur ValueValid de DureeField object
80 *
81 * @param _value
82 * @return La valeur ValueValid
83 */
84 public boolean isValueValid(Object _value)
85 {
86
87 // Seules les instances de Integer sont acceptées
88 if((_value instanceof Integer) == false)
89 {
90 return false;
91 }
92
93 int val = ((Integer)_value).intValue();
94 if(val < 0)
95 {
96 return false;
97 }
98
99 // Erreur s'il reste des secondes et qu'elles ne sont pas demandées
100 if(presenceMinutes && !presenceSecondes && (val % 60) != 0)
101 {
102 return false;
103 }
104
105 val = val / 60;// val converti en minutes
106
107 // Erreur s'il reste des minutes et qu'elles ne sont pas demandées
108 if(presenceHeures && !presenceMinutes && (val % 60) != 0)
109 {
110 return false;
111 }
112
113 val = val / 60;// val converti en heures
114 // Erreur s'il reste des heures et qu'elles ne sont pas demandées
115 if(presenceJours && !presenceHeures && (val % 24) != 0)
116 {
117 return false;
118 }
119
120 val = val / 24;// val converti en jours
121 // Si les jours ne sont pas demandées
122 if(presenceMois && !presenceJours)
123 {
124 int m = 0;
125 while(val >= (calendrier[m % 12]) * 1440)
126 {
127 val = val - (calendrier[m % 12]) * 1440;
128 m++;
129 }
130
131 // Erreur s'il reste des jours et qu'ils ne sont pas demandés
132 if(val != 0)
133 {
134 return false;
135 }
136 }
137
138 return true;
139 }
140 };
141
142 /**
143 * ....
144 */
145 final BuStringValidator STRING_DUREE =new BuStringValidator()
146 {
147 /**
148 * retourne la valeur StringValid de DureeField object
149 *
150 * @param _string
151 * @return La valeur StringValid
152 */
153 public boolean isStringValid(String _string)
154 {
155
156 StringTokenizer token = new StringTokenizer(_string, ":");
157
158 if(token.countTokens() > nbEltsMax)
159 {
160 return false;
161 }
162
163 return true;
164 }
165
166
167 /**
168 * Transforme le nombre de secondes donné en paramètre en champ
169 * affichable. Les données sont supposées acceptées par isValueValid.
170 *
171 * @param value
172 * @return
173 */
174 public String valueToString(Object value)
175 {
176 int secondes = ((Integer)value).intValue();
177 String nbMois = "";
178 String nbJours = "";
179 String nbHeures = "";
180 String nbMinutes = "";
181 String nbSecondes = "";
182
183 // Calcule du nombre de mois s'ils sont demandés
184 if(presenceMois)
185 {
186 int m = 0;
187 while(secondes >= (calendrier[m % 12]) * 86400)
188 {
189 secondes -= (calendrier[m % 12]) * 86400;
190 m++;
191 }
192 nbMois = (m < 10 ? "0" + String.valueOf(m) : String.valueOf(m));
193 }
194
195 // Calcule le nombre de jours s'ils sont demandés
196 if(presenceJours)
197 {
198 int jours = secondes / 86400;
199 secondes -= jours * 86400;
200 if(presenceMois)
201 {
202 nbJours = ":";
203 }
204 nbJours += (jours < 10 ? "0" + String.valueOf(jours) : String.valueOf(jours));
205 }
206
207 // Calcule le nombre d'heures si elles sont demandées
208 if(presenceHeures)
209 {
210 int heures = secondes / 3600;
211 secondes -= heures * 3600;
212 if(presenceJours)
213 {
214 nbHeures = ":";
215 }
216 nbHeures += (heures < 10 ? "0" + String.valueOf(heures) : String.valueOf(heures));
217 }
218
219 // Calcule le nombre de minutes si elles sont demandées
220 if(presenceMinutes)
221 {
222 int minutes = secondes / 60;
223 secondes -= minutes * 60;
224 if(presenceHeures)
225 {
226 nbMinutes = ":";
227 }
228 nbMinutes += (minutes < 10 ? "0" + String.valueOf(minutes) : String.valueOf(minutes));
229 }
230 // Affecte les secondes si elles sont demandées
231 if(presenceSecondes)
232 {
233 if(presenceMinutes)
234 {
235 nbSecondes = ":";
236 }
237 nbSecondes += (secondes < 10 ? "0" + String.valueOf(secondes) : String.valueOf(secondes));
238 }
239
240 return nbMois + nbJours + nbHeures + nbMinutes + nbSecondes;
241 }
242
243
244 /**
245 * Calcule le nombre de secondes correspondant au texte donné. Chaine est
246 * supposé accepté par isStringValid. principe de convertion automatique
247 * <br>
248 * 60 secondes :1 minute<br>
249 * 60 minutes :1 heure<br>
250 * 24 heures :1 jour<br>
251 * 31 jours:1 mois<br>
252 * 31+28 jours :2 mois ( = nombre de jours de janv. + fevrier )
253 *
254 * @param chaine
255 * @return
256 */
257 public Object stringToValue(String chaine)
258 {
259
260 StringTokenizer token = new StringTokenizer(chaine, ":");
261 // Nb d'éléments de la chaine separes par ":"
262 int nbEltDonnes = token.countTokens();
263 int nbEltsAttendus = nbEltsMax;
264 int sec = 0;
265
266 if(presenceMois && nbEltDonnes == nbEltsAttendus--)
267 {
268 int tempo = Integer.parseInt(token.nextToken());
269 for(int i = 0; i < tempo; i++)
270 {
271 sec += +86400 * calendrier[i % 12];
272 }
273 }
274 if(presenceJours && nbEltDonnes >= nbEltsAttendus--)
275 {
276 sec += 86400 * Integer.parseInt(token.nextToken());
277 }
278 if(presenceHeures && nbEltDonnes >= nbEltsAttendus--)
279 {
280 sec += 3600 * Integer.parseInt(token.nextToken());
281 }
282 if(presenceMinutes && nbEltDonnes >= nbEltsAttendus--)
283 {
284 sec += 60 * Integer.parseInt(token.nextToken());
285 }
286 if(presenceSecondes && nbEltDonnes >= nbEltsAttendus--)
287 {
288 sec += Integer.parseInt(token.nextToken());
289 }
290
291 return new Integer(sec);
292 }
293
294 };
295
296 /**
297 * ....
298 */
299 private static int[] calendrier =
300 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
301
302 /**
303 * ....
304 */
305 private boolean presenceMois, presenceJours, presenceHeures, presenceMinutes,
306 presenceSecondes;
307 /**
308 * ....
309 */
310 private BuTextField zoneTexte = new BuTextField();
311
312 /**
313 * ....
314 */
315 private BuLabel label = new BuLabel();
316
317 /**
318 * Nb maxi d'éléments séparés par des ":"
319 */
320 private int nbEltsMax = 0;
321
322
323
324 /**
325 * Création d'une zone de texte. Le format des données saisies devra respecter
326 * les champs demandés. ATTENTION : restez coherant si vous creez les mois et
327 * les heures, creez aussi les jours.
328 *
329 * @param m presence des mois.
330 * @param j presence des jours.
331 * @param h presence des heures.
332 * @param min presence des minutes.
333 * @param sec
334 */
335 public DureeField(boolean m, boolean j, boolean h, boolean min, boolean sec)
336 {
337
338 String textLabel = "";
339
340 // test de compatibilite de l'argument
341 if((m) && (!j) && (h))
342 {
343 throw new IllegalArgumentException
344 ("ERREUR de DureeField : manque les jours");
345 }
346
347 if((j) && (!h) && (min))
348 {
349 throw new IllegalArgumentException
350 ("ERREUR de DureeField : manque les heures");
351 }
352
353 if((h) && (!min) && (sec))
354 {
355 throw new IllegalArgumentException
356 ("ERREUR de DureeField : manque les minutes");
357 }
358
359 if((m) && (!j) && (!h) && (min))
360 {
361 throw new IllegalArgumentException
362 ("ERREUR de DureeField : manque les jours et les heures");
363 }
364
365 if((m) && (!j) && (!h) && (!min) && (sec))
366 {
367 throw new IllegalArgumentException
368 ("ERREUR de DureeField : manque les jours, les heures et les minutes");
369 }
370
371 if((j) && (!h) && (!min) && (sec))
372 {
373 throw new IllegalArgumentException
374 ("ERREUR de DureeField : manque les heures et les minutes");
375 }
376
377 // Flags pour les champs demandés
378 presenceMois = m;
379 presenceJours = j;
380 presenceHeures = h;
381 presenceMinutes = min;
382 presenceSecondes = sec;
383
384 // Validators pour les durée
385 zoneTexte.setCharValidator(CHAR_DUREE);
386 zoneTexte.setValueValidator(VALUE_DUREE);
387 zoneTexte.setStringValidator(STRING_DUREE);
388
389 // Layout manager
390 BuGridLayout lodate = new BuGridLayout(2, 5, 5, false, false);
391 setLayout(lodate);
392
393 add(zoneTexte);
394 add(label);
395 zoneTexte.setColumns(6);
396 zoneTexte.addFocusListener(this);
397
398 if(presenceMois)
399 {
400 textLabel += " mois :";
401 nbEltsMax++;
402 }
403 if(presenceJours)
404 {
405 textLabel += " jours :";
406 nbEltsMax++;
407 }
408 if(presenceHeures)
409 {
410 textLabel += " h :";
411 nbEltsMax++;
412 }
413 if(presenceMinutes)
414 {
415 textLabel += " min :";
416 nbEltsMax++;
417 }
418 if(presenceSecondes)
419 {
420 textLabel += " sec:";
421 nbEltsMax++;
422 }
423
424 label.setText(textLabel.substring(0, textLabel.length() - 1));
425 setValue(0);
426
427 }
428
429
430 /**
431 * Permet de lire la valeur de la zone de saisie (en nombre de minutes).
432 *
433 * @return La valeur DureeField
434 */
435 public int getDureeField()
436 {
437 Integer val = (Integer)zoneTexte.getValue();
438 return val.intValue();
439 }
440
441
442 /**
443 * Pour savoir si le composant est actif. Renvoie true si zoneTexte et label
444 * sont actifs
445 *
446 * @return La valeur Enabled
447 */
448 public boolean isEnabled()
449 {
450
451 boolean flag1 = zoneTexte.isEnabled();
452 boolean flag2 = label.isEnabled();
453 return (flag1 & flag2);
454 }
455
456
457 /**
458 * Quand on entre dans la zone de texte c'est que l'on entre dans le
459 * composant.
460 *
461 * @param e
462 */
463 public void focusGained(FocusEvent e)
464 {
465 zoneTexte.selectAll();
466 processFocusEvent(new FocusEvent(this, FocusEvent.FOCUS_GAINED));
467 }
468
469
470 /**
471 * Quand on sort de la zone de texte c'est que l'on sort du composant.
472 *
473 * @param e
474 */
475 public void focusLost(FocusEvent e)
476 {
477 processFocusEvent(new FocusEvent(this, FocusEvent.FOCUS_LOST));
478 }
479
480
481 /**
482 * Permet de modifier la valeur de la zone de texte.
483 *
484 * @param m nombre de mois.
485 * @param j nombre de jours.
486 * @param h nombre d' heures.
487 * @param min nombre de minutes.
488 * @param sec nombre de secondes;
489 */
490 public void setDureeField(int m, int j, int h, int min, int sec)
491 {
492 if((sec >= 0) && (min >= 0) && (h >= 0) && (j >= 0) && (m >= 0))
493 {
494 sec = sec + min * 60 + h * 60 + j * 24 * 60;
495 for(int i = 0; i < m; i++)
496 {
497 sec = sec + 60 * 60 * 24 * calendrier[i % 12];
498 }
499 setDureeField(sec);
500 }
501 else
502 {
503 setDureeField(-1);
504 }
505 }
506
507
508 /**
509 * Idem setDureeField(int m,int j,int h, int min).
510 *
511 * @param m La nouvelle valeur Value
512 * @param j La nouvelle valeur Value
513 * @param h La nouvelle valeur Value
514 * @param min La nouvelle valeur Value
515 * @param sec La nouvelle valeur Value
516 */
517 public void setValue(int m, int j, int h, int min, int sec)
518 {
519 setDureeField(m, j, h, min, sec);
520 }
521
522
523 /**
524 * Permet de modifier la valeur de la zone de texte.
525 *
526 * @param val : nouvelle valeur, en minutes.
527 */
528 public void setDureeField(int val)
529 {
530 zoneTexte.setValue(new Integer(val));
531 }
532
533
534 /**
535 * Idem setDureeField(int val)
536 *
537 * @param val La nouvelle valeur Value
538 */
539 public void setValue(int val)
540 {
541 setDureeField(val);
542 }
543
544
545 /**
546 * Pour activer ou desactiver le composant.
547 *
548 * @param flag La nouvelle valeur Enabled
549 */
550 public void setEnabled(boolean flag)
551 {
552 zoneTexte.setEnabled(flag);
553 label.setEnabled(flag);
554 }
555
556 /*
557 * public static String formatter(boolean pMois, boolean pJours, boolean pHeures, boolean pMinutes,boolean pSecondes, int secondes) {
558 *
559 * String retour = "";
560 *
561 * Calcule du nombre de mois d'ils sont demandés
562 * if ( pMois ) {
563 * int m = 0;
564 * while (secondes >= (calendrier[m % 12]) * 86400) {
565 * secondes -= (calendrier[m % 12]) * 86400;
566 * m++;
567 * }
568 * retour += ( m < 10 ? "0" : "") + String.valueOf( m ) + ":";
569 * }
570 *
571 * Calcule le nombre de jours s'ils sont demandés
572 * if ( pJours ) {
573 * int jours = secondes / 86400;
574 * secondes -= jours * 86400;
575 * retour += ( jours < 10 ? "0" : "") + String.valueOf(jours) + ":";
576 * }
577 *
578 * Calcule le nombre d'heures si elles sont demandées
579 * if ( pHeures ) {
580 * int heures = secondes / 3600;
581 * secondes -= heures * 3600;
582 * retour += ( heures < 10 ? "0" : "") + String.valueOf(heures) + ":";
583 * }
584 * Calcule le nombre de minutes si elles sont demandées
585 * if ( pHeures ) {
586 * int minutes = secondes / 60;
587 * secondes -= minutes * 60;
588 * retour += ( minutes < 10 ? "0" : "") + String.valueOf(minutes) + ":";
589 * }
590 *
591 * Affecte les secondes.
592 * if ( !pSecondes && secondes>0 ) retour += (secondes < 10 ? "0" : "") + String.valueOf ( secondes ) + "min:";
593 * else if ( pSecondes ) retour += (secondes < 10 ? "0" : "") + String.valueOf ( secondes ) + ":";
594 *
595 * return retour.substring(0, retour.length()-1);
596 *
597 * }
598 */
599
600 }
601