textarea.java

来自「j2me设计的界面包」· Java 代码 · 共 804 行 · 第 1/2 页

JAVA
804
字号
/*
 * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package com.sun.lwuit;

import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.geom.Dimension;
import com.sun.lwuit.geom.Rectangle;
import com.sun.lwuit.plaf.Style;
import com.sun.lwuit.plaf.UIManager;
import java.util.Vector;

/**
 * An optionally multi-line editable region that can display text and allow a user to edit it.
 * Depending on the platform editing might occur in a new screen. Notice that when creating
 * a text area with one row it will act as a text field and never grow beyond that, however 
 * when assigning a greater number of rows the text area becomes multi-line with a minimum
 * number of visible rows, the text area will grow based on its content.
 *
 * @author Chen Fishbein
 */
public class TextArea extends Component {
    private static int defaultMaxSize = 124;
    private static boolean autoDegradeMaxSize = false;
    private static boolean hadSuccessfulEdit = false;
    
    /**
     * Allows any type of input into a text field, if a constraint is not supported
     * by an underlying implementation this will be the default.
     */
    public static final int ANY = 0;

    /**
     * The user is allowed to enter an e-mail address.
     */
    public static final int EMAILADDR = 1;

    /**
     * The user is allowed to enter only an integer value.
     */
    public static final int NUMERIC = 2;

    /**
     * The user is allowed to enter a phone number.
     */
    public static final int PHONENUMBER = 3;

    /**
     * The user is allowed to enter a URL.
     */
    public static final int URL = 4;

    /**
     * The user is allowed to enter numeric values with optional decimal 
     * fractions, for example "-123", "0.123", or ".5".
     */
    public static final int DECIMAL = 5;
    
    /**
     * Indicates that the text entered is confidential data that should be 
     * obscured whenever possible.
     */
    public static final int PASSWORD = 0x10000;

    /**
     *  Indicates that editing is currently disallowed.
     */
    public static final int UNEDITABLE = 0x20000;

    /**
     * Indicates that the text entered is sensitive data that the 
     * implementation must never store into a dictionary or table for use 
     * in predictive, auto-completing, or other accelerated input schemes.
     */
    public static final int SENSITIVE = 0x40000;

    /**
     * Indicates that the text entered does not consist of words that are 
     * likely to be found in dictionaries typically used by predictive input 
     * schemes.
     */
    public static final int NON_PREDICTIVE= 0x80000;

    /**
     * This flag is a hint to the implementation that during text editing, 
     * the initial letter of each word should be capitalized.
     */
    public static final int INITIAL_CAPS_WORD = 0x100000;

    /**
     * This flag is a hint to the implementation that during text editing, 
     * the initial letter of each sentence should be capitalized.
     */
    public static final int INITIAL_CAPS_SENTENCE = 0x200000;
    //private int modifierFlag = 0x00000;
             
    /**
     * Input constraint which should be one of CONSTRAINT_ANY, CONSTRAINT_NUMERIC,
     * CONSTRAINT_PHONENUMBER, CONSTRAINT_URL or CONSTRAINT_EMAIL
     */
    private int constraint = ANY;
    
    private  String text="";
    
    private  boolean editable = true;
    
    private int maxSize = defaultMaxSize ; //maximum size (number of characters) that can be stored in this TextField.
    
    private int rows = 1;
    
    private int columns = 1;
    
    // problematic  maxSize = 20; //maximum size (number of characters) that can be stored in this TextField.
    
    private static String id = "TextArea";
    
    private Vector rowStrings;
    private int widthForRowCalculations = -1;

    private int rowsGap = 2;

    private boolean triggerClose;

    private Vector actionListeners = null;
    
    /**
     * Indicates that the text area should "grow" in height based on the content beyond the
     * limits indicate by the rows variable
     */
    private boolean growByContent = true;
    
