You Are Here:

Community: Wiki

This page was last modified 09:07, 8 June 2009.

J2ME Custom Text Input

From Forum Nokia Wiki


Here is a sample Midlet: Media:CustomInputMidlet.zip

Here is a basic example showing how to create a custom text input using J2me and Canvas, things that is often needed when using low level graphics (e.g. for games).

In this code, you can:

  • define which characters map to each key
  • define blinking interval
  • define max interval between subsequent key presses
  • move left/right within the text
  • delete text

A lot of features are missing, so if you want to implement them you're welcome :)

package com.jappit.custominput.screen;
 
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
 
public class CustomInputCanvas extends Canvas implements Runnable
{	
	static final char[] KEY_NUM1_CHARS = new char[]{'.', '?', '!'};
	static final char[] KEY_NUM2_CHARS = new char[]{'a', 'b', 'c'};
	static final char[] KEY_NUM3_CHARS = new char[]{'d', 'e', 'f'};
	static final char[] KEY_NUM4_CHARS = new char[]{'g', 'h', 'i'};
	static final char[] KEY_NUM5_CHARS = new char[]{'j', 'k', 'l'};
	static final char[] KEY_NUM6_CHARS = new char[]{'m', 'n', 'o'};
	static final char[] KEY_NUM7_CHARS = new char[]{'p', 'q', 'r', 's'};
	static final char[] KEY_NUM8_CHARS = new char[]{'t', 'u', 'v'};
	static final char[] KEY_NUM9_CHARS = new char[]{'w', 'x', 'y', 'z'};
	static final char[] KEY_NUM0_CHARS = new char[]{' '};
	
	int clearKeyCode = Integer.MIN_VALUE;
	
	StringBuffer currentText = new StringBuffer();
	String currentString = new String();
	
	int lastPressedKey = Integer.MIN_VALUE;
	int currentKeyStep = 0;
	
	Font inputFont = null;
	int inputWidth = 0;
	int inputHeight = 0;
	int inputTranslationX = 0;
	
	long lastKeyTimestamp = 0;
	long maxKeyDelay = 500L;
	
	int caretIndex = 0;
	int caretLeft = 0;
	boolean caretBlinkOn = true;
	long caretBlinkDelay = 500L;
	long lastCaretBlink = 0;
	
	boolean goToNextChar = true;
	
	public CustomInputCanvas()
	{
		new Thread(this).start();
		
		inputFont = Font.getDefaultFont();
		
		inputWidth = getWidth();
		
		inputHeight = inputFont.getHeight();
	}
	
	public char[] getChars(int key)
	{
		switch(key)
		{
		case Canvas.KEY_NUM1: return KEY_NUM1_CHARS;
		case Canvas.KEY_NUM2: return KEY_NUM2_CHARS;
		case Canvas.KEY_NUM3: return KEY_NUM3_CHARS;
		case Canvas.KEY_NUM4: return KEY_NUM4_CHARS;
		case Canvas.KEY_NUM5: return KEY_NUM5_CHARS;
		case Canvas.KEY_NUM6: return KEY_NUM6_CHARS;
		case Canvas.KEY_NUM7: return KEY_NUM7_CHARS;
		case Canvas.KEY_NUM8: return KEY_NUM8_CHARS;
		case Canvas.KEY_NUM9: return KEY_NUM9_CHARS;
		case Canvas.KEY_NUM0: return KEY_NUM0_CHARS;
		}
		return null;
	}
	boolean isClearKey(int key)
	{
		return key == -8;
	}
	
