0001: /*
0002: *
0003: *
0004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006: *
0007: * This program is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU General Public License version
0009: * 2 only, as published by the Free Software Foundation.
0010: *
0011: * This program is distributed in the hope that it will be useful, but
0012: * WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * General Public License version 2 for more details (a copy is
0015: * included at /legal/license.txt).
0016: *
0017: * You should have received a copy of the GNU General Public License
0018: * version 2 along with this work; if not, write to the Free Software
0019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA
0021: *
0022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023: * Clara, CA 95054 or visit www.sun.com if you need additional
0024: * information or have any questions.
0025: */
0026:
0027: package javax.microedition.lcdui;
0028:
0029: import com.sun.midp.lcdui.DynamicCharacterArray;
0030:
0031: /**
0032: * A <code>TextField</code> is an editable text component that may be
0033: * placed into
0034: * a {@link Form Form}. It can be
0035: * given a piece of text that is used as the initial value.
0036: *
0037: * <P>A <code>TextField</code> has a maximum size, which is the
0038: * maximum number of characters
0039: * that can be stored in the object at any time (its capacity). This limit is
0040: * enforced when the <code>TextField</code> instance is constructed,
0041: * when the user is editing text within the <code>TextField</code>, as well as
0042: * when the application program calls methods on the
0043: * <code>TextField</code> that modify its
0044: * contents. The maximum size is the maximum stored capacity and is unrelated
0045: * to the number of characters that may be displayed at any given time.
0046: * The number of characters displayed and their arrangement into rows and
0047: * columns are determined by the device. </p>
0048: *
0049: * <p>The implementation may place a boundary on the maximum size, and the
0050: * maximum size actually assigned may be smaller than the application had
0051: * requested. The value actually assigned will be reflected in the value
0052: * returned by {@link #getMaxSize() getMaxSize()}. A defensively-written
0053: * application should compare this value to the maximum size requested and be
0054: * prepared to handle cases where they differ.</p>
0055: *
0056: * <a name="constraints"></a>
0057: * <h3>Input Constraints</h3>
0058: *
0059: * <P>The <code>TextField</code> shares the concept of <em>input
0060: * constraints</em> with the {@link TextBox TextBox} class. The different
0061: * constraints allow the application to request that the user's input be
0062: * restricted in a variety of ways. The implementation is required to
0063: * restrict the user's input as requested by the application. For example, if
0064: * the application requests the <code>NUMERIC</code> constraint on a
0065: * <code>TextField</code>, the
0066: * implementation must allow only numeric characters to be entered. </p>
0067: *
0068: * <p>The <em>actual contents</em> of the text object are set and modified by
0069: * and are
0070: * reported to the application through the <code>TextBox</code> and
0071: * <code>TextField</code> APIs. The <em>displayed contents</em> may differ
0072: * from the actual contents if the implementation has chosen to provide
0073: * special formatting suitable for the text object's constraint setting.
0074: * For example, a <code>PHONENUMBER</code> field might be displayed with
0075: * digit separators and punctuation as
0076: * appropriate for the phone number conventions in use, grouping the digits
0077: * into country code, area code, prefix, etc. Any spaces or punctuation
0078: * provided are not considered part of the text object's actual contents. For
0079: * example, a text object with the <code>PHONENUMBER</code>
0080: * constraint might display as
0081: * follows:</p>
0082: *
0083: * <TABLE BORDER="2">
0084: * <TR>
0085: * <TD ROWSPAN="1" COLSPAN="1">
0086: * <pre><code>
0087: * (408) 555-1212 </code></pre>
0088: * </TD>
0089: * </TR>
0090: * </TABLE>
0091: *
0092: * <p>but the actual contents of the object visible to the application
0093: * through the APIs would be the string
0094: * "<code>4085551212</code>".
0095: * The <code>size</code> method reflects the number of characters in the
0096: * actual contents, not the number of characters that are displayed, so for
0097: * this example the <code>size</code> method would return <code>10</code>.</p>
0098: *
0099: * <p>Some constraints, such as <code>DECIMAL</code>, require the
0100: * implementation to perform syntactic validation of the contents of the text
0101: * object. The syntax checking is performed on the actual contents of the
0102: * text object, which may differ from the displayed contents as described
0103: * above. Syntax checking is performed on the initial contents passed to the
0104: * constructors, and it is also enforced for all method calls that affect the
0105: * contents of the text object. The methods and constructors throw
0106: * <code>IllegalArgumentException</code> if they would result in the contents
0107: * of the text object not conforming to the required syntax.</p>
0108: *
0109: * <p>The value passed to the {@link #setConstraints setConstraints()} method
0110: * consists of a restrictive constraint setting described above, as well as a
0111: * variety of flag bits that modify the behavior of text entry and display.
0112: * The value of the restrictive constraint setting is in the low order
0113: * <code>16</code> bits
0114: * of the value, and it may be extracted by combining the constraint value
0115: * with the <code>CONSTRAINT_MASK</code> constant using the bit-wise
0116: * <code>AND</code> (<code>&</code>) operator.
0117: * The restrictive constraint settings are as follows:
0118: *
0119: * <blockquote><code>
0120: * ANY<br>
0121: * EMAILADDR<br>
0122: * NUMERIC<br>
0123: * PHONENUMBER<br>
0124: * URL<br>
0125: * DECIMAL<br>
0126: * </code></blockquote>
0127: *
0128: * <p>The modifier flags reside in the high order <code>16</code> bits
0129: * of the constraint
0130: * value, that is, those in the complement of the
0131: * <code>CONSTRAINT_MASK</code> constant.
0132: * The modifier flags may be tested individually by combining the constraint
0133: * value with a modifier flag using the bit-wise <code>AND</code>
0134: * (<code>&</code>) operator. The
0135: * modifier flags are as follows:
0136: *
0137: * <blockquote><code>
0138: * PASSWORD<br>
0139: * UNEDITABLE<br>
0140: * SENSITIVE<br>
0141: * NON_PREDICTIVE<br>
0142: * INITIAL_CAPS_WORD<br>
0143: * INITIAL_CAPS_SENTENCE<br>
0144: * </code></blockquote>
0145: *
0146: * <a name="modes"></a>
0147: * <h3>Input Modes</h3>
0148: *
0149: * <p>The <code>TextField</code> shares the concept of <em>input
0150: * modes</em> with the {@link
0151: * TextBox TextBox} class. The application can request that the
0152: * implementation use a particular input mode when the user initiates editing
0153: * of a <code>TextField</code> or <code>TextBox</code>. The input
0154: * mode is a concept that exists within
0155: * the user interface for text entry on a particular device. The application
0156: * does not request an input mode directly, since the user interface for text
0157: * entry is not standardized across devices. Instead, the application can
0158: * request that the entry of certain characters be made convenient. It can do
0159: * this by passing the name of a Unicode character subset to the {@link
0160: * #setInitialInputMode setInitialInputMode()} method. Calling this method
0161: * requests that the implementation set the mode of the text entry user
0162: * interface so that it is convenient for the user to enter characters in this
0163: * subset. The application can also request that the input mode have certain
0164: * behavioral characteristics by setting modifier flags in the constraints
0165: * value.
0166: *
0167: * <p>The requested input mode should be used whenever the user initiates the
0168: * editing of a <code>TextBox</code> or <code>TextField</code> object.
0169: * If the user had changed input
0170: * modes in a previous editing session, the application's requested input mode
0171: * should take precedence over the previous input mode set by the user.
0172: * However, the input mode is not restrictive, and the user is allowed to
0173: * change the input mode at any time during editing. If editing is already in
0174: * progress, calls to the <code>setInitialInputMode</code> method do not
0175: * affect the current input mode, but instead take effect at the next time the
0176: * user initiates editing of this text object.
0177: *
0178: * <p>The initial input mode is a hint to the implementation. If the
0179: * implementation cannot provide an input mode that satisfies the
0180: * application's request, it should use a default input mode.
0181: *
0182: * <P>The input mode that results from the application's request is not a
0183: * restriction on the set of characters the user is allowed to enter. The
0184: * user MUST be allowed to switch input modes to enter any character that is
0185: * allowed within the current constraint setting. The constraint
0186: * setting takes precedence over an input mode request, and the implementation
0187: * may refuse to supply a particular input mode if it is inconsistent with the
0188: * current constraint setting.
0189: *
0190: * <P>For example, if the current constraint is <code>ANY</code>, the call</P>
0191: *
0192: * <TABLE BORDER="2">
0193: * <TR>
0194: * <TD ROWSPAN="1" COLSPAN="1">
0195: * <pre><code>
0196: * setInitialInputMode("MIDP_UPPERCASE_LATIN"); </code></pre>
0197: * </TD>
0198: * </TR>
0199: * </TABLE>
0200: *
0201: * <p>should set the initial input mode to allow entry of uppercase Latin
0202: * characters. This does not restrict input to these characters, and the user
0203: * will be able to enter other characters by switching the input mode to allow
0204: * entry of numerals or lowercase Latin letters. However, if the current
0205: * constraint is <code>NUMERIC</code>, the implementation may ignore
0206: * the request to set an
0207: * initial input mode allowing <code>MIDP_UPPERCASE_LATIN</code>
0208: * characters because these
0209: * characters are not allowed in a <code>TextField</code> whose
0210: * constraint is <code>NUMERIC</code>. In
0211: * this case, the implementation may instead use an input mode that allows
0212: * entry of numerals, since such an input mode is most appropriate for entry
0213: * of data under the <code>NUMERIC</code> constraint.
0214: *
0215: * <P>A string is used to name the Unicode character subset passed as a
0216: * parameter to the
0217: * {@link #setInitialInputMode setInitialInputMode()} method.
0218: * String comparison is case sensitive.
0219: *
0220: * <P>Unicode character blocks can be named by adding the prefix
0221: * "<code>UCB</code>_" to the
0222: * the string names of fields representing Unicode character blocks as defined
0223: * in the J2SE class <code>java.lang.Character.UnicodeBlock</code>. Any
0224: * Unicode character block may be named in this fashion. For convenience, the
0225: * most common Unicode character blocks are listed below.
0226: *
0227: * <blockquote><code>
0228: * UCB_BASIC_LATIN<br>
0229: * UCB_GREEK<br>
0230: * UCB_CYRILLIC<br>
0231: * UCB_ARMENIAN<br>
0232: * UCB_HEBREW<br>
0233: * UCB_ARABIC<br>
0234: * UCB_DEVANAGARI<br>
0235: * UCB_BENGALI<br>
0236: * UCB_THAI<br>
0237: * UCB_HIRAGANA<br>
0238: * UCB_KATAKANA<br>
0239: * UCB_HANGUL_SYLLABLES<br>
0240: * </code></blockquote>
0241: *
0242: * <P>"Input subsets" as defined by the J2SE class
0243: * <code>java.awt.im.InputSubset</code> may be named by adding the prefix
0244: * "<code>IS_</code>" to the string names of fields
0245: * representing input subsets as defined
0246: * in that class. Any defined input subset may be used. For convenience, the
0247: * names of the currently defined input subsets are listed below.
0248: *
0249: * <blockquote><code>
0250: * IS_FULLWIDTH_DIGITS<br>
0251: * IS_FULLWIDTH_LATIN<br>
0252: * IS_HALFWIDTH_KATAKANA<br>
0253: * IS_HANJA<br>
0254: * IS_KANJI<br>
0255: * IS_LATIN<br>
0256: * IS_LATIN_DIGITS<br>
0257: * IS_SIMPLIFIED_HANZI<br>
0258: * IS_TRADITIONAL_HANZI<br>
0259: * </code></blockquote>
0260: *
0261: * <P>MIDP has also defined the following character subsets:
0262: *
0263: * <blockquote>
0264: * <code>MIDP_UPPERCASE_LATIN</code> - the subset of
0265: * <code>IS_LATIN</code> that corresponds to
0266: * uppercase Latin letters
0267: * </blockquote>
0268: * <blockquote>
0269: * <code>MIDP_LOWERCASE_LATIN</code> - the subset of
0270: * <code>IS_LATIN</code> that corresponds to
0271: * lowercase Latin letters
0272: * </blockquote>
0273: *
0274: * <p>
0275: * Finally, implementation-specific character subsets may be named with
0276: * strings that have a prefix of "<code>X_</code>". In
0277: * order to avoid namespace conflicts,
0278: * it is recommended that implementation-specific names include the name of
0279: * the defining company or organization after the initial
0280: * "<code>X_</code>" prefix.
0281: *
0282: * <p> For example, a Japanese language application might have a particular
0283: * <code>TextField</code> that the application intends to be used
0284: * primarily for input of
0285: * words that are "loaned" from languages other than Japanese. The
0286: * application might request an input mode facilitating Hiragana input by
0287: * issuing the following method call:</p>
0288: *
0289: * <TABLE BORDER="2">
0290: * <TR>
0291: * <TD ROWSPAN="1" COLSPAN="1">
0292: * <pre><code>
0293: * textfield.setInitialInputMode("UCB_HIRAGANA"); </code></pre>
0294: * </TD>
0295: * </TR>
0296: * </TABLE>
0297: * <h3>Implementation Note</h3>
0298: *
0299: * <p>Implementations need not compile in all the strings listed above.
0300: * Instead, they need only to compile in the strings that name Unicode
0301: * character subsets that they support. If the subset name passed by the
0302: * application does not match a known subset name, the request should simply
0303: * be ignored without error, and a default input mode should be used. This
0304: * lets implementations support this feature reasonably inexpensively.
0305: * However, it has the consequence that the application cannot tell whether
0306: * its request has been accepted, nor whether the Unicode character subset it
0307: * has requested is actually a valid subset.
0308: *
0309: * @since MIDP 1.0
0310: */
0311:
0312: public class TextField extends Item {
0313:
0314: /**
0315: * The user is allowed to enter any text.
0316: * <A HREF="Form.html#linebreak">Line breaks</A> may be entered.
0317: *
0318: * <P>Constant <code>0</code> is assigned to <code>ANY</code>.</P>
0319: */
0320: public final static int ANY = 0;
0321:
0322: /**
0323: * The user is allowed to enter an e-mail address.
0324: *
0325: * <P>Constant <code>1</code> is assigned to <code>EMAILADDR</code>.</P>
0326: */
0327: public final static int EMAILADDR = 1;
0328:
0329: /**
0330: * The user is allowed to enter only an integer value. The implementation
0331: * must restrict the contents either to be empty or to consist of an
0332: * optional minus sign followed by a string of one or more decimal
0333: * numerals. Unless the value is empty, it will be successfully parsable
0334: * using {@link java.lang.Integer#parseInt(String)}.
0335: *
0336: * <P>The minus sign consumes space in the text object. It is thus
0337: * impossible to enter negative numbers into a text object whose maximum
0338: * size is <code>1</code>.</P>
0339: *
0340: * <P>Constant <code>2</code> is assigned to <code>NUMERIC</code>.</P>
0341: */
0342: public final static int NUMERIC = 2;
0343:
0344: /**
0345: * The user is allowed to enter a phone number. The phone number is a
0346: * special
0347: * case, since a phone-based implementation may be linked to the
0348: * native phone
0349: * dialing application. The implementation may automatically start a phone
0350: * dialer application that is initialized so that pressing a single key
0351: * would be enough to make a call. The call must not made automatically
0352: * without requiring user's confirmation. Implementations may also
0353: * provide a feature to look up the phone number in the device's phone or
0354: * address database.
0355: *
0356: * <P>The exact set of characters allowed is specific to the device and to
0357: * the device's network and may include non-numeric characters, such as a
0358: * "+" prefix character.</P>
0359: *
0360: * <P>Some platforms may provide the capability to initiate voice calls
0361: * using the {@link javax.microedition.midlet.MIDlet#platformRequest
0362: * MIDlet.platformRequest} method.</P>
0363: *
0364: * <P>Constant <code>3</code> is assigned to <code>PHONENUMBER</code>.</P>
0365: */
0366: public final static int PHONENUMBER = 3;
0367:
0368: /**
0369: * The user is allowed to enter a URL.
0370: *
0371: * <P>Constant <code>4</code> is assigned to <code>URL</code>.</P>
0372: */
0373: public final static int URL = 4;
0374:
0375: /**
0376: * The user is allowed to enter numeric values with optional decimal
0377: * fractions, for example "-123", "0.123", or
0378: * ".5".
0379: *
0380: * <p>The implementation may display a period "." or a
0381: * comma "," for the decimal fraction separator, depending on
0382: * the conventions in use on the device. Similarly, the implementation
0383: * may display other device-specific characters as part of a decimal
0384: * string, such as spaces or commas for digit separators. However, the
0385: * only characters allowed in the actual contents of the text object are
0386: * period ".", minus sign "-", and the decimal
0387: * digits.</p>
0388: *
0389: * <p>The actual contents of a <code>DECIMAL</code> text object may be
0390: * empty. If the actual contents are not empty, they must conform to a
0391: * subset of the syntax for a <code>FloatingPointLiteral</code> as defined
0392: * by the <em>Java Language Specification</em>, section 3.10.2. This
0393: * subset syntax is defined as follows: the actual contents
0394: * must consist of an optional minus sign
0395: * "-", followed by one or more whole-number decimal digits,
0396: * followed by an optional fraction separator, followed by zero or more
0397: * decimal fraction digits. The whole-number decimal digits may be
0398: * omitted if the fraction separator and one or more decimal fraction
0399: * digits are present.</p>
0400: *
0401: * <p>The syntax defined above is also enforced whenever the application
0402: * attempts to set or modify the contents of the text object by calling
0403: * a constructor or a method.</p>
0404: *
0405: * <p>Parsing this string value into a numeric value suitable for
0406: * computation is the responsibility of the application. If the contents
0407: * are not empty, the result can be parsed successfully by
0408: * <code>Double.valueOf</code> and related methods if they are present
0409: * in the runtime environment. </p>
0410: *
0411: * <p>The sign and the fraction separator consume space in the text
0412: * object. Applications should account for this when assigning a maximum
0413: * size for the text object.</p>
0414: *
0415: * <P>Constant <code>5</code> is assigned to <code>DECIMAL</code>.</P>
0416: *
0417: */
0418: public static final int DECIMAL = 5;
0419:
0420: /**
0421: * Indicates that the text entered is confidential data that should be
0422: * obscured whenever possible. The contents may be visible while the
0423: * user is entering data. However, the contents must never be divulged
0424: * to the user. In particular, the existing contents must not be shown
0425: * when the user edits the contents. The means by which the contents
0426: * are obscured is implementation-dependent. For example, each
0427: * character of the data might be masked with a
0428: * "<code>*</code>" character. The
0429: * <code>PASSWORD</code> modifier is useful for entering
0430: * confidential information
0431: * such as passwords or personal identification numbers (PINs).
0432: *
0433: * <p>Data entered into a <code>PASSWORD</code> field is treated
0434: * similarly to <code>SENSITIVE</code>
0435: * in that the implementation must never store the contents into a
0436: * dictionary or table for use in predictive, auto-completing, or other
0437: * accelerated input schemes. If the <code>PASSWORD</code> bit is
0438: * set in a constraint
0439: * value, the <code>SENSITIVE</code> and
0440: * <code>NON_PREDICTIVE</code> bits are also considered to be
0441: * set, regardless of their actual values. In addition, the
0442: * <code>INITIAL_CAPS_WORD</code> and
0443: * <code>INITIAL_CAPS_SENTENCE</code> flag bits should be ignored
0444: * even if they are set.</p>
0445: *
0446: * <p>The <code>PASSWORD</code> modifier can be combined with
0447: * other input constraints
0448: * by using the bit-wise <code>OR</code> operator (<code>|</code>).
0449: * The <code>PASSWORD</code> modifier is not
0450: * useful with some constraint values such as
0451: * <code>EMAILADDR</code>, <code>PHONENUMBER</code>,
0452: * and <code>URL</code>. These combinations are legal, however,
0453: * and no exception is
0454: * thrown if such a constraint is specified.</p>
0455: *
0456: * <p>Constant <code>0x10000</code> is assigned to
0457: * <code>PASSWORD</code>.</p>
0458: */
0459: public static final int PASSWORD = 0x10000;
0460:
0461: /**
0462: * Indicates that editing is currently disallowed. When this flag is set,
0463: * the implementation must prevent the user from changing the text
0464: * contents of this object. The implementation should also provide a
0465: * visual indication that the object's text cannot be edited. The intent
0466: * of this flag is that this text object has the potential to be edited,
0467: * and that there are circumstances where the application will clear this
0468: * flag and allow the user to edit the contents.
0469: *
0470: * <p>The <code>UNEDITABLE</code> modifier can be combined with
0471: * other input constraints
0472: * by using the bit-wise <code>OR</code> operator (<code>|</code>).
0473: *
0474: * <p>Constant <code>0x20000</code> is assigned to <code>UNEDITABLE</code>.
0475: *
0476: */
0477: public static final int UNEDITABLE = 0x20000;
0478:
0479: /**
0480: * Indicates that the text entered is sensitive data that the
0481: * implementation must never store into a dictionary or table for use in
0482: * predictive, auto-completing, or other accelerated input schemes. A
0483: * credit card number is an example of sensitive data.
0484: *
0485: * <p>The <code>SENSITIVE</code> modifier can be combined with other input
0486: * constraints by using the bit-wise <code>OR</code> operator
0487: * (<code>|</code>).</p>
0488: *
0489: * <p>Constant <code>0x40000</code> is assigned to
0490: * <code>SENSITIVE</code>.</p>
0491: *
0492: */
0493: public static final int SENSITIVE = 0x40000;
0494:
0495: /**
0496: * Indicates that the text entered does not consist of words that are
0497: * likely to be found in dictionaries typically used by predictive input
0498: * schemes. If this bit is clear, the implementation is allowed to (but
0499: * is not required to) use predictive input facilities. If this bit is
0500: * set, the implementation should not use any predictive input facilities,
0501: * but it instead should allow character-by-character text entry.
0502: *
0503: * <p>The <code>NON_PREDICTIVE</code> modifier can be combined
0504: * with other input
0505: * constraints by using the bit-wise <code>OR</code> operator
0506: * (<code>|</code>).
0507: *
0508: * <P>Constant <code>0x80000</code> is assigned to
0509: * <code>NON_PREDICTIVE</code>.</P>
0510: *
0511: */
0512: public static final int NON_PREDICTIVE = 0x80000;
0513:
0514: /**
0515: * This flag is a hint to the implementation that during text editing, the
0516: * initial letter of each word should be capitalized. This hint should be
0517: * honored only on devices for which automatic capitalization is
0518: * appropriate and when the character set of the text being edited has the
0519: * notion of upper case and lower case letters. The definition of
0520: * word boundaries is implementation-specific.
0521: *
0522: * <p>If the application specifies both the
0523: * <code>INITIAL_CAPS_WORD</code> and the
0524: * <code>INITIAL_CAPS_SENTENCE</code> flags,
0525: * <code>INITIAL_CAPS_WORD</code> behavior should be used.
0526: *
0527: * <p>The <code>INITIAL_CAPS_WORD</code> modifier can be combined
0528: * with other input
0529: * constraints by using the bit-wise <code>OR</code> operator
0530: * (<code>|</code>).
0531: *
0532: * <p>Constant <code>0x100000</code> is assigned to
0533: * <code>INITIAL_CAPS_WORD</code>.
0534: *
0535: */
0536: public static final int INITIAL_CAPS_WORD = 0x100000;
0537:
0538: /**
0539: * This flag is a hint to the implementation that during text editing, the
0540: * initial letter of each sentence should be capitalized. This hint
0541: * should be honored only on devices for which automatic capitalization is
0542: * appropriate and when the character set of the text being edited has the
0543: * notion of upper case and lower case letters. The definition of
0544: * sentence boundaries is implementation-specific.
0545: *
0546: * <p>If the application specifies both the
0547: * <code>INITIAL_CAPS_WORD</code> and the
0548: * <code>INITIAL_CAPS_SENTENCE</code> flags,
0549: * <code>INITIAL_CAPS_WORD</code> behavior should be used.
0550: *
0551: * <p>The <code>INITIAL_CAPS_SENTENCE</code> modifier can be
0552: * combined with other input
0553: * constraints by using the bit-wise <code>OR</code> operator
0554: * (<code>|</code>).
0555: *
0556: * <p>Constant <code>0x200000</code> is assigned to
0557: * <code>INITIAL_CAPS_SENTENCE</code>.
0558: *
0559: */
0560: public static final int INITIAL_CAPS_SENTENCE = 0x200000;
0561:
0562: /**
0563: * The mask value for determining the constraint mode. The application
0564: * should
0565: * use the bit-wise <code>AND</code> operation with a value returned by
0566: * <code>getConstraints()</code> and
0567: * <code>CONSTRAINT_MASK</code> in order to retrieve the current
0568: * constraint mode,
0569: * in order to remove any modifier flags such as the
0570: * <code>PASSWORD</code> flag.
0571: *
0572: * <P>Constant <code>0xFFFF</code> is assigned to
0573: * <code>CONSTRAINT_MASK</code>.</P>
0574: */
0575: public final static int CONSTRAINT_MASK = 0xFFFF;
0576:
0577: /**
0578: * Creates a new <code>TextField</code> object with the given label, initial
0579: * contents, maximum size in characters, and constraints.
0580: * If the text parameter is <code>null</code>, the
0581: * <code>TextField</code> is created empty.
0582: * The <code>maxSize</code> parameter must be greater than zero.
0583: * An <code>IllegalArgumentException</code> is thrown if the
0584: * length of the initial contents string exceeds <code>maxSize</code>.
0585: * However,
0586: * the implementation may assign a maximum size smaller than the
0587: * application had requested. If this occurs, and if the length of the
0588: * contents exceeds the newly assigned maximum size, the contents are
0589: * truncated from the end in order to fit, and no exception is thrown.
0590: *
0591: * @param label item label
0592: * @param text the initial contents, or <code>null</code> if the
0593: * <code>TextField</code> is to be empty
0594: * @param maxSize the maximum capacity in characters
0595: * @param constraints see <a href="#constraints">input constraints</a>
0596: *
0597: * @throws IllegalArgumentException if <code>maxSize</code> is zero or less
0598: * @throws IllegalArgumentException if the value of the constraints
0599: * parameter
0600: * is invalid
0601: * @throws IllegalArgumentException if <code>text</code> is illegal
0602: * for the specified constraints
0603: * @throws IllegalArgumentException if the length of the string exceeds
0604: * the requested maximum capacity
0605: */
0606: public TextField(String label, String text, int maxSize,
0607: int constraints) {
0608:
0609: super (label);
0610:
0611: synchronized (Display.LCDUILock) {
0612:
0613: // IllegalArgumentException thrown here
0614: buffer = new DynamicCharacterArray(maxSize);
0615:
0616: // Constraint value is checked here. Since textFieldLF is not
0617: // yet created, no LF notification will happen.
0618: setConstraintsImpl(constraints);
0619:
0620: // Create a LF with empty content
0621: itemLF = textFieldLF = LFFactory.getFactory()
0622: .getTextFieldLF(this );
0623:
0624: // this will use inputClient
0625: // Right now setCharsImpl notifies LF a content change.
0626: // If LF is created as an absolutely last thing then
0627: // setCharsImple here does not need the notification.
0628: if (text == null) {
0629: setCharsImpl(null, 0, 0);
0630: } else {
0631: setCharsImpl(text.toCharArray(), 0, text.length());
0632: }
0633: }
0634: }
0635:
0636: /**
0637: * Gets the contents of the <code>TextField</code> as a string value.
0638: *
0639: * @return the current contents
0640: * @see #setString
0641: */
0642: public String getString() {
0643: synchronized (Display.LCDUILock) {
0644: textFieldLF.lUpdateContents();
0645: return buffer.toString();
0646: }
0647: }
0648:
0649: /**
0650: * Sets the contents of the <code>TextField</code> as a string
0651: * value, replacing the
0652: * previous contents.
0653: *
0654: * @param text the new value of the <code>TextField</code>, or
0655: * <code>null</code> if the TextField is to be made empty
0656: * @throws IllegalArgumentException if <code>text</code>
0657: * is illegal for the current
0658: * <a href="TextField.html#constraints">input constraints</a>
0659: * @throws IllegalArgumentException if the text would exceed the current
0660: * maximum capacity
0661: * @see #getString
0662: */
0663: public void setString(String text) {
0664:
0665: synchronized (Display.LCDUILock) {
0666: if (text == null || text.length() == 0) {
0667: setCharsImpl(null, 0, 0);
0668: } else {
0669: setCharsImpl(text.toCharArray(), 0, text.length());
0670: }
0671: }
0672: }
0673:
0674: /**
0675: * Copies the contents of the <code>TextField</code> into a
0676: * character array starting at
0677: * index zero. Array elements beyond the characters copied are left
0678: * unchanged.
0679: *
0680: * @param data the character array to receive the value
0681: * @return the number of characters copied
0682: * @throws ArrayIndexOutOfBoundsException if the array is too short for the
0683: * contents
0684: * @throws NullPointerException if <code>data</code> is <code>null</code>
0685: * @see #setChars
0686: */
0687: public int getChars(char[] data) {
0688:
0689: synchronized (Display.LCDUILock) {
0690:
0691: textFieldLF.lUpdateContents();
0692:
0693: try {
0694: buffer.getChars(0, buffer.length(), data, 0);
0695: } catch (IndexOutOfBoundsException e) {
0696: throw new ArrayIndexOutOfBoundsException(e.getMessage());
0697: }
0698:
0699: return buffer.length();
0700: }
0701: }
0702:
0703: /**
0704: * Sets the contents of the <code>TextField</code> from a
0705: * character array, replacing the
0706: * previous contents. Characters are copied from the region of the
0707: * <code>data</code> array
0708: * starting at array index <code>offset</code> and running for
0709: * <code>length</code> characters.
0710: * If the data array is <code>null</code>, the <code>TextField</code>
0711: * is set to be empty and the other parameters are ignored.
0712: *
0713: * <p>The <code>offset</code> and <code>length</code> parameters must
0714: * specify a valid range of characters within
0715: * the character array <code>data</code>.
0716: * The <code>offset</code> parameter must be within the
0717: * range <code>[0..(data.length)]</code>, inclusive.
0718: * The <code>length</code> parameter
0719: * must be a non-negative integer such that
0720: * <code>(offset + length) <= data.length</code>.</p>
0721: *
0722: * @param data the source of the character data
0723: * @param offset the beginning of the region of characters to copy
0724: * @param length the number of characters to copy
0725: * @throws ArrayIndexOutOfBoundsException if <code>offset</code>
0726: * and <code>length</code> do not specify
0727: * a valid range within the data array
0728: * @throws IllegalArgumentException if <code>data</code>
0729: * is illegal for the current
0730: * <a href="TextField.html#constraints">input constraints</a>
0731: * @throws IllegalArgumentException if the text would exceed the current
0732: * maximum capacity
0733: * @see #getChars
0734: */
0735: public void setChars(char[] data, int offset, int length) {
0736:
0737: synchronized (Display.LCDUILock) {
0738: setCharsImpl(data, offset, length);
0739: }
0740: }
0741:
0742: /**
0743: * Inserts a string into the contents of the
0744: * <code>TextField</code>. The string is
0745: * inserted just prior to the character indicated by the
0746: * <code>position</code> parameter, where zero specifies the first
0747: * character of the contents of the <code>TextField</code>. If
0748: * <code>position</code> is
0749: * less than or equal to zero, the insertion occurs at the beginning of
0750: * the contents, thus effecting a prepend operation. If
0751: * <code>position</code> is greater than or equal to the current size of
0752: * the contents, the insertion occurs immediately after the end of the
0753: * contents, thus effecting an append operation. For example,
0754: * <code>text.insert(s, text.size())</code> always appends the string
0755: * <code>s</code> to the current contents.
0756: *
0757: * <p>The current size of the contents is increased by the number of
0758: * inserted characters. The resulting string must fit within the current
0759: * maximum capacity. </p>
0760: *
0761: * <p>If the application needs to simulate typing of characters it can
0762: * determining the location of the current insertion point
0763: * ("caret")
0764: * using the with {@link #getCaretPosition() getCaretPosition()} method.
0765: * For example,
0766: * <code>text.insert(s, text.getCaretPosition())</code> inserts the string
0767: * <code>s</code> at the current caret position.</p>
0768: *
0769: * @param src the <code>String</code> to be inserted
0770: * @param position the position at which insertion is to occur
0771: *
0772: * @throws IllegalArgumentException if the resulting contents
0773: * would be illegal for the current
0774: * <a href="TextField.html#constraints">input constraints</a>
0775: * @throws IllegalArgumentException if the insertion would exceed
0776: * the current
0777: * maximum capacity
0778: * @throws NullPointerException if <code>src</code> is <code>null</code>
0779: */
0780: public void insert(String src, int position) {
0781: synchronized (Display.LCDUILock) {
0782: // NullPointerException will be thrown by src.toCharArray
0783: insertImpl(src.toCharArray(), 0, src.length(), position);
0784: }
0785: }
0786:
0787: /**
0788: * Inserts a subrange of an array of characters into the contents of
0789: * the <code>TextField</code>. The <code>offset</code> and
0790: * <code>length</code> parameters indicate the subrange
0791: * of the data array to be used for insertion. Behavior is otherwise
0792: * identical to {@link #insert(String, int) insert(String, int)}.
0793: *
0794: * <p>The <code>offset</code> and <code>length</code> parameters must
0795: * specify a valid range of characters within
0796: * the character array <code>data</code>.
0797: * The <code>offset</code> parameter must be within the
0798: * range <code>[0..(data.length)]</code>, inclusive.
0799: * The <code>length</code> parameter
0800: * must be a non-negative integer such that
0801: * <code>(offset + length) <= data.length</code>.</p>
0802: *
0803: * @param data the source of the character data
0804: * @param offset the beginning of the region of characters to copy
0805: * @param length the number of characters to copy
0806: * @param position the position at which insertion is to occur
0807: *
0808: * @throws ArrayIndexOutOfBoundsException if <code>offset</code>
0809: * and <code>length</code> do not specify
0810: * a valid range within the <code>data</code> array
0811: * @throws IllegalArgumentException if the resulting contents
0812: * would be illegal for the current
0813: * <a href="TextField.html#constraints">input constraints</a>
0814: * @throws IllegalArgumentException if the insertion would exceed
0815: * the current
0816: * maximum capacity
0817: * @throws NullPointerException if <code>data</code> is <code>null</code>
0818: */
0819: public void insert(char[] data, int offset, int length, int position) {
0820: synchronized (Display.LCDUILock) {
0821: insertImpl(data, offset, length, position);
0822: }
0823: }
0824:
0825: /**
0826: * Deletes characters from the <code>TextField</code>.
0827: *
0828: * <p>The <code>offset</code> and <code>length</code> parameters must
0829: * specify a valid range of characters within
0830: * the contents of the <code>TextField</code>.
0831: * The <code>offset</code> parameter must be within the
0832: * range <code>[0..(size())]</code>, inclusive.
0833: * The <code>length</code> parameter
0834: * must be a non-negative integer such that
0835: * <code>(offset + length) <= size()</code>.</p>
0836: *
0837: * @param offset the beginning of the region to be deleted
0838: * @param length the number of characters to be deleted
0839: *
0840: * @throws IllegalArgumentException if the resulting contents
0841: * would be illegal for the current
0842: * <a href="TextField.html#constraints">input constraints</a>
0843: * @throws StringIndexOutOfBoundsException if <code>offset</code>
0844: * and <code>length</code> do not
0845: * specify a valid range within the contents of the <code>TextField</code>
0846: */
0847: public void delete(int offset, int length) {
0848: synchronized (Display.LCDUILock) {
0849: deleteImpl(offset, length);
0850: }
0851: }
0852:
0853: /**
0854: * Returns the maximum size (number of characters) that can be
0855: * stored in this <code>TextField</code>.
0856: * @return the maximum size in characters
0857: * @see #setMaxSize
0858: */
0859: public int getMaxSize() {
0860: synchronized (Display.LCDUILock) {
0861: return buffer.capacity();
0862: }
0863: }
0864:
0865: /**
0866: * Sets the maximum size (number of characters) that can be contained
0867: * in this
0868: * <code>TextField</code>. If the current contents of the
0869: * <code>TextField</code> are larger than
0870: * <code>maxSize</code>, the contents are truncated to fit.
0871: *
0872: * @param maxSize the new maximum size
0873: *
0874: * @return assigned maximum capacity - may be smaller than requested.
0875: * @throws IllegalArgumentException if <code>maxSize</code> is zero or less.
0876: * @throws IllegalArgumentException if the contents
0877: * after truncation would be illegal for the current
0878: * <a href="TextField.html#constraints">input constraints</a>
0879: * @see #getMaxSize
0880: */
0881: public int setMaxSize(int maxSize) {
0882: synchronized (Display.LCDUILock) {
0883:
0884: textFieldLF.lUpdateContents();
0885:
0886: int oldCapacity = buffer.capacity();
0887:
0888: if (oldCapacity == maxSize) {
0889: return maxSize;
0890: }
0891:
0892: buffer.setCapacity(maxSize);
0893:
0894: if (!textFieldLF.lValidate(buffer, constraints)) {
0895: buffer.setCapacity(oldCapacity);
0896: throw new IllegalArgumentException();
0897: }
0898:
0899: // Notify LF that contents has changed due to maxSize
0900: textFieldLF.lSetMaxSize(maxSize);
0901:
0902: return buffer.capacity();
0903: }
0904: }
0905:
0906: /**
0907: * Gets the number of characters that are currently stored in this
0908: * <code>TextField</code>.
0909: * @return number of characters in the <code>TextField</code>
0910: */
0911: public int size() {
0912: synchronized (Display.LCDUILock) {
0913: textFieldLF.lUpdateContents();
0914: return buffer.length();
0915: }
0916: }
0917:
0918: /**
0919: * Gets the current input position. For some UIs this may block and ask
0920: * the user for the intended caret position, and on other UIs this may
0921: * simply return the current caret position.
0922: *
0923: * @return the current caret position, <code>0</code> if at the beginning
0924: */
0925: public int getCaretPosition() {
0926: synchronized (Display.LCDUILock) {
0927: return textFieldLF.lGetCaretPosition();
0928: }
0929: }
0930:
0931: /**
0932: * Sets the input constraints of the <code>TextField</code>. If
0933: * the the current contents
0934: * of the <code>TextField</code> do not match the new
0935: * <code>constraints</code>, the contents are
0936: * set to empty.
0937: *
0938: * @param constraints see <a href="#constraints">input constraints</a>
0939: *
0940: * @throws IllegalArgumentException if constraints is not any of the ones
0941: * specified in <a href="TextField.html#constraints">input constraints</a>
0942: * @see #getConstraints
0943: */
0944: public void setConstraints(int constraints) {
0945: synchronized (Display.LCDUILock) {
0946: setConstraintsImpl(constraints);
0947: }
0948: }
0949:
0950: /**
0951: * Gets the current input constraints of the <code>TextField</code>.
0952: *
0953: * @return the current constraints value (see
0954: * <a href="#constraints">input constraints</a>)
0955: * @see #setConstraints
0956: */
0957: public int getConstraints() {
0958: return constraints;
0959: }
0960:
0961: /**
0962: * Sets a hint to the implementation as to the input mode that should be
0963: * used when the user initiates editing of this <code>TextField</code>. The
0964: * <code>characterSubset</code> parameter names a subset of Unicode
0965: * characters that is used by the implementation to choose an initial
0966: * input mode. If <code>null</code> is passed, the implementation should
0967: * choose a default input mode.
0968: *
0969: * <p>See <a href="#modes">Input Modes</a> for a full explanation of input
0970: * modes. </p>
0971: *
0972: * @param characterSubset a string naming a Unicode character subset,
0973: * or <code>null</code>
0974: *
0975: */
0976: public void setInitialInputMode(String characterSubset) {
0977: synchronized (Display.LCDUILock) {
0978: initialInputMode = characterSubset;
0979: textFieldLF.lSetInitialInputMode(initialInputMode);
0980: }
0981: }
0982:
0983: // ========================================================================
0984: // package private methods
0985: // ========================================================================
0986:
0987: /**
0988: * Creates a new <code>TextField</code> object with the given label, initial
0989: * contents, maximum size in characters, and constraints. Behaves
0990: * the same as the public <code>TextField</code> constructor above except
0991: * for an additional argument <code>forTextBox</code> which signals
0992: * this <code>TextField</code> will be used alone as a
0993: * <code>TextBox</code> widget.
0994: * @param label item label
0995: * @param text the initial contents, or <code>null</code> if the
0996: * <code>TextField</code> is to be empty
0997: * @param maxSize the maximum capacity in characters
0998: * @param constraints see <a href="#constraints">input constraints</a>
0999: * @param forTextBox true if this textField will be used to implement
1000: * a TextBox object. when false, this method's results are
1001: * identical to the public <code>TextField</code> constructor.
1002: * @throws IllegalArgumentException if <code>maxSize</code> is zero or less
1003: * @throws IllegalArgumentException if the value of the constraints
1004: * parameter
1005: * is invalid
1006: * @throws IllegalArgumentException if <code>text</code> is illegal
1007: * for the specified constraints
1008: * @throws IllegalArgumentException if the length of the string exceeds
1009: * the requested maximum capacity
1010: */
1011: TextField(String label, String text, int maxSize, int constraints,
1012: boolean forTextBox) {
1013:
1014: super (label);
1015:
1016: synchronized (Display.LCDUILock) {
1017:
1018: // IllegalArgumentException thrown here
1019: buffer = new DynamicCharacterArray(maxSize);
1020:
1021: // Constraint value is checked here. Since textFieldLF is not
1022: // yet created, no LF notification will happen.
1023: setConstraintsImpl(constraints);
1024:
1025: if (forTextBox) {
1026: itemLF = textFieldLF = LFFactory.getFactory()
1027: .getTextBoxLF(this );
1028: } else {
1029: // Create a LF with empty content
1030: itemLF = textFieldLF = LFFactory.getFactory()
1031: .getTextFieldLF(this );
1032: }
1033: //
1034: // this will use inputClient
1035: // Right now setCharsImpl notifies LF a content change.
1036: // If LF is created as an absolutely last thing then
1037: // setCharsImple here does not need the notification.
1038: if (text == null) {
1039: setCharsImpl(null, 0, 0);
1040: } else {
1041: setCharsImpl(text.toCharArray(), 0, text.length());
1042: }
1043: }
1044: }
1045:
1046: /**
1047: * Deletes characters from the <code>TextField</code>.
1048: *
1049: * <p>The <code>offset</code> and <code>length</code> parameters must
1050: * specify a valid range of characters within
1051: * the contents of the <code>TextField</code>.
1052: * The <code>offset</code> parameter must be within the
1053: * range <code>[0..(size())]</code>, inclusive.
1054: * The <code>length</code> parameter
1055: * must be a non-negative integer such that
1056: * <code>(offset + length) <= size()</code>.</p>
1057: *
1058: * @param offset the beginning of the region to be deleted
1059: * @param length the number of characters to be deleted
1060: *
1061: * @throws IllegalArgumentException if the resulting contents
1062: * would be illegal for the current
1063: * <a href="TextField.html#constraints">input constraints</a>
1064: * @throws StringIndexOutOfBoundsException if <code>offset</code>
1065: * and <code>length</code> do not
1066: * specify a valid range within the contents of the <code>TextField</code>
1067: */
1068: void deleteImpl(int offset, int length) {
1069:
1070: if (length == 0) {
1071: return;
1072: }
1073:
1074: // Update buffer with latest user input
1075: textFieldLF.lUpdateContents();
1076:
1077: // Keep old contents in case we need to restore below
1078: String oldContents = buffer.toString();
1079:
1080: // StringIndexOutOfBoundsException can be thrown here
1081: buffer.delete(offset, length);
1082:
1083: if (!textFieldLF.lValidate(buffer, constraints)) {
1084: // Restore to old contents
1085: buffer.delete(0, buffer.length());
1086: buffer.insert(0, oldContents);
1087: throw new IllegalArgumentException();
1088: }
1089:
1090: // Notify LF that contents has changed due to delete
1091: textFieldLF.lDelete(offset, length);
1092: }
1093:
1094: /**
1095: * Sets the contents of the <code>TextField</code> from a
1096: * character array, replacing the
1097: * previous contents.
1098: *
1099: * @param data the source of the character data
1100: * @param offset the beginning of the region of characters to copy
1101: * @param length the number of characters to copy
1102: * @throws ArrayIndexOutOfBoundsException if <code>offset</code>
1103: * and <code>length</code> do not specify
1104: * a valid range within the data array
1105: * @throws IllegalArgumentException if <code>data</code>
1106: * is illegal for the current
1107: * <a href="TextField.html#constraints">input constraints</a>
1108: * @throws IllegalArgumentException if the text would exceed the current
1109: * maximum capacity
1110: */
1111: void setCharsImpl(char[] data, int offset, int length) {
1112:
1113: if (data == null) {
1114: buffer.delete(0, buffer.length());
1115: } else {
1116:
1117: if (offset < 0 || offset > data.length || length < 0
1118: || length > data.length || offset + length < 0
1119: || offset + length > data.length) {
1120: throw new ArrayIndexOutOfBoundsException();
1121: }
1122:
1123: if (length > buffer.capacity()) {
1124: throw new IllegalArgumentException();
1125: }
1126:
1127: if (length > 0) {
1128: DynamicCharacterArray dca = new DynamicCharacterArray(
1129: length);
1130:
1131: dca.set(data, offset, length);
1132:
1133: if (!textFieldLF.lValidate(dca, constraints)) {
1134: throw new IllegalArgumentException();
1135: }
1136: }
1137:
1138: buffer.set(data, offset, length);
1139: }
1140:
1141: // Notify LF contents has changed due to setChars
1142: textFieldLF.lSetChars();
1143: }
1144:
1145: /**
1146: * Sets the input constraints of the <code>TextField</code>.
1147: * @param constraints see <a href="#constraints">input constraints</a>
1148: *
1149: * @throws IllegalArgumentException if constraints is not any of the ones
1150: * specified in <a href="TextField.html#constraints">input constraints</a>
1151: */
1152: void setConstraintsImpl(int constraints) {
1153:
1154: if ((constraints & CONSTRAINT_MASK) < ANY
1155: || (constraints & CONSTRAINT_MASK) > DECIMAL) {
1156: throw new IllegalArgumentException();
1157: }
1158:
1159: this .constraints = constraints;
1160:
1161: // Since this function is called from Constructor before
1162: // LF is created, checking is necessary.
1163: if (textFieldLF == null) {
1164: return;
1165: }
1166:
1167: textFieldLF.lSetConstraints();
1168:
1169: // If current contents doesn't satisfy new constraints,
1170: // set it to empty.
1171: textFieldLF.lUpdateContents();
1172:
1173: int curLen = buffer.length();
1174: if (curLen > 0 && !textFieldLF.lValidate(buffer, constraints)) {
1175: buffer.delete(0, curLen);
1176: textFieldLF.lDelete(0, curLen);
1177: }
1178: }
1179:
1180: /**
1181: * Inserts data into the buffer.
1182: *
1183: * @param data - data to be inserted
1184: * @param offset - <placeholder>
1185: * @param length - <placeholder>
1186: * @param position - <placeholder>
1187: */
1188: void insertImpl(char data[], int offset, int length, int position) {
1189:
1190: textFieldLF.lUpdateContents();
1191:
1192: int pos = buffer.insert(data, offset, length, position);
1193:
1194: if (!textFieldLF.lValidate(buffer, constraints)) {
1195: buffer.delete(pos, length); // reverse insertion
1196: throw new IllegalArgumentException();
1197: }
1198:
1199: // Notify LF contents has changed due a insertion
1200: textFieldLF.lInsert(data, offset, length, pos);
1201: }
1202:
1203: /**
1204: * Return whether the Item takes user input focus.
1205: *
1206: * @return Always return <code>true</code> so user can scroll
1207: * or highlight selection.
1208: */
1209: boolean acceptFocus() {
1210: return true;
1211: }
1212:
1213: /**
1214: * Notify the item to the effect that it has been recently deleted.
1215: * In addition to default action call TraverseOut for the TextField
1216: */
1217: void itemDeleted() {
1218: textFieldLF.itemDeleted();
1219: super .itemDeleted();
1220: }
1221:
1222: /**
1223: * The look&feel associated with this TextField.
1224: * Set in the constructor.
1225: */
1226: TextFieldLF textFieldLF; // = null
1227:
1228: /** buffer to store the text */
1229: DynamicCharacterArray buffer;
1230:
1231: /** Input constraints */
1232: int constraints;
1233:
1234: /** the initial input mode for when the text field gets focus */
1235: String initialInputMode = null;
1236: }
|