⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dec01_ericg.txt

📁 TechTips j2me的常用技巧. 网络功能
💻 TXT
📖 第 1 页 / 共 2 页
字号:
These components are referred to as "items" because they all 
extend the javax.microedition.lcdui.Item class. Some of the items 
are editable by the user, the include the ChoiceGroup, Gauge, 
DateField and TextField items.

Sometimes the application needs to know when an editable item's 
value or selection changes. For example, the application might want 
to update the text in a label based on the current value of 
a gauge. Or an application might want to do some preliminary 
validation of input from a text field. This is where the 
ItemStateListener interface is important. The interface is very 
simple, consisting of single method:

package javax.microedition.lcdui;

public interface ItemStateListener {
    void itemStateChanged( Item item );
}

If you want to be notified of item state changes, simply register 
(with the form) an object that implements the ItemStateListener 
interface:

Form f = new Form();
ItemStateListener listener = ....; //

form.setItemStateListener( listener );

Whenever an editable item on the form changes state because of 
user interaction, it invokes the listener's itemStateChanged
method. The item whose state changed is passed as the only 
argument. Note that the notification occurs after the item's 
state has changed -- if you need to know the old state you must 
keep track of it separately.

Let's use the ItemStateListener to perform some validation of 
numeric input. As discussed in the November 14, 2001 Tech Tip, 
"Developing Custom Components for the Mobile Information Device 
Profile" 
(http://java.sun.com/jdc/J2METechTips/2001/tt1114.html#tip2 ),
the type of input accepted by a TextField component can be 
constrained in simple ways. A text field can be limited to 
accepting numeric input by setting the TextField.NUMERIC
constraint. Unfortunately, there is no validation beyond these 
simple constraints. For example, suppose your application wants 
the user to enter a phone number. Although the TextField class
supports a PHONENUMBER constraint, it might be too limited or 
somehow inappropriate for your purposes. Using ItemStateListener,
you can build a phone number entry form that allows only
specific kinds of phone numbers.  In fact, in this tip you'll
see a more general form, called NumericInputForm, that can be 
used for arbitrary numeric input, not just phone numbers.

A NumericInputForm has two items on it: a labeled TextField and 
a StringItem. The TextField is where the user enters the phone 
number. It has a NUMERIC constraint -- in other words, the user 
enters an unformatted number. (This works quite well on MIDP 
devices because it means users can use the keypad to directly 
enter numbers without having to cycle through letters and 
symbols, as with general text input.) 

The StringItem displays the formatted form of the number if it 
matches one of the input masks. The form has two Command objects 
associated with it: a "Done" command and a "Cancel" command. The 
"Cancel" command is always active, but the "Done" command is only
enabled when the user's input matches one of the input masks. 
This means that the user can proceed to the next form only by 
canceling the current form or by entering a value that matches
one of the masks. Here's the code for NumericInputForm:

import javax.microedition.lcdui.*;

// Defines a form that prompts the user to
// enter a numeric value and checks it against
// a set of input masks.  If the number matches
// a mask, the "Done" command is made visible
// and the user can then proceed to the next
// form.

public class NumericInputForm extends Form
                     implements ItemStateListener {

    public static final Command DONE_COMMAND =
             new Command( "Done", Command.OK, 1 );

    public static final Command CANCEL_COMMAND =
             new Command( 
                         "Cancel", Command.CANCEL, 1 );

    private String[]   masks;
    private int[]      digits;
    private Command    done;
    private Command    cancel;
    private TextField  field;
    private StringItem match;

    public NumericInputForm( String title,
                             String label,
                             String[] masks,
                             String value ){
        this( title, label, masks, value,
              null, null );
    }

    public NumericInputForm( String title,
                             String label,
                             String[] masks,
                             String value,
                             Command done,
                             Command cancel ){
        super( title );

        this.masks  = masks;
        this.done   = ( done != null ? done
                                   : DONE_COMMAND );
        this.cancel = ( cancel != null ? cancel
                                   : CANCEL_COMMAND );

        digits = new int[ masks.length ];

        int maxlen = 0;
        for( int i = 0; i < masks.length; ++i ){
            int mlen = countDigitsInMask( masks[i] );
            if( mlen > maxlen ) maxlen = mlen;
            digits[i] = mlen;
        }

        field = new TextField( label, value,
                               maxlen,
                               TextField.PHONENUMBER );

        append( field );

        match = new StringItem( null, "" );
        append( match );

        adjustState();
        addCommand( this.cancel );

        setItemStateListener( this );
    }

    // Adjust the state of the form based on changes
    // made to the input field.  Adds or removes the
    // "done" command as appropriate, and also adjusts
    // the value of the label showing the masked
    // input that matches, if any.

    protected void adjustState(){
        String val = field.getString();
        String applied = null;

        for( int i = 0; i < masks.length; ++i ){
            applied = matches( 
                            val, digits[i], masks[i] );
            if( applied != null ){
                break;
            }
        }

        if( applied != null ){
            match.setText( applied );
            addCommand( done );
        } else {
            match.setText( "" );
            removeCommand( done );
        }
    }

    // Figure out how many digits need to be entered
    // for a particular mask.

    private int countDigitsInMask( String mask ){
        int count = 0;

        for( int i = 0; i < mask.length(); ++i ){
            char ch = mask.charAt( i );

            if( ch == '#' || Character.isDigit( ch ) ){
                ++count;
            }
        }

        return count;
    }

    // Return the masked value.

    public String getMaskedValue(){
        return match.getText();
    }

    // Return the raw value (numbers only).

    public String getRawValue(){
        return field.getString();
    }

    // Our callback, just calls adjustState.

    public void itemStateChanged( Item item ){
        adjustState();
    }

    // Check to see if the given string matches
    // the given mask.

    protected String matches( String value,
                              int digits,
                              String mask ){
        if( value.equals( mask ) ) return value;

        int vlen = value.length();
        if( vlen != digits ) return null;
        int mlen = mask.length();
        int vindex = 0;

        StringBuffer b = new StringBuffer( mlen );
        for( int i = 0; i < mlen; ++i ){
            char mch = mask.charAt( i );
            char vch = mch;

            if( mch == '#' ){
                vch = value.charAt( vindex++ );
            } else if( Character.isDigit( mch ) ){
                vch = value.charAt( vindex++ );
                if( mch != vch ) return null;
            }

            b.append( vch );
        }

        return b.toString();
    }

    // Adjust the field's value.

    public void setRawValue( String value ){
        field.setString( value );
        adjustState();
    }
}

Notice that the constructor takes an array of strings. These 
strings are the masks that are accepted by the form. Use the '#' 
character to indicate a placeholder for a number. For example, to 
accept North American style phone numbers, declare the masks like 
this:

String[] masks = new String[]{ "###-####",
                               "(###) ###-####" };

Here's a simple MIDlet that uses the NumericInputForm class to 
prompt the user for a phone number.

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

// A simple test of the NumericInputForm class
// that prompts the user to enter a phone number
// in one of two acceptable formats.

public class NumericInputTest extends MIDlet {

    private Display display;
    private Command exitCommand =
                         new Command( "Exit",
                                     Command.EXIT, 1 ); 
    private Command okCommand =
                         new Command( "OK",
                                      Command.OK, 1 );

    public NumericInputTest(){
    }

    protected void destroyApp( boolean unconditional )
                    throws MIDletStateChangeException {
        exitMIDlet();
    }

    protected void pauseApp(){
    }

    protected void startApp()
                    throws MIDletStateChangeException {
        if( display == null ){ 
            initMIDlet();
        }
    }

    private void initMIDlet(){
        display = Display.getDisplay( this );
        display.setCurrent( new PromptForPhone() );
    }

    public void exitMIDlet(){
        notifyDestroyed();
    }

    private String[] phoneMasks =
                       new String[]{ "###-####",
                                     "(###) ###-####" };

    // A subclass of NumericInputForm that does nothing
    // but set the masks and the initial values and
    // registers itself as a command listener.

    class PromptForPhone extends NumericInputForm
                          implements CommandListener {

        public PromptForPhone(){
            super( "Test", "Enter a phone number:",
                   phoneMasks, "" );

            setCommandListener( this );
        }

        // Called when the user presses either the
        // "done" or "cancel" commands on the
        // numeric input form.

        public void commandAction( Command c,
                                   Displayable d ){
            if( c == CANCEL_COMMAND ){
                exitMIDlet();
            } else {
                Alert a = new Alert( "Result" );
                a.setString( "You entered the number " +
                             getMaskedValue() +
                             " from the string " +
                             getRawValue() );
                a.setTimeout( Alert.FOREVER );
                display.setCurrent( a, this );
                setRawValue( "" );
            }
        }
    }
}

Several improvements can be made to the NumericInputForm class.  
It could allow for (and display) partial matches, for example, or 
it could dynamically adjust the constraints of the underlying
TextField to allow the user to enter more than just numeric 
characters.

.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

IMPORTANT: Please read our Terms of Use and Privacy policies:
http://www.sun.com/share/text/termsofuse.html
http://www.sun.com/privacy/ 

* FEEDBACK
  Comments? Send your feedback on the J2ME Tech Tips to: 
  
  jdc-webmaster@sun.com

* SUBSCRIBE/UNSUBSCRIBE
  - To subscribe, go to the subscriptions page,
    (http://developer.java.sun.com/subscription/), choose
    the newsletters you want to subscribe to and click "Update".
  - To unsubscribe, go to the subscriptions page,
    (http://developer.java.sun.com/subscription/), uncheck the
    appropriate checkbox, and click "Update".
  - To use our one-click unsubscribe facility, see the link at 
    the end of this email:
    
- ARCHIVES
You'll find the J2ME Tech Tips archives at:

http://java.sun.com/jdc/J2METechTips/index.html


- COPYRIGHT
Copyright 2001 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA.

This document is protected by copyright. For more information, see:

http://java.sun.com/jdc/copyright.html

J2ME Tech Tips 
December 17, 2001

Sun, Sun Microsystems, Java, Java Developer Connection, J2ME, and
J2SE are trademarks or registered trademarks of Sun Microsystems, 
Inc. in the United States and other countries.




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -