You Are Here:

Community: Wiki

This page was last modified 14:09, 23 April 2008.

J2ME Fisheye Menu with JSR 226

From Forum Nokia Wiki

A simple Fisheye menu can be created with JSR 226.

Image:J2me_fisheye_menu.png

Following is the actual implementation. Some details:

  • paint() method is used to actually paint the menu on a Graphics instance
  • keyPressed() method is used to handle keypress events, so, to scroll menu
  • mustRepaint() is useful to know if menu requires a repaint or not

The rest is quite all size/coords calculations :)

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.m2g.ScalableGraphics;
import javax.microedition.m2g.ScalableImage;
 
public class SvgFisheye
{
	ScalableGraphics sg = null;
	
	ScalableImage[] icons = null;
	int itemsNum = 0;
	
	int bgColor = 0xffffff;
	
	int currentItem = 0;
	int previousItem = 0;
	
	int width = 0;
	int height = 0;
	
	int iconPadding = 10;
 
	static int baseIconSide = 30;
	static int currentIconSide = 50;
	
	
	static final int TRANSITION_STEPS = 5;
	int currentStep = TRANSITION_STEPS;
	int direction = 0;
	
	boolean mustRepaint = true;
	
	public SvgFisheye(ScalableImage[] icons, int width, int height)
	{
		sg = ScalableGraphics.createInstance();
		
		this.width = width;
		this.height = height;
		
		this.icons = icons;
		this.itemsNum = icons.length;
	}
	
	public void paint(Graphics g)
	{
		int cx, cy, cw, ch;
		cx = g.getClipX();
		cy = g.getClipY();
		cw = g.getClipWidth();
		ch = g.getClipHeight();
		
		g.setClip(0, 0, width, height);
		
		int currentSide = currentIconSide - (TRANSITION_STEPS - currentStep) * (currentIconSide - baseIconSide) / TRANSITION_STEPS;
		int previousSide = baseIconSide + (TRANSITION_STEPS - currentStep) * (currentIconSide - baseIconSide) / TRANSITION_STEPS;
		
		int center = 0;
		
		if(direction == 0)
		{
			center = (currentItem) * (iconPadding + baseIconSide) + currentSide / 2;
		}
		else if(direction == Canvas.RIGHT)
		{
			int prevCenter = (currentItem - 1) * (iconPadding + baseIconSide) +
				previousSide / 2;
			
			int currentCenter = prevCenter + previousSide / 2 + iconPadding +
				currentSide / 2;
		
			center = prevCenter + (currentCenter - prevCenter) * currentStep / TRANSITION_STEPS;
		}
		else if(direction == Canvas.LEFT)
		{
			int currentCenter = currentItem * (iconPadding + baseIconSide) +
				currentSide / 2;
			
			int prevCenter = currentCenter + currentSide / 2 + iconPadding + 
				previousSide / 2;
	
			center = prevCenter + (currentCenter - prevCenter) * currentStep / TRANSITION_STEPS;
		}
		
		g.setColor(bgColor);
		g.fillRect(0, 0, width, height);
		
		int left = width / 2 - center;
		
		sg.bindTarget(g);
		
		for(int i = 0; i < itemsNum; i++)
		{
			int iconSide = i == currentItem ? currentSide :
				(i == previousItem ? previousSide : baseIconSide);
			
			icons[i].setViewportWidth(iconSide);
			icons[i].setViewportHeight(iconSide);
			
			sg.render(left, 0, icons[i]);
			
			left += iconSide + iconPadding;
		}
		
		sg.releaseTarget();
		
		move();
		
		g.setClip(cx, cy, cw, ch);
	}
	
	public boolean mustRepaint()
	{
		return mustRepaint;
	}
	private boolean isMoving()
	{
		return currentStep < TRANSITION_STEPS;
	}
	private void move()
	{
		if(currentStep < TRANSITION_STEPS)
		{
			mustRepaint = true;
			
			currentStep++;
			
			if(currentStep == TRANSITION_STEPS)
			{
				direction = 0;
			}
		}
		else
		{
			mustRepaint = false;
		}
	}
	private void startMove()
	{
		currentStep = 0;
		
		mustRepaint = true;
	}
	
	public void keyPressed(int keyCode)
	{
		int delta = keyCode == Canvas.RIGHT ? 1 : (keyCode == Canvas.LEFT ? -1 : 0);
		
		if(delta != 0 && !isMoving() && currentItem + delta >= 0 && currentItem + delta < itemsNum)
		{
			previousItem = currentItem;
			
			currentItem = currentItem + delta;
			
			startMove();
				
			direction = keyCode;
		}
	}
}

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