	void clearChar()
	{
		if(currentText.length() > 0 && caretIndex > 0)
		{
			caretIndex--;
			
			currentText.deleteCharAt(caretIndex);
			
			currentString = currentText.toString();
		}
	}
	void updateCaretPosition()
	{
		caretLeft = inputFont.substringWidth(currentString, 0, caretIndex);
		
		if(caretLeft + inputTranslationX < 0)
		{
			inputTranslationX = - caretLeft;
		}
		else if(caretLeft + inputTranslationX > inputWidth)
		{
			inputTranslationX = inputWidth - caretLeft;
		}
	}
	public void keyPressed(int key)
	{
		int gameAction = getGameAction(key);
		
		System.out.println("KEY: " + key + ", " + gameAction);
		
		if(isClearKey(key))
		{
			clearChar();
			
			updateCaretPosition();
			
			goToNextChar = true;
		}
		else if(key >= KEY_NUM0 && key <= KEY_NUM9)
		{
			writeKeyPressed(key);
		}
		else if(gameAction == Canvas.LEFT)
		{
			if(caretIndex > 0)
			{
				caretIndex--;
				
				updateCaretPosition();
				
				goToNextChar = true;
			}
		}
		else if(gameAction == Canvas.RIGHT)
		{
			if(caretIndex < currentText.length())
			{
				if(goToNextChar)
					caretIndex++;
				
				updateCaretPosition();
				
				goToNextChar = true;
			}
		}
	}
	public void writeKeyPressed(int key)
	{
		if(goToNextChar || key != lastPressedKey)
		{
			goToNextChar = true;
			
			lastPressedKey = key;
			
			currentKeyStep = 0;
		}
		else
		{
			currentKeyStep++;
		}
 
		char[] chars = getChars(key);
		
		if(chars != null)
		{
			if(currentKeyStep >= chars.length)
			{
				currentKeyStep -= chars.length;
			}
			if(goToNextChar)
			{
				currentText.insert(caretIndex, chars[currentKeyStep]);
				
				caretIndex++;
			}
			else
			{
				currentText.setCharAt(caretIndex - 1, chars[currentKeyStep]);
			}
			currentString = currentText.toString();
			
			updateCaretPosition();
			
			lastKeyTimestamp = System.currentTimeMillis();
			
			goToNextChar = false;
		}
	}
	
	public void checkTimestamps()
	{
		long currentTime = System.currentTimeMillis();
		
		if(lastCaretBlink + caretBlinkDelay < currentTime)
		{
			caretBlinkOn = !caretBlinkOn;
			
			lastCaretBlink = currentTime;
		}
		
		if(!goToNextChar && lastKeyTimestamp + maxKeyDelay < currentTime)
		{
			goToNextChar = true;
		}
	}
	
