001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package javax.microedition.lcdui;
028:
029: /**
030: * Implementation class for TextFieldLF
031: */
032:
033: import com.sun.midp.lcdui.DynamicCharacterArray;
034: import com.sun.midp.lcdui.TextPolicy;
035: import com.sun.midp.configurator.Constants;
036:
037: /**
038: * Look and feel implementation of <code>TextField</code> based on
039: * platform widget.
040: */
041: class TextFieldLFImpl extends ItemLFImpl implements TextFieldLF {
042:
043: /**
044: * Creates <code>TextFieldLF</code> for the passed in
045: * <code>TextField</code>.
046: *
047: * @param tf The <code>TextField</code> associated with this
048: * <code>TextFieldLF</code>
049: */
050: TextFieldLFImpl(TextField tf) {
051: super (tf);
052:
053: this .tf = tf;
054: }
055:
056: // *****************************************************
057: // Public methods defined in interfaces
058: // *****************************************************
059:
060: /**
061: * Update the character buffer in <code>TextField</code> with latest
062: * user input.
063: *
064: * @return <code>true</code> if there is new user input updated in
065: * the buffer
066: */
067: public boolean lUpdateContents() {
068: // No pending user input when there is no native resource or not shown
069: if (nativeId == DisplayableLFImpl.INVALID_NATIVE_ID) {
070: return false;
071: }
072:
073: // Query native resource for pending user input
074: return getString0(nativeId, tf.buffer);
075: }
076:
077: /**
078: * Override the preferred width of this <code>Item</code>.
079: *
080: * @param h tentative locked height.
081: * Ignored here.
082: *
083: * @return the preferred width
084: */
085: public int lGetPreferredWidth(int h) {
086:
087: // note: h is not used
088:
089: // For TextBox return all width available for the item
090: if (tf.owner instanceof TextBox) {
091: return ((DisplayableLFImpl) tf.owner.getLF()).width;
092: }
093: return super .lGetPreferredWidth(h);
094: }
095:
096: /**
097: * Override the preferred height of this <code>Item</code>.
098: *
099: * @param w tentative locked width.
100: * Ignored here and preferred width is used always.
101: *
102: * @return the preferred height
103: */
104: public int lGetPreferredHeight(int w) {
105:
106: // note: w is not used
107:
108: int h = super .lGetPreferredHeight(w);
109:
110: // For TextBox return all height available for the item
111: if (tf.owner instanceof TextBox) {
112: if (((DisplayableLFImpl) tf.owner.getLF()).height > h) {
113: h = ((DisplayableLFImpl) tf.owner.getLF()).height;
114: }
115: }
116: return h;
117: }
118:
119: /**
120: * Get current contents from native resource.
121: *
122: * @param nativeId native resource id of this <code>Item</code>
123: * @param buffer the char array to be populated
124: *
125: * @return <code>true</code> if there is new input
126: */
127: private native boolean getString0(int nativeId,
128: DynamicCharacterArray buffer);
129:
130: /**
131: * Update content and caret position of the TextField's native widget.
132: *
133: * @param nativeId native resource id of this <code>Item</code>
134: * @param buffer char array of the new contents
135: */
136: private native void setString0(int nativeId,
137: DynamicCharacterArray buffer);
138:
139: /**
140: * Notifies L&F of a content change in the corresponding
141: * <code>TextField</code>.
142: * The parameters are not used. Instead, this function directly
143: * uses data from TextField.java.
144: */
145: public void lSetChars() {
146: // Only update native resource if it exists.
147: if (nativeId != DisplayableLFImpl.INVALID_NATIVE_ID) {
148: setString0(nativeId, tf.buffer);
149: }
150:
151: lRequestInvalidate(true, true);
152: }
153:
154: /**
155: * Notifies L&F of a character insertion in the corresponding
156: * <code>TextField</code>.
157: *
158: * @param data the source of the character data. Not used.
159: * @param offset the beginning of the region of characters copied.
160: * Not used.
161: * @param length the number of characters copied. Not used.
162: * @param position the position at which insertion occurred
163: */
164: public void lInsert(char data[], int offset, int length,
165: int position) {
166: // Simplify porting layer by treating insert as setChars
167: lSetChars();
168: }
169:
170: /**
171: * Notifies L&F of character deletion in the corresponding
172: * <code>TextField</code>.
173: *
174: * @param offset the beginning of the deleted region
175: * @param length the number of characters deleted
176: */
177: public void lDelete(int offset, int length) {
178: // Simplify porting layer by treating delete as setChars
179: lSetChars();
180: }
181:
182: /**
183: * Notifies L&F of a maximum size change in the corresponding
184: * <code>TextField</code>.
185: *
186: * @param maxSize the new maximum size
187: */
188: public void lSetMaxSize(int maxSize) {
189: // Only update native resource if it exists.
190: if (nativeId != DisplayableLFImpl.INVALID_NATIVE_ID) {
191: setMaxSize0(nativeId, maxSize);
192: }
193:
194: lRequestInvalidate(true, true);
195: }
196:
197: /**
198: * Set new maximum size of the native widget.
199: *
200: * @param nativeId native resource id of this <code>Item</code>
201: * @param maxSize new maximum size
202: */
203: private native void setMaxSize0(int nativeId, int maxSize);
204:
205: /**
206: * Gets the current input position.
207: *
208: * @return the current caret position, <code>0</code> if at the beginning
209: */
210: public int lGetCaretPosition() {
211: return (nativeId != DisplayableLFImpl.INVALID_NATIVE_ID) ? getCaretPosition0(nativeId)
212: : tf.buffer.length();
213: }
214:
215: /**
216: * Gets the current input position from native widget.
217: *
218: * @param nativeId native resource id of this <code>Item</code>
219: * @return current caret position
220: */
221: private native int getCaretPosition0(int nativeId);
222:
223: /**
224: * Notifies L&F that constraints have to be changed.
225: */
226: public void lSetConstraints() {
227:
228: // Only update native resource if it exists.
229: if (nativeId != DisplayableLFImpl.INVALID_NATIVE_ID) {
230: setConstraints0(nativeId, tf.constraints);
231: }
232:
233: // note: int some implementation this method call may affect
234: // the layout, and int this case such a call will be needed:
235: // lRequestInvalidate(true, true);
236: }
237:
238: /**
239: * Set input constraints of the native widget.
240: *
241: * @param nativeId native resource id of this <code>Item</code>
242: * @param constraints the new input constraints
243: */
244: private native void setConstraints0(int nativeId, int constraints);
245:
246: /**
247: * Validate a given character array against a constraints.
248: *
249: * @param buffer a character array
250: * @param constraints text input constraints
251: *
252: * @return <code>true</code> if constraints is met by the character array
253: */
254: public boolean lValidate(DynamicCharacterArray buffer,
255: int constraints) {
256: return TextPolicy.isValidString(buffer, constraints);
257: }
258:
259: /**
260: * Notifies L&F that preferred initial input mode was changed.
261: *
262: * @param characterSubset a string naming a Unicode character subset,
263: * or <code>null</code>
264: */
265: public void lSetInitialInputMode(String characterSubset) {
266: // No visual impact
267: }
268:
269: /**
270: * Notifies item that it has been recently deleted
271: * Traverse out the textFieldLF.
272: */
273: public void itemDeleted() {
274: uCallTraverseOut();
275: }
276:
277: // *****************************************************
278: // Package private methods
279: // *****************************************************
280:
281: /**
282: * Called by event delivery to notify an <code>ItemLF</code> in current
283: * <code>FormLF</code> of a change in its peer state.
284: *
285: * @param hint any value means contents have changed in native
286: *
287: * @return always <code>true</code> to notify
288: * <code>ItemStateListener</code>
289: */
290: boolean uCallPeerStateChanged(int hint) {
291: return true;
292: }
293:
294: /**
295: * Determine if this <code>Item</code> should have a newline after it.
296: *
297: * @return <code>true</code> if it should have a newline after
298: */
299: boolean equateNLA() {
300: if (super .equateNLA()) {
301: return true;
302: }
303:
304: return ((tf.layout & Item.LAYOUT_2) != Item.LAYOUT_2);
305: }
306:
307: /**
308: * Determine if this <code>Item</code> should have a newline before it.
309: *
310: * @return <code>true</code> if it should have a newline before
311: */
312: boolean equateNLB() {
313: if (super .equateNLB()) {
314: return true;
315: }
316:
317: return ((tf.layout & Item.LAYOUT_2) != Item.LAYOUT_2);
318: }
319:
320: /**
321: * Create native resource for current <code>TextField</code>.
322: * Override function in <code>ItemLFImpl</code>.
323: *
324: * @param ownerId Owner screen's native resource id
325: */
326: void createNativeResource(int ownerId) {
327: nativeId = createNativeResource0(ownerId, tf.label,
328: (tf.owner instanceof TextBox ? -1 : tf.layout),
329: tf.buffer, tf.constraints, tf.initialInputMode);
330: }
331:
332: /**
333: * KNI function that create native resource for current
334: * <code>TextField</code>.
335: *
336: * @param ownerId Owner screen's native resource id
337: * (<code>MidpDisplayable *</code>)
338: * @param label label of the item
339: * @param layout layout directive associated with this <code>Item</code>
340: * @param buffer char array of the contents
341: * @param constraints input constraints
342: * @param initialInputMode suggested input mode on creation
343: *
344: * @return native resource id (<code>MidpItem *</code>) of this
345: * <code>Item</code>
346: */
347: private native int createNativeResource0(int ownerId, String label,
348: int layout, DynamicCharacterArray buffer, int constraints,
349: String initialInputMode);
350:
351: /**
352: * Override <code>ItemLFImpl</code> method to sync with native resource
353: * before hiding the native resource.
354: */
355: void lHideNativeResource() {
356: lUpdateContents();
357: super .lHideNativeResource();
358: }
359:
360: /** <code>TextField</code> instance associated with this view. */
361: TextField tf;
362:
363: } // TextFieldLFImpl
|