Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/flexstor/common/awt/field/FlexChoice.java


1   /*
2    * FlexChoice.java
3    *
4    * Copyright $Date: 2003/08/11 02:22:44 $ FLEXSTOR.net Inc.
5    *
6    * This work is licensed for use and distribution under license terms found at
7    * http://www.flexstor.org/license.html
8    *
9    */
10  
11  package com.flexstor.common.awt.field;
12  
13  import java.awt.Choice;
14  import java.awt.Color;
15  import java.awt.Component;
16  import java.awt.Dimension;
17  import java.awt.FontMetrics;
18  import java.awt.Frame;
19  import java.awt.event.ItemEvent;
20  import java.awt.event.ItemListener;
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  import java.util.Vector;
24  
25  import com.flexstor.common.awt.dialogs.MessageBox;
26  import com.flexstor.common.awt.event.FlexTextEvent;
27  import com.flexstor.common.awt.event.FlexTextListener;
28  import com.flexstor.common.disguise.LookupListItem;
29  import com.flexstor.common.parsers.ValidatorI;
30  
31  /**
32   * FlexChoice extends choice by providing for:
33   *   1.  The ability to add a list of items at one time with the construstor.
34   *   2.  The setItems() method which clears the choice and adds a list of items.
35   *   3.  Auto padding automatically handled.  This means that the first item in the choice is
36   *       always a space.  This option must be selected in the constructor.
37   *   4.  Keeping an associated id to each item value in the list of choices.
38   */
39  public class FlexChoice
40     extends Choice
41     implements ItemListener, ComponentI
42  {
43     /** The preferred length of the items in this choice. */
44     private int nMaxLength;
45  
46     /** If set to false, then this choice does not support tabbing. */
47     private boolean bTabbable;
48  
49     /** A string with a single space is added as the first item to the choice when true. */
50     private boolean bPadChoice;
51  
52     /** Text Listeners -- used for filtering of text events. */
53     private Vector textListeners;
54  
55     private boolean bRequired;
56     
57     /** The currently valid selected item.  May differ from actual selected value when between textValueChangeBegin()
58         and textValueChangeEnd() processing. */   
59     private String sLastValue   = "";
60     private long   nLastValueId = -1;;
61  
62     /** The list of lookup items (value,id pairs) for this choice. */
63     private ArrayList alItems = null;
64     
65     private static FontMetrics metrics = null;
66     
67     /**
68      * Creates an empty FlexChoice.
69      */
70     public FlexChoice()
71     {
72        this( "", new ArrayList(), false );
73     }
74  
75     /**
76      * Creates a new FlexChoice containing the items saItems.
77      * @param alItems the items values and ids to add to the choice.
78      */
79     public FlexChoice( ArrayList alItems )
80     {
81        this( "", alItems, false );
82     }
83  
84     /**
85      * Creates a new FlexChoice containing the items saItems.
86      * @param saItems the items values to add to the choice. The values ids will be set to -1.
87      */
88     public FlexChoice( String[] saItems )
89     {
90        this( "", saItems, false );
91     }
92  
93     /**
94      * Creates a new FlexChoice with the name sName and containing the items saItems.
95      * @param bPadChoice Padding automatically handled if true.
96      */
97     public FlexChoice( boolean bPadChoice )
98     {
99        this( "", new ArrayList(), bPadChoice );
100    }
101 
102    /**
103     * Creates a new FlexChoice with the name sName and containing the items saItems.
104     * @param sName the name of this choice.
105     * @param saItems the items values to add to the choice. The values ids will be set to -1.
106     * @param bPadChoice Padding automatically handled if true.
107     */
108    public FlexChoice( String sName, String[] saItems, boolean bPadChoice )
109    {
110       super();
111 
112       setName( sName );
113     setForeground( Color.black );
114     setBackground( Color.white );
115 
116       textListeners = new Vector( 1, 1 );
117       addItemListener( this );
118 
119       this.alItems    = new ArrayList();
120       this.bPadChoice = bPadChoice;
121 
122       setItems( saItems );
123 
124       setFocusTraversable( true );
125    }
126    
127    /**
128     * Creates a new FlexChoice with the name sName and containing the items saItems.
129     * @param sName the name of this choice.
130     * @param alItems the lookup items values and ids to add to the choice.
131     * @param bPadChoice Padding automatically handled if true.
132     */
133    public FlexChoice( String sName, ArrayList alItems, boolean bPadChoice )
134    {
135       super();
136 
137       setName( sName );
138     setForeground( Color.black );
139     setBackground( Color.white );
140 
141       textListeners = new Vector( 1, 1 );
142       addItemListener( this );
143 
144       this.alItems    = new ArrayList();
145       this.bPadChoice = bPadChoice;
146 
147       setItems( alItems );
148 
149       setFocusTraversable( true );
150    }
151 
152    /**
153     * Configures the validator field.
154     * @param bEditable will this field be editable.
155     * @param bRequired will the user be required to enter data in this field.
156     * @param sLabel the name that is used in error messages for vaildation.
157     */
158    public void configure( boolean bEditable, boolean bRequired, String sLabel, String[] saItems )
159    {
160       ArrayList alItems = new ArrayList();
161       if ( saItems != null )
162       {
163          for ( int i = 0; i < saItems.length; i++ )
164             alItems.add( new LookupListItem( saItems[i], -1 ) );
165       }
166       
167       configure( bEditable, bRequired, sLabel, alItems );
168    }
169 
170    /**
171     * Configures the validator field.
172     * @param bEditable will this field be editable.
173     * @param bRequired will the user be required to enter data in this field.
174     * @param sLabel the name that is used in error messages for vaildation.
175     */
176    public void configure( boolean bEditable, boolean bRequired, String sLabel, ArrayList alItems )
177    {
178       setEnabled( bEditable );
179       setRequired( bRequired );
180       setName( sLabel );
181 
182       setItems( alItems );
183 
184       clear( false );
185    }
186 
187    /**
188     *
189     */
190    public void addItem( String sItem )
191    {
192       addItem( new LookupListItem( sItem, -1 ) );
193    }
194 
195    /**
196     *
197     */
198    public void addItem( LookupListItem item )
199    {
200       if ( item != null && item.getValue() != null )
201       {
202          alItems.add( item );
203          super.addItem( item.getValue() );
204       
205          if ( metrics != null )
206              nMaxLength = Math.max( metrics.stringWidth( item.getValue() ), nMaxLength );
207       }
208    }
209 
210    /**
211     * Adds an array of items to the choice.
212     * @param saItems The array of items to add.
213     */
214    public void setItems( String[] saItems )
215    {
216       ArrayList alItems = new ArrayList();
217       if ( saItems != null )
218       {
219          for ( int i = 0; i < saItems.length; i++ )
220             alItems.add( new LookupListItem( saItems[i], -1 ) );
221       }
222 
223       setItems( alItems );
224    }
225 
226    /**
227     * Adds an array of items to the choice.
228     * @param alItems the items ( values and ids ) to be added to the choices list.
229     */
230    public void setItems( ArrayList alItems )
231    {
232       removeAll();
233 
234       if ( bPadChoice )
235          addItem( " " );
236 
237       if ( alItems != null && alItems.size() > 0 )
238       {
239          Iterator itItems = alItems.iterator();
240          while ( itItems.hasNext() )
241             addItem( (LookupListItem)itItems.next() );
242       }
243 
244       if ( this.alItems.size() > 0 )
245       {
246          sLastValue   = ( (LookupListItem)this.alItems.get( 0 ) ).getValue();
247          nLastValueId = ( (LookupListItem)this.alItems.get( 0 ) ).getLookupRecordId();
248       }
249       else
250       {
251          sLastValue   = "";
252          nLastValueId = -1;
253       }
254    }
255 
256    /**
257     *
258     */
259    public void removeAll()
260    {
261       nMaxLength = 0;
262 
263       super.removeAll();
264       alItems.clear();
265    }
266 
267    /**
268     *
269     */
270    public void insert( String sItem, int index )
271    {
272       alItems.add( index, new LookupListItem( sItem, -1 ) );
273       super.insert( sItem, index );
274 
275       if ( metrics != null )
276          nMaxLength = Math.max ( metrics.stringWidth( sItem ), nMaxLength );
277    }  
278 
279    /**
280     *
281     */
282    public void insert( LookupListItem item, int index )
283    {
284       alItems.add( index, item );
285       super.insert( item.getValue(), index );
286 
287       if ( metrics != null )
288          nMaxLength = Math.max ( metrics.stringWidth( item.getValue() ), nMaxLength );
289    }  
290 
291    /**
292     * Selects the first item in the choice.
293     * @param bNotify Sends an edit ActionEvent to all listeners if true.
294     */
295    public void clear( boolean bNotify )
296    {
297       select( 0 );
298 
299       if ( bNotify )
300          itemStateChanged( null );
301    }
302 
303    /**
304     *
305     */
306    public void cleanup()
307    {
308       removeAll();
309 
310       textListeners.removeAllElements();
311       textListeners = null;
312 
313       metrics = null;
314    }
315 
316    /**
317     *
318     */
319    public void addNotify()
320    {
321       super.addNotify();
322       
323       metrics = getFontMetrics( getFont() );
324       for ( int i = 0; i < getItemCount(); i++ )
325           nMaxLength = Math.max( metrics.stringWidth( getItem( i ) ), nMaxLength );
326    }     
327 
328    /**
329     * Sets the focusTraversable function.
330     * @param bState this choice supports tabbing if true.
331     */
332    public void setFocusTraversable( boolean bState )
333    {
334       bTabbable = bState;
335    }
336 
337    /**
338     * Overides isFocusTraversable in java.awt.Component.
339     * This choice supports tabbing only if it is enabled, showing on the
340     * screen, and setFocusTraversable(false) was not called.
341     */
342    public boolean isFocusTraversable()
343    {
344       return isEnabled() && isShowing() && bTabbable;
345    }
346 
347    /**
348     *
349     */
350    public void itemStateChanged ( ItemEvent ie )
351    {
352       synchronized ( textListeners )
353       {
354          FlexTextEvent e = new FlexTextEvent( this, 0, 0, "" );
355          for ( int i = 0; i < textListeners.size(); i++ )
356             ( (FlexTextListener)textListeners.elementAt( i ) ).textValueChangeBegin( e );
357             
358          // Check if the change was aborted...
359          if ( !e.getAllowChange() )
360          {
361             setText( sLastValue );
362             return;
363          }
364 
365          sLastValue = getText();
366 
367          e = new FlexTextEvent( this, 0, 0, "" );
368          for ( int i = 0; i < textListeners.size(); i++ )
369             ( (FlexTextListener)textListeners.elementAt( i ) ).textValueChangeEnd( e );
370       }
371    }
372 
373    /**
374     * Returns true if this choice is enabled.
375     * @return true if this choice is enabled.
376     */
377    public boolean getEnabled()
378    {
379       return isEnabled();
380    }
381 
382    /**
383     * Sets the contents of the upper part of the choice.  Automatically handles padding.
384     * @sText the new value.
385     */
386    public void setText( String sText )
387    {
388       if ( bPadChoice && sText.trim().equals( "" ) )
389          sText = " ";
390 
391       select( sText );
392    }
393 
394    /**
395     * Returns the contents of the upper part of the choice.  Automatically handles padding.
396     * @return the contents of the choice.
397     */
398    public String getText()
399    {
400       if ( bPadChoice && getSelectedIndex() == 0 )
401          return "";
402       else
403          return getSelectedItem();
404    }
405 
406    /**
407     *
408     */
409    public void setId( long nId )
410    {
411       int      i       = -1;
412       Iterator itItems = alItems.iterator();
413       for ( i = 0; itItems.hasNext(); i++ )
414       {
415          if ( ( (LookupListItem)itItems.next() ).getLookupRecordId() == nId )
416             break;
417       }
418    
419       select( i );
420    }
421 
422    /**
423     *
424     */
425    public long getId()
426    {
427       return ( (LookupListItem)alItems.get( getSelectedIndex() ) ).getLookupRecordId();
428    }
429 
430    /**
431     *
432     */
433    public synchronized void select( int pos )
434    {
435       sLastValue   = getItem( pos );
436       nLastValueId = ( (LookupListItem)alItems.get( pos ) ).getLookupRecordId();
437       
438       super.select( pos );
439    }
440  
441    /**
442     *
443     */
444    public synchronized void select( String str )
445    {
446       sLastValue = str;
447 
448       LookupListItem item    = null;
449       Iterator         itItems = alItems.iterator();
450       while ( itItems.hasNext() )
451       {
452          item = (LookupListItem)itItems.next();
453          if ( item.getValue().equals( str ) )
454          {
455             nLastValueId = item.getLookupRecordId();
456             break;
457          }
458       }
459       
460       super.select( str );
461    }
462 
463    /**
464     *
465     */
466    public boolean verify( boolean bCheckRequired )
467    {
468       // Check required.
469       if ( bCheckRequired && isBlank() && bRequired )
470       {
471          MessageBox.showMessageDialog ( getParentFrame(), 5792, MessageBox.OK, getName() );
472          requestFocus();
473          return false;
474       }
475 
476       return true;
477    }
478 
479    /**
480     *
481     */
482    private Frame getParentFrame()
483    {
484       Component c = this;
485 
486       do
487       {
488          c = c.getParent();
489       }
490       while ( c != null && !(c instanceof Frame) );
491 
492       return (Frame)c;
493    }
494 
495    /** Not implemented until this choice supports editing. */
496    public void formatCase ( )
497    {
498    }
499 
500    /** Not implemented until this choice supports editing. */
501    public void setCustomValidator ( ValidatorI validator )
502    {
503    }
504 
505    /**
506     *
507     */
508    public boolean quietVerify()
509    {
510       return !(isBlank() && bRequired);
511    }
512 
513    /**
514     *
515     */
516    public boolean isBlank()
517    {
518       if ( bPadChoice )
519          return ( getSelectedIndex() == 0 );
520       else
521          return false;
522    }
523 
524    /**
525     *
526     */
527    public boolean isRequired ( )
528    {
529       return bRequired;
530    }
531 
532    /**
533     *
534     */
535    public void setRequired ( boolean bRequired )
536    {
537       this.bRequired = bRequired;
538    }
539    
540    /**
541     *
542     */
543    public Dimension getMinimumSize ( )
544    {
545       return getPreferredSize();
546    }
547 
548    /**
549     *
550     */
551    public Dimension getPreferredSize ( )
552    {
553       return new Dimension ( nMaxLength + 40, ComponentI.COMPONENT_HEIGHT );
554    }
555 
556    /**
557     *
558     */
559    public synchronized void addTextListener ( FlexTextListener l )
560    {
561       textListeners.addElement ( l );
562    }
563 
564    /**
565     *
566     */
567    public synchronized void removeTextListener ( FlexTextListener l )
568    {
569       if ( textListeners.contains ( l ) )
570          textListeners.removeElement ( l );
571    }
572 
573 }