    /**
     * Creates an area with the given rows and columns
     * 
     * @param rows the number of rows
     * @param columns - the number of columns
     */
    public TextArea(int rows, int columns){
        this("", defaultMaxSize, rows, columns, ANY);
    }

    /**
     * Creates an area with the given rows, columns and constrint 
     * 
     * @param rows the number of rows
     * @param columns - the number of columns
     * @param constraint one of ANY, EMAILADDR, NUMERIC, PHONENUMBER, URL, DECIMAL
     * it can be bitwised or'd with one of PASSWORD, UNEDITABLE, SENSITIVE, NON_PREDICTIVE,
     * INITIAL_CAPS_SENTENCE, INITIAL_CAPS_WORD. E.g. ANY | PASSWORD.
     */
    public TextArea(int rows, int columns, int constraint){
        this("", defaultMaxSize, rows, columns, constraint);
    }
    
    /**
     * Creates an area with the given text, rows and columns
     * 
     * @param text the text to be displayed; if text is null, the empty 
     * string "" will be displayed
     */
    public TextArea(String text, int rows, int columns){
        this(text,defaultMaxSize, rows, columns, ANY); //String , maxSize, constraints= 0 (ANY)
    }

    /**
     * Creates an area with the given text, rows, columns and constrint 
     * 
     * @param text the text to be displayed; if text is null, the empty 
     * string "" will be displayed
     * @param rows the number of rows
     * @param columns - the number of columns
     * @param constraint one of ANY, EMAILADDR, NUMERIC, PHONENUMBER, URL, DECIMAL
     * it can be bitwised or'd with one of PASSWORD, UNEDITABLE, SENSITIVE, NON_PREDICTIVE,
     * INITIAL_CAPS_SENTENCE, INITIAL_CAPS_WORD. E.g. ANY | PASSWORD.
     */
    public TextArea(String text, int rows, int columns, int constraint){
        this(text,defaultMaxSize, rows, columns, constraint); 
    }

    /**
     * Creates an area with the given text and maximum size, this constructor
     * will create a single line text area similar to a text field! 
     * 
     * @param text the text to be displayed; if text is null, the empty 
     * string "" will be displayed
     * @param maxSize text area maximum size
     */
    public TextArea(String text, int maxSize){
        this(text,maxSize, 1, 1, ANY); //String , maxSize, constraints= 0 (ANY)
    }
    
    /**
     * Creates an area with the given text, this constructor
     * will create a single line text area similar to a text field! 
     * 
     * @param text the text to be displayed; if text is null, the empty 
     * string "" will be displayed
     */
    public TextArea(String text) {
        this(text, Math.max(defaultMaxSize, text.length()), 1, 1, ANY); //String , maxSize, constraints= 0 (ANY)
    }

    /**
     * Creates an empty text area, this constructor
     * will create a single line text area similar to a text field! 
     */
    public TextArea() {
        this("");
    }
    
    /**
     * Creates an area with the given text, maximum size, rows, columns and constrint 
     * 
     * @param text the text to be displayed; if text is null, the empty 
     * string "" will be displayed
     * @param maxSize text area maximum size
     * @param rows the number of rows
     * @param columns - the number of columns
     * @param constraint one of ANY, EMAILADDR, NUMERIC, PHONENUMBER, URL, DECIMAL
     * it can be bitwised or'd with one of PASSWORD, UNEDITABLE, SENSITIVE, NON_PREDICTIVE,
     * INITIAL_CAPS_SENTENCE, INITIAL_CAPS_WORD. E.g. ANY | PASSWORD.
     */
    private TextArea(String text, int maxSize, int rows, int columns, int constraint){
        this.maxSize = maxSize;
        setText(text);
        setConstraint(constraint);
        this.rows = rows;
        this.columns = columns;
        setSmoothScrolling(false);
    }

