📄 choicetextfield.java
字号:
//#condition polish.usePolishGui
/*
* Created on 27-Feb-2006 at 7:36:20.
*
* Copyright (c) 2004-2006 Robert Virkus / Enough Software
*
* This file is part of J2ME Polish.
*
* J2ME Polish is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* J2ME Polish 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with J2ME Polish; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Commercial licenses are also available, please
* refer to the accompanying LICENSE.txt or visit
* http://www.j2mepolish.org for details.
*/
package de.enough.polish.ui;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
//#if polish.blackberry
//# import de.enough.polish.blackberry.ui.PolishEditField;
//#endif
import de.enough.polish.util.TextUtil;
/**
* <p>Provides a TextField that provides the user with possible matches for the current input.</p>
*
* <p>Copyright Enough Software 2006</p>
* <pre>
* history
* 27-Feb-2006 - rob creation
* </pre>
* @author Robert Virkus, j2mepolish@enough.de
*/
public class ChoiceTextField
//#if polish.LibraryBuild
//# extends FakeTextFieldCustomItem
//#else
extends TextField
//#endif
{
/**
* The matching mode that selects choices that start with the same characters as the current input
*/
public static final int MATCH_STARTS_WITH = 0;
/**
* The matching mode that selects choices that contain the same characters as the current input
*/
public static final int MATCH_INDEX_OF = 1;
private final boolean isAllowFreeTextEntry;
private final Container choicesContainer;
private String[] choices;
private String[] lowerCaseChoices;
private int numberOfMatches;
private boolean isInChoice;
private Item[] choiceItems;
private String lastMatchingText;
private Style originalStyle;
private Style focusingStyle;
private int matchMode;
private boolean reenableCaretFlashing = true;
private int choicesYOffsetAdjustment;
private boolean isOpen;
private Style choiceItemStyle;
private String appendChoiceDelimiter;
private boolean isAppendMode;
private int appendDelimiterIndex = -1;
private boolean choiceTriggerEnabled;
private char choiceTrigger;
private boolean choiceTriggerAllowInputBeforeTrigger;
/**
* Creates a new ChoiceTextField.
*
* @param label the label
* @param text the current text
* @param maxSize the maximum size for the input
* @param constraints input constraints, TextField.ANY for no constraints
* @param availableChoices a list of available texts for the user
* @param allowFreeTextEntry true when the user should be allowed to enter any text that does not match any existing choice
*/
public ChoiceTextField(String label, String text, int maxSize, int constraints, String[] availableChoices, boolean allowFreeTextEntry) {
this(label, text, maxSize, constraints, availableChoices, allowFreeTextEntry, false, ";", null);
}
/**
* Creates a new ChoiceTextField.
*
* @param label the label
* @param text the current text
* @param maxSize the maximum size for the input
* @param constraints input constraints, TextField.ANY for no constraints
* @param availableChoices a list of available texts for the user
* @param allowFreeTextEntry true when the user should be allowed to enter any text that does not match any existing choice
* @param style the style for this item
*/
public ChoiceTextField(String label, String text, int maxSize, int constraints, String[] availableChoices, boolean allowFreeTextEntry, Style style) {
this(label, text, maxSize, constraints, availableChoices, allowFreeTextEntry, false, ";", style );
}
/**
* Creates a new ChoiceTextField.
*
* @param label the label
* @param text the current text
* @param maxSize the maximum size for the input
* @param constraints input constraints, TextField.ANY for no constraints
* @param availableChoices a list of available texts for the user
* @param allowFreeTextEntry true when the user should be allowed to enter any text that does not match any existing choice
* @param appendChoice true when the selected choices should be appended to the text rather than replacing the text
* @param appendChoiceDelimiter the character that separates several selections, e.g. '\n' or ';'
*/
public ChoiceTextField(String label, String text, int maxSize, int constraints, String[] availableChoices, boolean allowFreeTextEntry, boolean appendChoice, String appendChoiceDelimiter) {
this(label, text, maxSize, constraints, availableChoices, allowFreeTextEntry, appendChoice, appendChoiceDelimiter, null);
}
/**
* Creates a new ChoiceTextField.
*
* @param label the label
* @param text the current text
* @param maxSize the maximum size for the input
* @param constraints input constraints, TextField.ANY for no constraints
* @param availableChoices a list of available texts for the user
* @param allowFreeTextEntry true when the user should be allowed to enter any text that does not match any existing choice
* @param appendChoice true when the selected choices should be appended to the text rather than replacing the text
* @param appendChoiceDelimiter the character that separates several selections, e.g. "\n" or ";" or null.
* @param style the style for this item
*/
public ChoiceTextField(String label, String text, int maxSize, int constraints, String[] availableChoices, boolean allowFreeTextEntry, boolean appendChoice, String appendChoiceDelimiter, Style style) {
super(label, text, maxSize, constraints, style);
this.choices = availableChoices;
if (availableChoices != null) {
this.lowerCaseChoices = new String[ availableChoices.length ];
for (int i = 0; i < availableChoices.length; i++) {
String choice = availableChoices[i];
this.lowerCaseChoices[i] = choice.toLowerCase();
}
this.choiceItems = new Item[ availableChoices.length ];
}
this.isAllowFreeTextEntry = allowFreeTextEntry;
this.choicesContainer = new Container( false );
//#if polish.Container.allowCycling != false
this.choicesContainer.allowCycling = false;
//#endif
//#if polish.usePolishGui && !polish.LibraryBuild
this.choicesContainer.parent = this;
//#endif
this.isAppendMode = appendChoice;
this.appendChoiceDelimiter = appendChoiceDelimiter;
if (appendChoiceDelimiter != null && appendChoiceDelimiter.length() > 0) {
this.emailSeparatorChar = appendChoiceDelimiter.charAt(0);
}
}
/* (non-Javadoc)
* @see de.enough.polish.ui.FakeTextFieldCustomItem#initContent(int, int)
*/
protected void initContent(int firstLineWidth, int lineWidth) {
super.initContent(firstLineWidth, lineWidth);
this.choicesContainer.relativeY = this.contentHeight + this.paddingVertical;
}
/**
* Enables that available choices should (only) be shown after the specified character is entered.
* This method automatically enables the append mode.
*
* @param choiceTrigger the trigger for showing choice
* @param allowChoicesBeforeTrigger true when the user should be able to add choices before he has entered the trigger character
*/
public void setChoiceTrigger( char choiceTrigger, boolean allowChoicesBeforeTrigger ) {
this.isAppendMode = true;
this.choiceTriggerEnabled = true;
this.choiceTrigger = choiceTrigger;
this.choiceTriggerAllowInputBeforeTrigger = allowChoicesBeforeTrigger;
}
/**
* Sets the available choices.
* Use this method in conjunction with an ItemStateListener for using complex rules for creating choices.
*
* @param choices the new choices, null when no choices are given
*/
public void setChoices( String[] choices ) {
this.choicesContainer.clear();
if ( choices == null ) {
this.choiceItems = new Item[ 0 ];
openChoices( false );
return;
}
this.choiceItems = new Item[ choices.length ];
for (int i = 0; i < choices.length; i++) {
String choiceText = choices[i];
Item item = new ChoiceItem( choiceText, null, Choice.IMPLICIT, this.choiceItemStyle );
this.choiceItems[i] = item;
this.choicesContainer.add( item );
}
this.choices = choices;
openChoices( choices.length > 0 );
}
/**
* Sets the available choices.
* Use this method in conjunction with an ItemStateListener for using complex rules for creating choices.
* The given items should implement the "toString()" method and return the correct string value for the text field.
*
* @param choices the new choices, null when no choices are available
*/
public void setChoices( Item[] choices ) {
this.choicesContainer.clear();
if ( choices == null ) {
this.choiceItems = new Item[ 0 ];
openChoices( false );
return;
}
this.choiceItems = choices;
for (int i = 0; i < choices.length; i++) {
Item item = choices[i];
this.choicesContainer.add( item );
}
openChoices( choices.length > 0 );
}
/**
* Sets the matching algorithm that is used for finding out whether an available choices matches the input of the user.
*
* @param mode the matching mode, the default mode is ChoiceTextField.MATCH_STARTS_WITH, so the user input is compared with the start of the available choices.
* @see #MATCH_STARTS_WITH
* @see #MATCH_INDEX_OF
* @see #setChoices(Item[]) for using complex matching rules
* @see #setChoices(String[]) for using complex matching rules
*/
public void setMatchMode( int mode ) {
this.matchMode = mode;
}
/**
* Retrieves the matching algorithm that is used for finding out whether an available choices matches the input of the user.
*
* @return the matching mode, the default mode is ChoiceTextField.MATCH_STARTS_WITH, so the user input is compared with the start of the available choices.
* @see #MATCH_STARTS_WITH
* @see #MATCH_INDEX_OF
* @see #setChoices(Item[]) for using complex matching rules
* @see #setChoices(String[]) for using complex matching rules
*/
public int getMatchMode() {
return this.matchMode;
}
/* (non-Javadoc)
* @see de.enough.polish.ui.TextField#defocus(de.enough.polish.ui.Style)
*/
protected void defocus(Style origStyle) {
super.defocus(origStyle);
if (!this.isAllowFreeTextEntry && this.numberOfMatches > 0) {
Item item = this.choicesContainer.get( 0 );
if (item instanceof StringItem) {
setString( ((StringItem)item).getText() );
} else {
setString( item.toString() );
}
}
this.numberOfMatches = 0;
this.choicesContainer.clear();
openChoices(false);
}
/* (non-Javadoc)
* @see de.enough.polish.ui.TextField#animate()
*/
public boolean animate() {
boolean animated = super.animate();
if (this.numberOfMatches > 0) {
animated |= this.choicesContainer.animate();
}
return animated;
}
/* (non-Javadoc)
* @see de.enough.polish.ui.TextField#focus(de.enough.polish.ui.Style, int)
*/
protected Style focus(Style focStyle, int direction) {
this.originalStyle = super.focus(focStyle, direction);
this.focusingStyle = this.style;
return this.originalStyle;
}
/* (non-Javadoc)
* @see de.enough.polish.ui.TextField#handleKeyPressed(int, int)
*/
protected boolean handleKeyPressed(int keyCode, int gameAction) {
//#debug
//# System.out.println("keyPressed( keyCode=" + keyCode + ", gameAction=" + gameAction + ", isInChoice=" + this.isInChoice + " )");
if (this.isInChoice) {
if ( this.choicesContainer.handleKeyPressed(keyCode, gameAction) ) {
//#debug
//# System.out.println("keyPressed handled by choices container");
return true;
}
//System.out.println("focusing textfield again, isFocused=" + this.isFocused);
enterChoices( false );
if (gameAction == Canvas.FIRE) {
// option has been selected!
Item item = this.choicesContainer.getFocusedItem();
String choiceText;
if ( item instanceof ChoiceItem ) {
choiceText = ((ChoiceItem) item).getText();
} else if (item != null) {
choiceText = item.toString();
} else {
return false;
}
if (this.isAppendMode) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -