View Javadoc

1   /*
2    * MicroEmulator 
3    * Copyright (C) 2001 Bartek Teodorczyk <barteo@barteo.net>
4    * 
5    * This library is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as published by the
7    * Free Software Foundation; either version 2.1 of the License, or (at your
8    * option) any later version.
9    * 
10   * This library is distributed in the hope that it will be useful, but WITHOUT
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13   * for more details.
14   * 
15   * You should have received a copy of the GNU Lesser General Public License
16   * along with this library; if not, write to the Free Software Foundation,
17   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18   * 
19   * Contributor(s): 
20   *   3GLab
21   *   Robert Helmer
22   */
23  
24  package javax.microedition.lcdui;
25  
26  import org.microemu.device.DeviceFactory;
27  import org.microemu.device.InputMethod;
28  import org.microemu.device.InputMethodEvent;
29  import org.microemu.device.InputMethodListener;
30  
31  public class TextField extends Item 
32  {
33  	public static final int ANY = 0;
34  	public static final int EMAILADDR = 1;
35  	public static final int NUMERIC = 2;
36  	public static final int PHONENUMBER = 3;
37  	public static final int URL = 4;	
38  	public static final int DECIMAL = 5;
39  
40  	public static final int PASSWORD = 0x10000;
41  	public static final int UNEDITABLE = 0x20000;
42  	public static final int SENSITIVE = 0x40000;
43  	public static final int NON_PREDICTIVE = 0x80000;
44  	public static final int INITIAL_CAPS_WORD = 0x100000;
45  	public static final int INITIAL_CAPS_SENTENCE = 0x200000;
46  	
47  	public static final int CONSTRAINT_MASK = 0xffff;
48  
49  	StringComponent stringComponent;
50  	
51  	private String field;
52  	private int caret;
53  	private boolean caretVisible;
54  	private int maxSize;
55  	private int constraints;
56  
57  	private InputMethodListener inputMethodListener = new InputMethodListener() 
58  	{
59  		public void caretPositionChanged(InputMethodEvent event) 
60  		{
61  			setCaretPosition(event.getCaret());
62  			setCaretVisible(true);
63  			repaint();
64  		}
65  
66  		public void inputMethodTextChanged(InputMethodEvent event) 
67  		{
68  			setCaretVisible(false);
69  			setString(event.getText(), event.getCaret());
70  			repaint();
71              
72              if (owner instanceof Form) {
73                  ((Form) owner).fireItemStateListener();
74              }
75  		}
76  
77  		public int getCaretPosition()
78  		{
79  			return TextField.this.getCaretPosition();
80  		}
81  
82  		public String getText()
83  		{
84  			return TextField.this.getString();
85  		}
86  
87  		public int getConstraints()
88          {
89              return TextField.this.getConstraints();
90          }
91  	};
92  
93  	
94  	public TextField(String label, String text, int maxSize, int constraints) 
95  	{
96  		super(label);
97  		if (maxSize <= 0) {
98  			throw new IllegalArgumentException();
99  		}
100 		setConstraints(constraints);
101         if (!InputMethod.validate(text, constraints)) {
102             throw new IllegalArgumentException();
103         }
104 		this.maxSize = maxSize;
105 		stringComponent = new StringComponent();
106 		if (text != null) {
107 			setString(text);
108 		} else {
109 			setString("");
110 		}
111 		stringComponent.setWidthDecreaser(8);
112 	}
113 
114 	
115 	public String getString() 
116 	{
117 		return field;
118 	}
119 
120 	
121 	public void setString(String text) 
122 	{
123         setString(text, text.length());
124 	}
125     
126     
127     void setString(String text, int caret)
128     {
129         if (!InputMethod.validate(text, constraints)) {
130             throw new IllegalArgumentException();
131         }
132         if (text == null) {
133             field = "";
134             stringComponent.setText("");
135         } else {
136             if (text.length() > maxSize) {
137                 throw new IllegalArgumentException();
138             }
139             field = text;
140             if ((constraints & PASSWORD) == 0) {
141                 stringComponent.setText(text);
142             } else {
143                 StringBuffer sb = new StringBuffer();
144                 for (int i = 0; i < text.length(); i++) {
145                     sb.append('*');
146                 }
147                 stringComponent.setText(sb.toString());
148             }
149         }
150         setCaretPosition(caret);
151         setCaretVisible(false);
152         repaint();
153     }
154 
155 	
156 	public int getChars(char[] data) 
157 	{
158 		if (data.length < field.length()) {
159 			throw new ArrayIndexOutOfBoundsException();
160 		}
161 		getString().getChars(0, field.length(), data, 0);
162 
163 		return field.length();
164 	}
165 
166 	
167 	public void setChars(char[] data, int offset, int length) 
168 	{
169 		if (data == null) {
170 			setString("");
171 		} else {
172 			if (length > maxSize) {
173 				throw new IllegalArgumentException();
174 			}
175 			String newtext = new String(data, offset, length);
176 			if (!InputMethod.validate(newtext, constraints)) {
177                 throw new IllegalArgumentException();
178             }
179 			setString(newtext);
180 		}
181 		repaint();
182 	}
183 
184 	
185 	public void insert(String src, int position) 
186 	{
187 		if (!InputMethod.validate(src, constraints)) {
188             throw new IllegalArgumentException();
189         }
190 		if (field.length() + src.length() > maxSize) {
191 			throw new IllegalArgumentException();
192 		}
193 		String newtext = "";
194 		if (position > 0) {
195 			newtext = getString().substring(0, position);
196 		}
197 		newtext += src;
198 		if (position < field.length()) {
199 			newtext += getString().substring(position + 1);
200 		}
201 		setString(newtext);
202 		repaint();
203 	}
204 
205 	
206 	public void insert(char[] data, int offset, int length, int position) 
207 	{
208 		if (offset + length > data.length) {
209 			throw new ArrayIndexOutOfBoundsException();
210 		}
211 		insert(new String(data, offset, length), position);
212 	}
213 
214 	
215 	public void delete(int offset, int length) 
216 	{
217 		if (offset + length > field.length()) {
218 			throw new StringIndexOutOfBoundsException();
219 		}
220 		String newtext = "";
221 		if (offset > 0) {
222 			newtext = getString().substring(0, offset);
223 		}
224 		if (offset + length < field.length()) {
225 			newtext += getString().substring(offset + length);
226 		}
227 		setString(newtext);
228 		repaint();
229 	}
230 
231 	
232 	public int getMaxSize() 
233 	{
234 		return maxSize;
235 	}
236 
237 	
238 	public int setMaxSize(int maxSize) 
239 	{
240 		if (maxSize <= 0) {
241 			throw new IllegalArgumentException();
242 		}
243 		if (field.length() > maxSize) {
244 			setString(getString().substring(0, maxSize));
245 		}
246 		this.maxSize = maxSize;
247 		return maxSize;
248 	}
249 
250 	
251 	public int size() 
252 	{
253 		return field.length();
254 	}
255 
256 	
257 	public int getCaretPosition() 
258 	{
259 		return caret;
260 	}
261 
262 	
263 	public void setConstraints(int constraints) 
264 	{
265 		if ((constraints & TextField.CONSTRAINT_MASK) < ANY
266 			|| (constraints & TextField.CONSTRAINT_MASK) > DECIMAL) {
267 			throw new IllegalArgumentException("constraints " + constraints + " is an illegal value");
268 		}
269 		this.constraints = constraints;
270         if (!InputMethod.validate(field, constraints)) {
271             setString("");
272         }
273 	}
274 
275 	
276 	public int getConstraints() 
277 	{
278 		return constraints;
279 	}
280 	
281 	
282 	public void setInitialInputMode(String characterSubset)
283 	{
284 		// TODO implement
285 	}
286 
287 	
288 	boolean isFocusable() 
289 	{
290 		return true;
291 	}
292 
293 	
294 	int getHeight() 
295 	{
296 		return super.getHeight() + stringComponent.getHeight() + 8;
297 	}
298 
299 	
300 	int paint(Graphics g) 
301 	{
302 		super.paintContent(g);
303 
304 		g.translate(0, super.getHeight());
305 		int savedColor = g.getColor();
306 		if (!hasFocus()) {
307 		    g.setGrayScale(127);
308 		}
309 		g.drawRect(
310 		        1, 1, 
311 				owner.getWidth() - 3, stringComponent.getHeight() + 4);
312 		if (!hasFocus()) {
313 		    g.setColor(savedColor);
314 		}
315 		g.translate(3, 3);
316 		paintContent(g);
317 		g.translate(-3, -3);
318 		g.translate(0, -super.getHeight());
319 
320 		return getHeight();
321 	}
322 
323 	
324 	void paintContent(Graphics g) 
325 	{
326 		stringComponent.paint(g);
327 		if (caretVisible) {
328 			int x_pos = stringComponent.getCharPositionX(caret);
329 			int y_pos = stringComponent.getCharPositionY(caret);
330 			g.drawLine(x_pos, y_pos, x_pos, y_pos + Font.getDefaultFont().getHeight());
331 		}
332 	}
333 
334 	
335 	void setCaretPosition(int position) 
336 	{
337 		caret = position;
338 	}
339 
340 	
341 	void setCaretVisible(boolean state) 
342 	{
343 		caretVisible = state;
344 	}
345 
346 	
347 	int traverse(int gameKeyCode, int top, int bottom, boolean action) 
348 	{
349 		if (gameKeyCode == Canvas.UP) {
350 			if (top > 0) {
351 				return -top;
352 			} else {
353 				return Item.OUTOFITEM;
354 			}
355 		}
356 		if (gameKeyCode == Canvas.DOWN) {
357 			if (getHeight() > bottom) {
358 				return getHeight() - bottom;
359 			} else {
360 				return Item.OUTOFITEM;
361 			}
362 		}
363 
364 		return 0;
365 	}
366 
367 	
368 	void setFocus(boolean hasFocus) 
369 	{
370 		super.setFocus(hasFocus);
371 		if (hasFocus) {
372 			// register input listener
373 			InputMethod inputMethod = DeviceFactory.getDevice().getInputMethod();
374 			inputMethod.setInputMethodListener(inputMethodListener);
375 			inputMethod.setMaxSize(getMaxSize());
376 			setCaretVisible(true);
377 		} else {
378 			// unregister input listener
379 			DeviceFactory.getDevice().getInputMethod().removeInputMethodListener(inputMethodListener);
380 			setCaretVisible(false);
381 		}
382 	}	
383 
384 }