001    package util.swing;
002    
003    import javax.swing.event.DocumentEvent;
004    import javax.swing.event.DocumentListener;
005    
006    /**
007     * Input field for integers.
008     * 
009     * <p>This input field lets you define the following parameters:
010     * <ul>
011     * <li><b>Default value:</b> This value will be taken as well in the beginning
012     *     as every time when an error occurs.</li>
013     * <li><b>Minimum value:</b> This value will be taken whenever the input is
014     *     below it.</li>
015     * <li><b>Maximum value:</b> This value will be taken whenever the input is
016     *     above it.</li>
017     * </ul>
018     * </p>
019     * 
020     * <p>You can define an Integer object as observer. Therefore you have to give
021     * it to the constructor via an array:<br /><br />
022     * <tt>int[] iaObserver = { new int[0] };<br />
023     * JIntInput = new JIntInput(iaObserver, 2500, 1900, 2300);</tt>
024     * <br /><br />
025     * If you do not wish to use an observer, simply set it to <code>null</code>. 
026     * </p>
027     *  
028     * <p>The control's behaviour is quite easy: As long as the component has the
029     * focus, you can type in <i>any</i> valid integer (if it is in the integer
030     * range of Java). Only when the control looses the focus, a range check is
031     * performed. Then, if the input is below the minimum value, it will be set
032     * to it. The same goes with the maximum value.
033     * </p>
034     *  
035     * @author   Thomas Ryssel
036     * @version  3.2
037     * @since    3.2 2006-03-18
038     */
039    public class JIntInput extends JFilterInput {
040            
041            /**
042             * ID for serialization.
043             */
044            private static final long serialVersionUID = 3791819523855330606L;
045    
046            /**
047             * The observer. Whenever a valid value is entered, this will be
048             * canged, too.
049             */
050            private int[] m_iObserver;
051            
052            /**
053             * Lower range bound. If the value in the input is below this when
054             * exiting the control, it will be set to this.
055             */
056            private int m_iMinimum;
057            
058            /**
059             * Upper range bound. If the value in the input is higher than this when
060             * exiting the control, it will be set to this.
061             */
062            private int m_iMaximum;
063            
064            /**
065             * Default value. Will be applied in the beginning and whenever the input
066             * is invalid when exiting the control. 
067             */
068            private int m_iDefault;
069            
070            
071            /**
072             * Creates a JIntInput object without ranges, a default value of 0
073             * and without an observer.
074             */
075            public JIntInput() {
076                    this(null, 0, Integer.MIN_VALUE, Integer.MAX_VALUE);
077            }
078            
079            /**
080             * Creates a JIntInput object according to the given parameters.
081             * 
082             * @param observer The observer of the input value. Content will always
083             *                 be written into the first element of the array. Can
084             *                 be <tt>null</tt> if you wish no observer.
085             */
086            public JIntInput(int[] observer) {
087                    this(observer, 0, Integer.MIN_VALUE, Integer.MAX_VALUE);
088            }
089            
090            /**
091             * Creates a JIntInput object according to the given parameters.
092             * 
093             * @param observer The observer of the input value. Content will always
094             *                 be written into the first element of the array. Can
095             *                 be <tt>null</tt> if you wish no observer.
096             * @param def      The default value.
097             */
098            public JIntInput(int[] observer, int def) {
099                    this(observer, def, Integer.MIN_VALUE, Integer.MAX_VALUE);
100            }
101            
102            /**
103             * Creates a JIntInput object according to the given parameters. 
104             * 
105             * @param observer The observer of the input value. Content will always
106             *                 be written into the first element of the array. Can
107             *                 be <tt>null</tt> if you wish no observer.
108             * @param def      The default value.
109             * @param min      The minimum value.
110             * @param max      The maximum value.
111             */
112            public JIntInput(int[] observer, int def, int min, int max) {
113                    super();
114                    
115                    m_iObserver = observer;
116                    m_iDefault = def;
117                    m_iMinimum = min;
118                    m_iMaximum = max;
119                    
120                    setHorizontalAlignment(RIGHT);
121                    
122                    getDocument().addDocumentListener(new DocumentListener() {
123                            public void insertUpdate(DocumentEvent e) {
124                                    if (m_iObserver == null || m_iObserver.length < 1) {
125                                            return;
126                                    }
127                                    
128                                    String sText = getText();
129                                    if (sText != "") {
130                                            try {
131                                                    m_iObserver[0] = Integer.parseInt(sText);
132                                            } catch(Exception ex) {
133                                                    m_iObserver[0] = m_iDefault;
134                                            }
135                                    } else {
136                                            m_iObserver[0] = 0;
137                                    }
138                                    
139                            }
140    
141                            public void removeUpdate(DocumentEvent e) {
142                                    insertUpdate(e);
143                            }
144    
145                            public void changedUpdate(DocumentEvent e) {
146                                    insertUpdate(e);
147                            }
148                            
149                    });
150                    
151                    setFilter(new InputFilter() {
152                            public boolean allowEditing(String value) {
153                                    try {
154                                            Integer.parseInt(value);
155                                    } catch (Exception ex) {
156                                            if (value.equals("")  || value.equals("-")) {
157                                                    return true;
158                                            }
159                                            return false;
160                                    }
161                                    if (value.indexOf(' ') > -1) {
162                                            return false;
163                                    }
164                                    return true;
165                            }
166    
167                            public String validExit(String value) {
168                                    Integer i = new Integer(0);
169                                    try {
170                                            i = new Integer(value);
171                                    } catch (Exception ex) {
172                                            if (!value.equals("") && !value.equals("-")) {
173                                                    return String.valueOf(m_iDefault);
174                                            }
175                                    }
176                                    if (i < m_iMinimum) {
177                                            return String.valueOf(m_iMinimum);
178                                    }
179                                    if (i > m_iMaximum) {
180                                            return String.valueOf(m_iMaximum);
181                                    }
182                                    return i.toString();
183                            }
184                    });
185                    
186                    setText(Integer.toString(m_iDefault));
187            }
188    }