	public void run()
	{
		while(true)
		{
			checkTimestamps();
			
			repaint();
			
			try
			{
				synchronized(this)
				{
					wait(50L);
				}
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
	
	public void paint(Graphics g)
	{
		g.setFont(inputFont);
		
		g.setColor(0xffffff);
		
		g.fillRect(0, 0, getWidth(), getHeight());
		
		g.setColor(0x000000);
		
		g.translate(inputTranslationX, 0);
		
		g.drawString(currentString, 0, 0, Graphics.LEFT | Graphics.TOP);
		
		if(caretBlinkOn && goToNextChar)
		{
			g.drawLine(caretLeft, 0, caretLeft, inputHeight);
		}
		g.translate(- inputTranslationX, 0);
	}
}

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditFurlTechnocratiMagnoliaTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia 
RDF Facets: qdcZdescriptionQSxEa0E20WikiE20javaE20symbianE5fosE20s60E20maemoE20cE2bE2bE20WikiE20HomeE20WikiE20HelpE20OverviewE20GlossaryE20CreateE20PageE20ProposeE20anE20ArticleE20SpotlightE20TopicE20E2dE20WE52TE20WidgetsE20ProgrammingE20E4canguageE20E2dE20SymbianE20CE2bE2bE20E2dE20OpenE20CE2fCE2bE2bE20E2dE20JavaE20E2dE20FlashE20E4citeE20E2dE20PythonE20WebE20TechnologiesE20E2dE20WE52TE20WidgetsE20E2dE20WidSetsE20ToolsE20andE20SE44KE20CodeE20E45E78amplesE20KnowledgeE20BaseE20TechnologyE20AreasE20SoftwareE20PlatformsE20E44evelopmentE20ProcessE20E3fE3fWikiE20ChineseE20E3fE3fE3fWikiE20JapaneseE20PortugueseE2fBrazilianE20E52ussianE20WhatE20linksE20hereE20UploadE20fileE20SpecialE20pagesE20PrintableE20versionE44ownloadE20asE20PE44FE20GoE20ToE20E2eE2eE2eX qdcZidentifierQSxhttpE3aE2fE2fwikiE2eforumE2enokiaE2ecomE2findeE78E2ephpE2fMMPE5ffileX qdcZpublisherQUxhttpE3aE2fE2fswE2enokiaE2ecomE2fidE2fc764fd1cE2d8b06E2d499aE2d9a6aE2d17c3903d5a65E2fforumE5fnokiaE5fcrawlerE5fagentX qdcZtitleQSxMMPE20fileE20E2dE20ForumE20NokiaE20WikiX qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfnTypeZCommunityContentQ qdcZtypeQUqfnTypeZE52esourceQ qdcZtypeQUqfnTypeZWebpageQ qdcZtypeQUqfnTypeZWikiContentQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qrssZdescriptionQSxEa0E20WikiE20javaE20symbianE5fosE20s60E20maemoE20cE2bE2bE20WikiE20HomeE20WikiE20HelpE20OverviewE20GlossaryE20CreateE20PageE20ProposeE20anE20ArticleE20SpotlightE20TopicE20E2dE20WE52TE20WidgetsE20ProgrammingE20E4canguageE20E2dE20SymbianE20CE2bE2bE20E2dE20OpenE20CE2fCE2bE2bE20E2dE20JavaE20E2dE20FlashE20E4citeE20E2dE20PythonE20WebE20TechnologiesE20E2dE20WE52TE20WidgetsE20E2dE20WidSetsE20ToolsE20andE20SE44KE20CodeE20E45E78amplesE20KnowledgeE20BaseE20TechnologyE20AreasE20SoftwareE20PlatformsE20E44evelopmentE20ProcessE20E3fE3fWikiE20ChineseE20E3fE3fE3fWikiE20JapaneseE20PortugueseE2fBrazilianE20E52ussianE20WhatE20linksE20hereE20UploadE20fileE20SpecialE20pagesE20PrintableE20versionE44ownloadE20asE20PE44FE20GoE20ToE20E2eE2eE2eX qfnZdistributionQUxhttpE3aE2fE2fwikiE2eforumE2enokiaE2ecomE2fX qfnZtypeQUqfnTypeZCommunityContentQ qfnZtypeQUqfnTypeZE52esourceQ qfnZtypeQUqfnTypeZWebpageQ qfnZtypeQUqfnTypeZWikiContentQ qfnZupdatedQDx2008E2d10E2d02X qfnZuserE5ftagQSxfileX qfnZuserE5ftagQSxlibpathX qfnZuserE5ftagQSxmmpX qfnZuserE5ftagQSxresourceX qmarsZdescriptionQSxEa0E20WikiE20javaE20symbianE5fosE20s60E20maemoE20cE2bE2bE20WikiE20HomeE20WikiE20HelpE20OverviewE20GlossaryE20CreateE20PageE20ProposeE20anE20ArticleE20SpotlightE20TopicE20E2dE20WE52TE20WidgetsE20ProgrammingE20E4canguageE20E2dE20SymbianE20CE2bE2bE20E2dE20OpenE20CE2fCE2bE2bE20E2dE20JavaE20E2dE20FlashE20E4citeE20E2dE20PythonE20WebE20TechnologiesE20E2dE20WE52TE20WidgetsE20E2dE20WidSetsE20ToolsE20andE20SE44KE20CodeE20E45E78amplesE20KnowledgeE20BaseE20TechnologyE20AreasE20SoftwareE20PlatformsE20E44evelopmentE20ProcessE20E3fE3fWikiE20ChineseE20E3fE3fE3fWikiE20JapaneseE20PortugueseE2fBrazilianE20E52ussianE20WhatE20linksE20hereE20UploadE20fileE20SpecialE20pagesE20PrintableE20versionE44ownloadE20asE20PE44FE20GoE20ToE20E2eE2eE2eX qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfnTypeZCommunityContentQ qrdfZtypeQUqfnTypeZE52esourceQ qrdfZtypeQUqfnTypeZWebpageQ qrdfZtypeQUqfnTypeZWikiContentQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ
User Rating: qfnZuserE5FratingQNx4E2E0000X