001    /* 
002     * Copyright (c) Holger Pfaff - http://pfaff.ws
003     *
004     * This software maybe used for any purpose provided the
005     * above copyright notice is retained. It is supplied as is.
006     * No warranty expressed or implied - Use at your own risk.
007     */
008    
009    import java.awt.*;
010    import java.util.*;
011    import java.awt.event.*;
012    
013    /**
014      * (#)Base.java
015      * @author   Holger Pfaff
016      * @version  3.2 19-Mar-2004<br><br>
017      *
018      * Common class to create arbitrary GUI programs. Needs Main as initiator.
019      * Base offers:<br>
020      * - a BorderPanel with different borders<br>
021      * - GUI items creation with options from properties<br>
022      * - access property files<br>
023      * <br>
024      * <table width="1%" border="1" cellspacing="2" cellpadding="2">
025      *   <tbody>
026      *     <tr>
027      *       <th valign="top"><prefix> +<br>
028      *       </th>
029      *       <th valign="top">Base<br>
030      *       </th>
031      *       <th valign="top">Caption<br>
032      *       </th>
033      *       <th valign="top">Knob<br>
034      *       </th>
035      *       <th valign="top">Triage<br>
036      *       </th>
037      *       <th valign="top">Xbox<br>
038      *       </th>
039      *       <th valign="top">MultiColumList<br>
040      *       </th>
041      *       <th valign="top">EditField<br>
042      *       </th>
043      *       <th valign="top">EditArea<br>
044      *       </th>
045      *     </tr>
046      *     <tr>
047      *       <td valign="top">""<br>
048      *       </td>
049      *       <td valign="top" align="center"><br>
050      *       </td>
051      *       <td valign="top" align="center">X<br>
052      *       </td>
053      *       <td valign="top" align="center">X<br>
054      *       </td>
055      *       <td valign="top" align="center">X<br>
056      *       </td>
057      *       <td valign="top" align="center">X<br>
058      *       </td>
059      *       <td valign="top" align="center"><br>
060      *       </td>
061      *       <td valign="top" align="center"><br>
062      *       </td>
063      *       <td valign="top" align="center"><br>
064      *       </td>
065      *     </tr>
066      *     <tr>
067      *       <td valign="top">label<br>
068      *       </td>
069      *       <td valign="top" align="center">X<br>
070      *       </td>
071      *       <td valign="top" align="center"><br>
072      *       </td>
073      *       <td valign="top" align="center"><br>
074      *       </td>
075      *       <td valign="top" align="center"><br>
076      *       </td>
077      *       <td valign="top" align="center"><br>
078      *       </td>
079      *       <td valign="top" align="center"><br>
080      *       </td>
081      *       <td valign="top" align="center"><br>
082      *       </td>
083      *       <td valign="top" align="center"><br>
084      *       </td>
085      *     </tr>
086      *     <tr>
087      *       <td valign="top">title<br>
088      *       </td>
089      *       <td valign="top" align="center">X<br>
090      *       </td>
091      *       <td valign="top" align="center"><br>
092      *       </td>
093      *       <td valign="top" align="center"><br>
094      *       </td>
095      *       <td valign="top" align="center"><br>
096      *       </td>
097      *       <td valign="top" align="center"><br>
098      *       </td>
099      *       <td valign="top" align="center"><br>
100      *       </td>
101      *       <td valign="top" align="center"><br>
102      *       </td>
103      *       <td valign="top" align="center"><br>
104      *       </td>
105      *     </tr>
106      *     <tr>
107      *       <td valign="top">tip<br>
108      *       </td>
109      *       <td valign="top" align="center">X<br>
110      *       </td>
111      *       <td valign="top" align="center">X<br>
112      *       </td>
113      *       <td valign="top" align="center"><br>
114      *       </td>
115      *       <td valign="top" align="center"><br>
116      *       </td>
117      *       <td valign="top" align="center"><br>
118      *       </td>
119      *       <td valign="top" align="center"><br>
120      *       </td>
121      *       <td valign="top" align="center">X<br>
122      *       </td>
123      *       <td valign="top" align="center">X<br>
124      *       </td>
125      *     </tr>
126      *     <tr>
127      *       <td valign="top">background<br>
128      *       </td>
129      *       <td valign="top" align="center">X<br>
130      *       </td>
131      *       <td valign="top" align="center">X<br>
132      *       </td>
133      *       <td valign="top" align="center">X<br>
134      *       </td>
135      *       <td valign="top" align="center">X<br>
136      *       </td>
137      *       <td valign="top" align="center">X<br>
138      *       </td>
139      *       <td valign="top" align="center">X<br>
140      *       </td>
141      *       <td valign="top" align="center">X<br>
142      *       </td>
143      *       <td valign="top" align="center">X<br>
144      *       </td>
145      *     </tr>
146      *     <tr>
147      *       <td valign="top">foreground<br>
148      *       </td>
149      *       <td valign="top" align="center">X<br>
150      *       </td>
151      *       <td valign="top" align="center">X<br>
152      *       </td>
153      *       <td valign="top" align="center">X<br>
154      *       </td>
155      *       <td valign="top" align="center">X<br>
156      *       </td>
157      *       <td valign="top" align="center">X<br>
158      *       </td>
159      *       <td valign="top" align="center">X<br>
160      *       </td>
161      *       <td valign="top" align="center">X<br>
162      *       </td>
163      *       <td valign="top" align="center">X<br>
164      *       </td>
165      *     </tr>
166      *     <tr>
167      *       <td valign="top">insets<br>
168      *       </td>
169      *       <td valign="top" align="center">X<br>
170      *       </td>
171      *       <td valign="top" align="center">X<br>
172      *       </td>
173      *       <td valign="top" align="center">X<br>
174      *       </td>
175      *       <td valign="top" align="center">X<br>
176      *       </td>
177      *       <td valign="top" align="center">X<br>
178      *       </td>
179      *       <td valign="top" align="center">X<br>
180      *       </td>
181      *       <td valign="top" align="center"><br>
182      *       </td>
183      *       <td valign="top" align="center"><br>
184      *       </td>
185      *     </tr>
186      *     <tr>
187      *       <td valign="top">innerinsets<br>
188      *       </td>
189      *       <td valign="top" align="center">X<br>
190      *       </td>
191      *       <td valign="top" align="center">X<br>
192      *       </td>
193      *       <td valign="top" align="center">X<br>
194      *       </td>
195      *       <td valign="top" align="center">X<br>
196      *       </td>
197      *       <td valign="top" align="center">X<br>
198      *       </td>
199      *       <td valign="top" align="center">X<br>
200      *       </td>
201      *       <td valign="top" align="center"><br>
202      *       </td>
203      *       <td valign="top" align="center"><br>
204      *       </td>
205      *     </tr>
206      *     <tr>
207      *       <td valign="top">bordertype<br>
208      *       </td>
209      *       <td valign="top" align="center">X<br>
210      *       </td>
211      *       <td valign="top" align="center">X<br>
212      *       </td>
213      *       <td valign="top" align="center">X<br>
214      *       </td>
215      *       <td valign="top" align="center">X<br>
216      *       </td>
217      *       <td valign="top" align="center">X<br>
218      *       </td>
219      *       <td valign="top" align="center">X<br>
220      *       </td>
221      *       <td valign="top" align="center"><br>
222      *       </td>
223      *       <td valign="top" align="center"><br>
224      *       </td>
225      *     </tr>
226      *     <tr>
227      *       <td valign="top">borderdepth<br>
228      *       </td>
229      *       <td valign="top" align="center">X<br>
230      *       </td>
231      *       <td valign="top" align="center">X<br>
232      *       </td>
233      *       <td valign="top" align="center">X<br>
234      *       </td>
235      *       <td valign="top" align="center">X<br>
236      *       </td>
237      *       <td valign="top" align="center">X<br>
238      *       </td>
239      *       <td valign="top" align="center">X<br>
240      *       </td>
241      *       <td valign="top" align="center"><br>
242      *       </td>
243      *       <td valign="top" align="center"><br>
244      *       </td>
245      *     </tr>
246      *     <tr>
247      *       <td valign="top">minimizable<br>
248      *       </td>
249      *       <td valign="top" align="center">X<br>
250      *       </td>
251      *       <td valign="top" align="center"><br>
252      *       </td>
253      *       <td valign="top" align="center"><br>
254      *       </td>
255      *       <td valign="top" align="center"><br>
256      *       </td>
257      *       <td valign="top" align="center"><br>
258      *       </td>
259      *       <td valign="top" align="center"><br>
260      *       </td>
261      *       <td valign="top" align="center"><br>
262      *       </td>
263      *       <td valign="top" align="center"><br>
264      *       </td>
265      *     </tr>
266      *     <tr>
267      *       <td valign="top">mini<br>
268      *       </td>
269      *       <td valign="top" align="center">X<br>
270      *       </td>
271      *       <td valign="top" align="center"><br>
272      *       </td>
273      *       <td valign="top" align="center"><br>
274      *       </td>
275      *       <td valign="top" align="center"><br>
276      *       </td>
277      *       <td valign="top" align="center"><br>
278      *       </td>
279      *       <td valign="top" align="center"><br>
280      *       </td>
281      *       <td valign="top" align="center"><br>
282      *       </td>
283      *       <td valign="top" align="center"><br>
284      *       </td>
285      *     </tr>
286      *     <tr>
287      *       <td valign="top">header<br>
288      *       </td>
289      *       <td valign="top" align="center"><br>
290      *       </td>
291      *       <td valign="top" align="center"><br>
292      *       </td>
293      *       <td valign="top" align="center"><br>
294      *       </td>
295      *       <td valign="top" align="center"><br>
296      *       </td>
297      *       <td valign="top" align="center"><br>
298      *       </td>
299      *       <td valign="top" align="center">X<br>
300      *       </td>
301      *       <td valign="top" align="center"><br>
302      *       </td>
303      *       <td valign="top" align="center"><br>
304      *       </td>
305      *     </tr>
306      *     <tr>
307      *       <td valign="top">visiblecols<br>
308      *       </td>
309      *       <td valign="top" align="center"><br>
310      *       </td>
311      *       <td valign="top" align="center"><br>
312      *       </td>
313      *       <td valign="top" align="center"><br>
314      *       </td>
315      *       <td valign="top" align="center"><br>
316      *       </td>
317      *       <td valign="top" align="center"><br>
318      *       </td>
319      *       <td valign="top" align="center">X<br>
320      *       </td>
321      *       <td valign="top" align="center"><br>
322      *       </td>
323      *       <td valign="top" align="center">X<br>
324      *       </td>
325      *     </tr>
326      *     <tr>
327      *       <td valign="top">minvisiblecols<br>
328      *       </td>
329      *       <td valign="top" align="center"><br>
330      *       </td>
331      *       <td valign="top" align="center"><br>
332      *       </td>
333      *       <td valign="top" align="center"><br>
334      *       </td>
335      *       <td valign="top" align="center"><br>
336      *       </td>
337      *       <td valign="top" align="center"><br>
338      *       </td>
339      *       <td valign="top" align="center">X<br>
340      *       </td>
341      *       <td valign="top" align="center"><br>
342      *       </td>
343      *       <td valign="top" align="center">X<br>
344      *       </td>
345      *     </tr>
346      *     <tr>
347      *       <td valign="top">visiblerows<br>
348      *       </td>
349      *       <td valign="top" align="center"><br>
350      *       </td>
351      *       <td valign="top" align="center"><br>
352      *       </td>
353      *       <td valign="top" align="center"><br>
354      *       </td>
355      *       <td valign="top" align="center"><br>
356      *       </td>
357      *       <td valign="top" align="center"><br>
358      *       </td>
359      *       <td valign="top" align="center">X<br>
360      *       </td>
361      *       <td valign="top" align="center"><br>
362      *       </td>
363      *       <td valign="top" align="center">X<br>
364      *       </td>
365      *     </tr>
366      *     <tr>
367      *       <td valign="top">len<br>
368      *       </td>
369      *       <td valign="top" align="center"><br>
370      *       </td>
371      *       <td valign="top" align="center"><br>
372      *       </td>
373      *       <td valign="top" align="center"><br>
374      *       </td>
375      *       <td valign="top" align="center"><br>
376      *       </td>
377      *       <td valign="top" align="center"><br>
378      *       </td>
379      *       <td valign="top" align="center"><br>
380      *       </td>
381      *       <td valign="top" align="center">X<br>
382      *       </td>
383      *       <td valign="top" align="center"><br>
384      *       </td>
385      *     </tr>
386      *     <tr>
387      *       <td valign="top">maxlen<br>
388      *       </td>
389      *       <td valign="top" align="center"><br>
390      *       </td>
391      *       <td valign="top" align="center"><br>
392      *       </td>
393      *       <td valign="top" align="center"><br>
394      *       </td>
395      *       <td valign="top" align="center"><br>
396      *       </td>
397      *       <td valign="top" align="center"><br>
398      *       </td>
399      *       <td valign="top" align="center"><br>
400      *       </td>
401      *       <td valign="top" align="center">X<br>
402      *       </td>
403      *       <td valign="top" align="center">X<br>
404      *       </td>
405      *     </tr>
406      *     <tr>
407      *       <td valign="top">minlen<br>
408      *       </td>
409      *       <td valign="top" align="center"><br>
410      *       </td>
411      *       <td valign="top" align="center"><br>
412      *       </td>
413      *       <td valign="top" align="center"><br>
414      *       </td>
415      *       <td valign="top" align="center"><br>
416      *       </td>
417      *       <td valign="top" align="center"><br>
418      *       </td>
419      *       <td valign="top" align="center"><br>
420      *       </td>
421      *       <td valign="top" align="center">X<br>
422      *       </td>
423      *       <td valign="top" align="center">X<br>
424      *       </td>
425      *     </tr>
426      *     <tr>
427      *       <td valign="top">init<br>
428      *       </td>
429      *       <td valign="top" align="center"><br>
430      *       </td>
431      *       <td valign="top" align="center"><br>
432      *       </td>
433      *       <td valign="top" align="center"><br>
434      *       </td>
435      *       <td valign="top" align="center"><br>
436      *       </td>
437      *       <td valign="top" align="center"><br>
438      *       </td>
439      *       <td valign="top" align="center"><br>
440      *       </td>
441      *       <td valign="top" align="center">X<br>
442      *       </td>
443      *       <td valign="top" align="center">X<br>
444      *       </td>
445      *     </tr>
446      *     <tr>
447      *       <td valign="top">allow<br>
448      *       </td>
449      *       <td valign="top" align="center"><br>
450      *       </td>
451      *       <td valign="top" align="center"><br>
452      *       </td>
453      *       <td valign="top" align="center"><br>
454      *       </td>
455      *       <td valign="top" align="center"><br>
456      *       </td>
457      *       <td valign="top" align="center"><br>
458      *       </td>
459      *       <td valign="top" align="center"><br>
460      *       </td>
461      *       <td valign="top" align="center">X<br>
462      *       </td>
463      *       <td valign="top" align="center">X<br>
464      *       </td>
465      *     </tr>
466      *     <tr>
467      *       <td valign="top">deny<br>
468      *       </td>
469      *       <td valign="top" align="center"><br>
470      *       </td>
471      *       <td valign="top" align="center"><br>
472      *       </td>
473      *       <td valign="top" align="center"><br>
474      *       </td>
475      *       <td valign="top" align="center"><br>
476      *       </td>
477      *       <td valign="top" align="center"><br>
478      *       </td>
479      *       <td valign="top" align="center"><br>
480      *       </td>
481      *       <td valign="top" align="center">X<br>
482      *       </td>
483      *       <td valign="top" align="center">X<br>
484      *       </td>
485      *     </tr>
486      *   </tbody>
487      * </table>
488      * <br>
489      */
490      
491    public abstract class Base extends BorderPanel {
492    
493      /**
494       * handle for main object.
495       */  
496      protected Main     main = null;
497    
498      /**
499       * handle for default font.
500       */  
501            protected Font     font = null;
502      
503      /**
504       * prefix used to distinguish different base objects
505       */  
506      protected String prefix = "";
507      
508      /**
509       * The contructor called from Main
510       *
511       * @param   m   handle for main object.
512       */  
513      public Base(Main m) {
514              this(m, "");
515      }
516    
517      /**
518       * The contructor called from other base object
519       *
520       * @param   m   handle for main object.
521       * @param   pf  prefix used to distinguish different base objects
522       */  
523      protected Base(Main m, String pf) {
524        main   = m;
525        font   = main.getFont();
526        prefix = pf;
527        
528        // inherit Colors from Main
529        setBackground(m.getBackground());
530        setForeground(m.getForeground());
531    
532        setTitle();
533        setHelptext(getStringP("tip", null));
534        
535        setAttr(this, "");  // set name, color, border & insets
536        
537        setMinimizable(getIntP("minimizable", 0) > 0);
538        if(getIntP("mini", 0) > 0) setMini(true);
539      }
540        
541      /**
542       * Convenience routines to get a String Property. 
543       * Returns "##ERR:<key>" on failure
544       *
545       * @param   key   key to use for lookup.
546       */  
547            protected String getString(String key) {
548        return getString(key, "##ERR:" + key);
549            }
550      
551      /**
552       * Convenience routines to get a String Property. 
553       *
554       * @param   key   key to use for lookup.
555       * @param   def   value to return on failure.
556       */  
557            protected String getString(String key, String def) {
558        main.setModule(getClass().getName());
559        String res = main.getString(key);
560        return res == null ? def : res;
561            }
562    
563      /**
564       * Convenience routines to get a String Property. Short for getString(prefix);
565       */  
566            protected String getStringP() {
567        return getString(prefix);
568            }
569      
570      /**
571       * Convenience routines to get a String Property. Short for getString(prefix + <key>);
572       *
573       * @param   key   key to use for lookup. Will be prefixed
574       */  
575            protected String getStringP(String key) {
576        return getString(prefix + key);
577            }
578      
579      /**
580       * Convenience routines to get a String Property. Short for getString(prefix + <key>, <def>);
581       *
582       * @param   key   key to use for lookup. Will be prefixed
583       * @param   def   value to return on failure.
584       */  
585            protected String getStringP(String key, String def) {
586        return getString(prefix + key, def);
587            }
588        
589      /**
590       * Convenience routines to get a Object Property.
591       *
592       * @param   key   key to use for lookup
593       */  
594            protected Object getObject(String key) {
595        return main.get(key);
596            }
597      
598      /**
599       * Convenience routines to get a Object Property. Short for getObject(prefix);
600       */  
601            protected Object getObjectP() {
602        return main.get(prefix);
603            }
604      
605      /**
606       * Convenience routines to get a Object Property. Short for getObject(prefix + <key>);
607       *
608       * @param   key   key to use for lookup
609       */  
610            protected Object getObjectP(String key) {
611        return main.get(prefix + key);
612            }
613      
614      /**
615       * Convenience routines to get a int Property.
616       * Returns 0 on failure
617       *
618       * @param   key   key to use for lookup
619       */  
620            protected int getInt(String key) {
621        return getInt(key, 0);
622      }
623      
624      /**
625       * Convenience routines to get a int Property.
626       *
627       * @param   key   key to use for lookup
628       * @param   def   value to return on failure.
629       */  
630            protected int getInt(String key, int def) {
631              try {
632          return Integer.parseInt(getString(key, "" + def));
633                    } catch(Exception x) {
634                      return def;
635                    }
636            }
637      
638      /**
639       * Convenience routines to get a int Property. Short for getInt(prefix);
640       */  
641            protected int getIntP() {
642        return getInt(prefix);
643      }
644      
645      /**
646       * Convenience routines to get a int Property. Short for getInt(prefix + <key>);
647       *
648       * @param   key   key to use for lookup. Will be prefixed
649       */  
650            protected int getIntP(String key) {
651        return getInt(prefix + key);
652      }
653      
654      /**
655       * Convenience routines to get a int Property. Short for getint(prefix + <key>, <def>);
656       *
657       * @param   key   key to use for lookup. Will be prefixed
658       * @param   def   value to return on failure.
659       */  
660            protected int getIntP(String key, int def) {
661        return getInt(prefix + key, def);
662      }
663    
664      /**
665       * Convenience routines to get a Stringarray Property.
666       * Returns empty array on failure
667       *
668       * @param   key   key to use for lookup. Will be prefixed
669       */  
670      protected String[] getStringArray(String key) {
671        return new StringSplitter(getString(key, null), ",").toArray();
672      }
673      
674      /**
675       * Convenience routines to get a Stringarray Property. Short for getStringArray(prefix)
676       */  
677      protected String[] getStringArrayP() {
678        return getStringArray(prefix);
679      }
680      
681      /**
682       * Convenience routines to get a Stringarray Property. Short for getStringArray(prefix + <key>)
683       *
684       * @param   key   key to use for lookup. Will be prefixed
685       */  
686      protected String[] getStringArrayP(String key) {
687        return getStringArray(prefix + key);
688      }
689    
690      /**
691       * Convenience routines to get an intarray Property.
692       * Returns empty array on failure
693       *
694       * @param   key   key to use for lookup. Will be prefixed
695       */  
696      protected int[] getIntArray(String key) {
697        String S[] = getStringArray(key); int I[] = new int[S.length];
698        for(int i = 0; i < S.length; ++ i) {
699                try { I[i] = Integer.parseInt(S[i]); } catch(Exception x) { I[i] = 0; }
700        }
701        return I;
702      }
703      
704      /**
705       * Convenience routines to get a intarray Property. Short for getIntArray(prefix)
706       */  
707      protected int[] getIntArrayP() {
708        return getIntArray(prefix);
709      }
710      
711      /**
712       * Convenience routines to get a intarray Property. Short for getIntArray(prefix + <key>)
713       *
714       * @param   key   key to use for lookup. Will be prefixed
715       */  
716      protected int[] getIntArrayP(String key) {
717        return getIntArray(prefix + key);
718      }
719      
720    
721      /**
722       * Convenience routine to put a variable in the main var bucket
723       *
724       * @param   key   key to use 
725       * @param   val   value to use 
726       */  
727      protected void putObject(String key, Object val) {
728        main.put(key, val);
729      }
730        
731      /**
732       * Convenience routine to put a variable in the main var bucket
733       * Short for putObject(prefix, <val>);
734       *
735       * @param   val   value to use 
736       */  
737      protected void putObjectP(Object val) {
738        putObject(prefix, val);
739      }
740      
741      /**
742       * Convenience routine to put a variable in the main var bucket
743       * Short for putObject(prefix + <key>, <val>);
744       *
745       * @param   key   key to use. Will be prefixed
746       * @param   val   value to use 
747       */  
748      protected void putObjectP(String key, Object val) {
749        putObject(prefix + key, val);
750      }
751      
752      /**
753       * Sets the title for this Panel
754       * Overwrite if you need something special
755       */  
756      protected void setTitle() {
757        setTitle(getStringP("label", null));
758      }
759        
760      /**
761       * Sets the attributes for component
762       * Usually used only internally for new... routines
763       *
764       * @param   c   the component
765       * @param   n   String to use for proerty lookups
766       */  
767      protected Component setAttr(Component c, String n) {
768        c.setName(n); 
769        c.setBackground(getColor(getStringP(n + "background")));
770        c.setForeground(getColor(getStringP(n + "foreground")));
771        if(c instanceof Awt) {
772          Awt a = (Awt) c;
773          a.setInsets(Array2Insets(getIntArrayP(n + "insets")));
774          a.setInnerInsets(Array2Insets(getIntArrayP(n + "innerinsets")));
775          a.setBorderType(getStringP(n + "bordertype", null));
776          a.setBorderDepth(getIntP(n + "borderdepth", -1));
777          String BG = getStringP(n + "img", null);
778          if(BG != null) {
779            setBG(BG);
780          }
781        }
782        return c;
783      }
784    
785      /**
786       * Sets the attributes for component. Like setAttr, but also adds
787       * a mouselistener for Tip popups
788       * Usually used only internally for new... routines
789       *
790       * @param   c   the component
791       * @param   n   String to use for property lookups
792       */  
793      protected Component setAttrTip(Component c, String n) {
794        c.addMouseListener(new Tip(getStringP(n + "tip", null)));
795        return setAttr(c, n);
796      }
797      
798      /**
799       * Adds Component to our container
800       * Usually used only internally for new... routines
801       *
802       * @param   c   the component to add
803       */  
804      protected Component addComp(Component c) {
805        add(c); return c;
806      }
807      
808      /**
809       * Creates a new Caption
810       *
811       * @param   n   String to use for property lookups
812       */  
813      protected Caption newCaption(String n) {
814        return (Caption) setAttrTip(new Caption(getStringP(n)), n);
815      }
816      
817      /**
818       * Adds a new Caption to our container
819       *
820       * @param   n   String to use for property lookups
821       */  
822      protected Caption addNewCaption(String n) {
823        return (Caption) addComp(newCaption(n));
824      }
825      
826      /**
827       * Creates a new Triage (Choice)
828       *
829       * @param   n   String to use for property lookups
830       */  
831      protected Triage newTriage(String n) {
832        return (Triage) setAttr(new Triage(getStringArrayP(n)), n);
833      }
834      
835      /**
836       * Adds a new Triage to our container
837       *
838       * @param   n   String to use for property lookups
839       */  
840      protected Triage addNewTriage(String n) {
841        return (Triage) addComp(newTriage(n));
842      }
843      
844      /**
845       * Creates a new Knob (Button)
846       *
847       * @param   n   String to use for property lookups
848       */  
849      protected Knob newKnob(String n) {
850        return (Knob) setAttr(new Knob(getStringP(n)), n);
851      }
852      
853      /**
854       * Adds a new Knob to our container
855       *
856       * @param   n   String to use for property lookups
857       */  
858      protected Knob addNewKnob(String n) {
859        return (Knob) addComp(newKnob(n));
860      }
861      
862      /**
863       * Creates a new Xbox (Checkbox)
864       *
865       * @param   n   String to use for property lookups
866       */  
867      protected Xbox newXbox(String n) {
868        return (Xbox) setAttr(new Xbox(getStringP(n)), n);
869      }
870      
871      /**
872       * Adds a new Xbox to our container
873       *
874       * @param   n   String to use for property lookups
875       */  
876      protected Xbox addNewXbox(String n) {
877        return (Xbox) addComp(newXbox(n));
878      }
879      
880      /**
881       * Creates a new MultiColumnList
882       *
883       * @param   n   String to use for property lookups
884       */  
885      protected MultiColumnList newMultiColumnList(String n) {
886        return (MultiColumnList) setAttr(new MultiColumnList(getStringArrayP(n + "header"), getIntP(n +"visiblecols", 4), getIntP(n +"minvisiblecols", 1), getIntP(n +"visiblerows", 5)), n);
887      }
888      
889      /**
890       * Adds a new MultiColumnList to our container
891       *
892       * @param   n   String to use for property lookups
893       */  
894      protected MultiColumnList addNewMultiColumnList(String n) {
895        return (MultiColumnList) addComp(newMultiColumnList(n));
896      }
897      
898      /**
899       * Creates a new EditField (single-line input)
900       *
901       * @param   n   String to use for property lookups
902       */  
903      protected EditField newEditField(String n) {
904        return (EditField) initEditComponent(n, new EditField(getIntP(n + "len", 10)));
905      }
906      
907      /**
908       * Adds a new EditField to our container
909       *
910       * @param   n   String to use for property lookups
911       */  
912      protected EditField addNewEditField(String n) {
913        return (EditField) addComp(newEditField(n));
914      }
915      
916      /**
917       * Creates a new EditArea (multi-line input)
918       *
919       * @param   n   String to use for property lookups
920       */  
921      protected EditArea newEditArea(String n) {
922        return (EditArea) initEditComponent(n, new EditArea("", getIntP(n + "visiblerows", 10), getIntP(n + "visiblecols", 78), TextArea.SCROLLBARS_VERTICAL_ONLY));
923      }
924      
925      /**
926       * Adds a new EditArea to our container
927       *
928       * @param   n   String to use for property lookups
929       */  
930      protected EditArea addNewEditArea(String n) {
931        return (EditArea) addComp(newEditArea(n));
932      }
933      
934      /**
935       * subroutine for newEditField/newEditArea to add attributes
936       * used only internally
937       *
938       * @param   n   String to use for property lookups
939       * @param   tc   the TextComponent to modify
940       */  
941      private Component initEditComponent(String n, AwtText tc) {
942        tc.setText(getStringP(n + "init", ""));
943        tc.addTextListener(new TextFilter(getStringP(n + "allow", ""), getStringP(n + "deny", ""), getIntP(n + "maxlen", 0)));
944        return setAttrTip(tc, n);
945      }
946      
947      /**
948       * returns true if MultiColumnList is empty
949       * pops up Dialog if msg != null
950       *
951       * @param   l   MultiColumnList to use 
952       * @param   msg   msg to popup if list is empty
953       */  
954      protected boolean checkEmpty(MultiColumnList l, String msg) {
955        return checkEmpty(l.getItem(0,0), msg, 1);
956      }
957      
958      /**
959       * returns true if TextComponent is empty
960       * pops up Dialog if msg != null
961       *
962       * @param   t   TextComponent to use 
963       * @param   msg   msg to popup if list is empty
964       */  
965      protected boolean checkEmpty(TextComponent t, String msg) {
966        return checkEmpty(t.getText(), msg, getIntP(t.getName() + "minlen", 1));
967      }
968      
969      /**
970       * returns true if String is shorter than minlen
971       * pops up Dialog if msg != null
972       *
973       * @param   t   TextComponent to use 
974       * @param   msg   msg to popup if list is empty
975       * @param   minlen   how long this string should be
976       */  
977      protected boolean checkEmpty(String s, String msg, int minlen) {
978        if(s.length() < minlen) {
979          if(msg != null) DialogBox.errorDialog(msg).show(this);
980          return true;
981        }
982        return false;
983      }
984    
985      /**
986       * Interface to Main(). Used in Applet Mode to notify us of stop/start
987       * Overwrite to receive these events
988       */  
989      public void stop() {
990      }
991      
992      /**
993       * Interface to Main(). Used in Applet Mode to notify us of stop/start
994       * Overwrite to receive these events
995       */  
996      public void start() {
997      }
998    }
999