1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package zeus.gui.fields;
25
26 import java.awt.Toolkit;
27 import java.awt.event.*;
28 import javax.swing.*;
29 import javax.swing.text.*;
30 import javax.swing.event.*;
31
32
33 public class RealNumberField extends JTextField
34 implements FocusListener, DocumentListener {
35
36 protected static char MINUS = '-';
37 protected static char PERIOD = '.';
38 protected EventListenerList changeListeners = new EventListenerList();
39 protected double min;
40 protected double max;
41 protected boolean range_check = false;
42 protected boolean range_checked = false;
43
44 public RealNumberField() {
45 super();
46 }
47 public RealNumberField(double min, double max) {
48 this();
49 this.min = min;
50 this.max = max;
51 range_check = true;
52 this.addFocusListener(this);
53 }
54
55 public void focusGained(FocusEvent evt) {
56 }
57 public void focusLost(FocusEvent evt) {
58 if ( range_check && !range_checked ) {
59 range_checked = true;
60 try {
61 double value = (Double.valueOf(getText())).doubleValue();
62 if ( value < min || value > max ) {
63 errorMsg();
64 return;
65 }
66 }
67 catch(NumberFormatException e) {
68 errorMsg();
69 return;
70 }
71 }
72 }
73
74 public void setText(Double obj) {
75 setText(obj.toString());
76 }
77 public void setText(Integer obj) {
78 setText(obj.toString());
79 }
80 public void setText(Long obj) {
81 setText(obj.toString());
82 }
83
84 protected void errorMsg() {
85 JOptionPane.showMessageDialog(this,
86 "Illegal entry\nValue must be between " + min + " and " +
87 max + " inclusive","Error", JOptionPane.ERROR_MESSAGE);
88 }
89
90 public void setValue(double value) {
91 if ( range_check ) {
92 if ( value < min || value > max ) {
93 errorMsg();
94 return;
95 }
96 }
97 setText(Double.toString(value));
98 }
99
100 public Double getValue() {
101 try {
102 return new Double(getText());
103 }
104 catch(NumberFormatException e) {
105 return null;
106 }
107 }
108
109 public Double getValue(double def) {
110 try {
111 return new Double(getText());
112 }
113 catch(NumberFormatException e) {
114 return new Double(def);
115 }
116 }
117
118 protected Document createDefaultModel() {
119 Document doc = new RealNumberFieldDocument();
120 doc.addDocumentListener(this);
121 return doc;
122 }
123
124 public void insertUpdate(DocumentEvent e) {
125 range_checked = false;
126 fireChanged();
127 }
128 public void removeUpdate(DocumentEvent e) {
129 range_checked = false;
130 fireChanged();
131 }
132 public void changedUpdate(DocumentEvent e) {
133 range_checked = false;
134 fireChanged();
135 }
136
137 static char[] numberSet = {
138 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
139 };
140
141 class RealNumberFieldDocument extends PlainDocument {
142 public void insertString(int offs, String str, AttributeSet a)
143 throws BadLocationException {
144
145 if ( str == null ) return;
146 str = str.trim();
147
148 int length = getLength();
149 String buf = getText(0,offs) + str + getText(offs,length-offs);
150 buf = buf.trim();
151 char[] array = buf.toCharArray();
152
153 if ( array.length > 0 ) {
154 if ( array[0] != MINUS && !member(array[0],numberSet) &&
155 array[0] != PERIOD ) {
156 Toolkit.getDefaultToolkit().beep();
157 return;
158 }
159 }
160
161 boolean period_found = (array.length > 0 && array[0] == PERIOD);
162
163 for(int i = 1; i < array.length; i++ ) {
164 if ( !member(array[i],numberSet) ) {
165 if ( !period_found && array[i] == PERIOD ) {
166 period_found = true;
167 }
168 else {
169 Toolkit.getDefaultToolkit().beep();
170 return;
171 }
172 }
173 }
174 super.insertString(offs,str,a);
175 }
176 }
177 static boolean member(char item, char[] array) {
178 for(int i = 0; i < array.length; i++ )
179 if ( array[i] == item ) return true;
180 return false;
181 }
182
183
184
185
186 public void addChangeListener(ChangeListener x) {
187 changeListeners.add(ChangeListener.class, x);
188 }
189
190 public void removeChangeListener(ChangeListener x) {
191 changeListeners.remove(ChangeListener.class, x);
192 }
193
194 protected void fireChanged() {
195 ChangeEvent c = new ChangeEvent(this);
196 Object[] listeners = changeListeners.getListenerList();
197 for(int i= listeners.length-2; i >= 0; i -=2) {
198 if (listeners[i] == ChangeListener.class) {
199 ChangeListener cl = (ChangeListener)listeners[i+1];
200 cl.stateChanged(c);
201 }
202 }
203 }
204 }