    /**
     * Sets the constraint 
     * 
     * @param constraint one of ANY, EMAILADDR, NUMERIC, PHONENUMBER, URL, DECIMAL
     * it can be bitwised or'd with one of PASSWORD, UNEDITABLE, SENSITIVE, NON_PREDICTIVE,
     * INITIAL_CAPS_SENTENCE, INITIAL_CAPS_WORD. E.g. ANY | PASSWORD.
     */
    public void setConstraint(int constraint) {
        this.constraint = constraint;
    }


    /**
     * Returns the editing constraint value
     * 
     * @return the editing constraint value
     * @see #setConstraint
     */
    public int getConstraint() {
        return constraint;
    }

    /**
     * Sets the text within this text area
     * 
     * @param t new value for the text area
     */
    public void setText(String t) {
        this.text = (t != null) ? t : "";
        setShouldCalcPreferredSize(true);
        if(maxSize < text.length()) {
            maxSize = text.length() + 1;
        }
        // special case to make the text field really fast...
        rowStrings=null; //zero the vector inorder to initialize it on the next paint
        repaint();
    }

    /**
     * Returns the text in the text area
     * 
     * @return the text in the text area
     */
    public String getText() {
        return text;
    }
    
    /**
     * Returns true if this area is editable
     * 
     * @return true if this area is editable
     */
    public boolean isEditable() {
        return editable;
    }

    /**
     * Sets this text area to be editable or readonly
     * 
     * @param b true is text are is editable; otherwise false
     */
    public void setEditable(boolean b) {
        editable = b;
    }

    /**
     * Returns the maximum size for the text area
     * 
     * @return the maximum size for the text area
     */
    public int getMaxSize() {
        return maxSize;
    }

    /**
     * Sets the maximum size of the text area
     * 
     * @param maxSize the maximum size of the text area
     */
    public void setMaxSize(int maxSize) {
        this.maxSize = maxSize;
    }
    
    /**
     * @inheritDoc
     */
    public void keyPressed(int keyCode) {
        super.keyPressed(keyCode);
        
        int action = com.sun.lwuit.Display.getInstance().getGameAction(keyCode);

        // this works around a bug where fire is also a softkey on devices such as newer Nokia
        // series 40's (e.g. the Nokia emulator). It closes its native text box on fire then
        // as a result of a Nokia bug we get the key released of that closing and assume the
        // users wants to edit the text... When means the only way to exit the native text box
        // is via the cancel option (after pressing OK once).
        triggerClose = action == Display.GAME_FIRE;

        //scroll the TextArea
        Rectangle rect = new Rectangle(getScrollX(), getScrollY(), getWidth(), getHeight());
        Font textFont = getStyle().getFont();
        if(action == Display.GAME_DOWN){
            if((getScrollY() + getHeight()) <(rowsGap + getStyle().getFont().getHeight()) * getLines()) {
                rect.setY(rect.getY() + textFont.getHeight() + rowsGap);
                scrollRectToVisible(rect, this);
            } else {
                setHandlesInput(false);
            }
        }else if(action == Display.GAME_UP){
            if(getScrollY() > 0) {
                rect.setY(Math.max(0, rect.getY() - textFont.getHeight() - rowsGap));
                scrollRectToVisible(rect, this);
            } else {
                setHandlesInput(false);
            }
        }
    }
    
    
    /**
     * @inheritDoc
     */
    protected void fireClicked() {
        onClick();
    }
    
    /**
     * @inheritDoc
     */
    protected boolean isSelectableInteraction() {
        return editable;
    }

    /**
     * @inheritDoc
     */
    public void keyReleased(int keyCode) {
        int action = com.sun.lwuit.Display.getInstance().getGameAction(keyCode);
        if(isEditable()){
            // this works around a bug where fire is also a softkey on devices such as newer Nokia
            // series 40's
            if (triggerClose && action == Display.GAME_FIRE) {
                triggerClose = false;
                onClick();
                return;
            }
        }
    }
    

⌨️ 快捷键说明

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