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

Quick Search    Search Deep

Source code: org/maloi/evolvo/gui/DoubleField.java


1   /* Evolvo - Image Generator
2    * Copyright (C) 2000 Andrew Molloy
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU General Public License
6    * as published by the Free Software Foundation; either version 2
7    * of the License, or (at your option) any later version.
8   
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13  
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, write to the Free Software
16   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17   */
18  
19  /**
20   *  $Id: DoubleField.java,v 1.2 2002/10/07 15:20:21 maloi Exp $
21   */
22  
23  package org.maloi.evolvo.gui;
24  
25  import java.awt.event.ActionEvent;
26  import java.awt.event.ActionListener;
27  import java.awt.event.FocusEvent;
28  import java.awt.event.FocusListener;
29  
30  import javax.swing.JTextField;
31  import javax.swing.event.ChangeEvent;
32  import javax.swing.event.ChangeListener;
33  import javax.swing.text.AttributeSet;
34  import javax.swing.text.BadLocationException;
35  import javax.swing.text.Document;
36  import javax.swing.text.PlainDocument;
37  
38  /**
39   * Extends JTextField, allowing only numbers to be entered.
40   * These numbers may be floating point (double, specifically), but are 
41   * restricted to a specified range.
42   */
43  public class DoubleField
44     extends JTextField
45     implements ActionListener, ChangeListener, FocusListener
46  {
47     /** Range model used to determine valid values for the text field. */
48     DoubleBoundedRangeModel dbrm;
49     int precision;
50  
51     /** Default constructor. */
52     public DoubleField()
53     {
54        this(0.0, 0.0, 0.0, 1.0, 4, 6);
55     }
56  
57     /** Class constuctor that takes DoubleBoundedRandeModel's parameters 
58      *  individually, and a column width. 
59      */
60     public DoubleField(
61        double v,
62        double e,
63        double min,
64        double max,
65        int p,
66        int cols)
67     {
68        this(new DoubleBoundedRangeModel(v, e, min, max, p), cols);
69  
70        setPrecision(p);
71     }
72  
73     /** Class constuctor that takes DoubleBoundedRandeModel's parameters 
74      *  individually, setting a default column width. 
75      */
76     public DoubleField(double v, double e, double min, double max, int p)
77     {
78        this(new DoubleBoundedRangeModel(v, e, min, max, p), 6);
79  
80        setPrecision(p);
81     }
82  
83     /** Class constructor that takes a DoubleBoundedRangeModel and sets the 
84      *  column with to a default value. 
85      */
86     public DoubleField(DoubleBoundedRangeModel dm)
87     {
88        this(dm, 6);
89     }
90  
91     /** Class constructor which takes a DoubleBoundedRangeModel, and a column 
92      *  width. 
93      */
94     public DoubleField(DoubleBoundedRangeModel dm, int cols)
95     {
96        super(cols);
97        dbrm = dm;
98        addActionListener(this);
99        addChangeListener(this);
100 
101       setPrecision(dbrm.getPrecision());
102       setFieldText(Double.toString(dbrm.getDoubleValue()));
103       
104       addFocusListener(this);
105    }
106 
107    /** Creates a new DoubleDocument document model. */
108    protected Document createDefaultModel()
109    {
110       return new DoubleDocument();
111    }
112 
113    /** Handles all recieved ActionEvents. */
114    public void actionPerformed(ActionEvent e)
115    {
116       try
117       {
118          setValue(Double.parseDouble(getText()));
119          // Set the value to number in the text field.
120       }
121       catch (NumberFormatException ex)
122       {
123          select(0, getText().length());
124          // If the text field does not contain a valid number, reject the input and select all the text.
125       }
126    }
127 
128    public void setFieldText(String s)
129    {
130       int end = s.indexOf(".");
131       
132       if (end == -1)
133       {
134          end = s.length();
135       }
136       else
137       {
138          end += precision;
139          
140          if (precision != 0)
141          {
142             end++;
143          }
144          
145          if (end > s.length())
146          {
147             end = s.length();
148          }
149       }
150       
151       s = s.substring(0, end);
152             
153       setText(s);
154    }
155 
156    /** Handles all recieved ChangeEvents. */
157    public void stateChanged(ChangeEvent e)
158    {
159       setValue(dbrm.getDoubleValue());
160       
161       setFieldText(Double.toString(dbrm.getDoubleValue()));
162    }
163 
164    /** Returns the current value of the text field as a double. */
165    public double getValue()
166    {
167       return dbrm.getDoubleValue();
168    }
169 
170    /** Sets the value of the text field from a double. */
171    public void setValue(double newValue)
172    {
173       double oldValue = dbrm.getDoubleValue();
174       dbrm.setDoubleValue(newValue);
175       newValue = dbrm.getDoubleValue();
176 
177       setFieldText(Double.toString(newValue));
178       
179       select(0, getText().length()); // Select the entire text field.
180 
181       firePropertyChange("value", oldValue, dbrm.getDoubleValue());
182    }
183 
184    /** Adds a ChangeListener. */
185    public void addChangeListener(ChangeListener l)
186    {
187       dbrm.addChangeListener(l);
188    }
189 
190    /** Removes a ChangeListener. */
191    public void removeChangeListener(ChangeListener l)
192    {
193       dbrm.removeChangeListener(l);
194    }
195 
196    /** Defines a document model that restricts input to characters which may 
197     *  be used to define a double. 
198     */
199    static class DoubleDocument extends PlainDocument
200    {
201       /** The acceptable characters. */
202       byte[] validChars = new String("eE-+.0123456789").getBytes();
203       /** The number of acceptable characters. */
204       int vcLength = validChars.length;
205 
206       /** Insert the given String into the document iff it is valid.
207         * @throws BadLocationException
208         */
209       public void insertString(int offset, String str, AttributeSet a)
210          throws BadLocationException
211       {
212          byte[] strArray = str.getBytes();
213          boolean valid = true;
214 
215          for (int strIndex = 0; strIndex < strArray.length; strIndex++)
216          {
217             boolean internalValid = false;
218             for (int vcIndex = 0; vcIndex < vcLength; vcIndex++)
219             {
220                if (strArray[strIndex] == validChars[vcIndex])
221                {
222                   internalValid = true;
223                   vcIndex = vcLength;
224                }
225             }
226             if (internalValid == false)
227             {
228                valid = false;
229                strIndex = strArray.length;
230             }
231          }
232          if (!valid)
233          {
234             return;
235          }
236          super.insertString(offset, str, a);
237       }
238    }
239    
240    public void setPrecision(int p)
241    {
242       precision = p;
243 
244       dbrm.setPrecision(p);
245    }
246    
247    public void focusGained(FocusEvent e)
248    {
249    }
250 
251    public void focusLost(FocusEvent e)
252    {
253       // Set our value when we lose focus
254       setValue(Double.parseDouble(getText()));
255    }
256 }