Tagged: source code Toggle Comment Threads | Keyboard Shortcuts

  • pit 4:24 pm on February 23, 2009 Permalink | Reply
    Tags: , , , gestures, source code,   

    Handling touch gestures in Flash Lite 

    With the release of many touch-enabled devices, as the latest Nokia 5800 XpressMusic and the forthcoming Nokia N97, applications can benefit from new ways of touch-based interactions. A typical example of these new patterns is represented by gestures: simple finger/stylus actions that allow the user to perform specific task, without the need of a precise interaction (e.g.: identify and press a specific button).

    This article will explain how to implement basic touch gestures in Flash Lite. Specifically, we’ll see how to detect both horizontal (left-to-right and right-to-left) and vertical (up-to-down and down-to-up) gestures.

    In the above video it’s possible to see a simple Flash Lite photo viewer, where the user can go from a photo to the next/previous just sliding finger or stylus.

    The source code

    Step 1. Detect touch events

    First thing to do is to detect and handle touch-based events, and this can be done by implementing a MouseListener, and its onMouseDown() and onMouseUp() methods. We also define 4 Number variables to hold the x and y coordinates associated to the mouse up and down events: these will be used to detect if the touch interaction was actually a gesture or not.

    So, take a new and empty FLA, and add this code on your first frame:

    var startX:Number;
    var startY:Number;
    var endX:Number;
    var endY:Number;
     
    var gesturesListener:Object = new Object();
     
    gesturesListener.onMouseDown = function()
    {
    	startX = _root._xmouse;
    	startY = _root._ymouse;
    }
    gesturesListener.onMouseUp = function()
    {
    	endX = _root._xmouse;
    	endY = _root._ymouse;
     
    	checkGesture();
    }
    Mouse.addListener(gesturesListener);

    The onMouseDown() function just sets the starting coordinates values, while the onMouseUp() also calls the checkGesture() function, defined below, that will check if the touch interaction was actually a gesture.

    Step 2. Identify a gesture

    Before trying to identify a gesture, let’s define some variables used to identify and define specific gesture types:

    // minimum length of an horizontal gesture
    var MIN_H_GESTURE:Number = Stage.width / 3;
    // minimum length of a vertical gesture
    var MIN_V_GESTURE:Number = Stage.height / 3;
     
    // flags for each kind of gesture
    var UP_TO_DOWN:Number = 1;
    var DOWN_TO_UP:Number = 2;
    var LEFT_TO_RIGHT:Number = 4;
    var RIGHT_TO_LEFT:Number = 8;

    The MIN_H_GESTURE and MIN_V_GESTURE variables define the minimum horizontal and vertical distances that must exist between the onMouseDown() and the onMouseUp() event to have, respectively, a horizontal or a vertical gesture.

    Now, we can easily implement the checkGesture() function, by getting the horizontal and vertical length of the touch interaction, and comparing them with the minimum distances defined above.

    function checkGesture()
    {
    	var xDelta:Number = endX - startX;
    	var yDelta:Number = endY - startY;
     
    	var gesture:Number = 0;
     
    	if(xDelta > MIN_H_GESTURE)
    		gesture |= LEFT_TO_RIGHT;
    	else if(xDelta < - MIN_H_GESTURE)
    		gesture |= RIGHT_TO_LEFT;
     
    	if(yDelta > MIN_V_GESTURE)
    		gesture |= UP_TO_DOWN;
    	else if(yDelta < - MIN_V_GESTURE)
    		gesture |= DOWN_TO_UP;
     
    	if(gesture > 0)
    		handleGesture(gesture);
    }

    Step 3. Handling the detected gesture

    Once identified a gesture, we have to actually handle it in some way. To do it, we’ll implement the handleGesture() function, that will check the passed argument to find which is the specific identified gesture.

    In this example, we’ll simply trace the kind of identified gesture(s).

    function handleGesture(gestureFlags:Number)
    {
    	if(gestureFlags & LEFT_TO_RIGHT)
    		trace("left to right gesture");
    	if(gestureFlags & RIGHT_TO_LEFT)
    		trace("right to left gesture");
    	if(gestureFlags & UP_TO_DOWN)
    		trace("up to down gesture");
    	if(gestureFlags & DOWN_TO_UP)
    		trace("down to up gesture");
    }

    Further development

    A lot of improvements can be done to the code presented in this article. Just some example:

    • Detect diagonal gestures: by checking the appropriate gesture flags, it’s already possible to identify mixed diagonal gestures. So, basically you need to extend a bit the handleGesture() method
    • Define a maximum time to perform a gesture: basically, accept a gesture only if the time elapsed to perform it is below a certain limit. This could be useful in some scenarios, to avoid detecting fake gestures.

    Download source code

    You can download the full source code used in this article here:

    Rate this article!

    If you like this article, please vote it on Forum Nokia Wiki. Thanks :)

     
    • joy 5:08 am on April 7, 2009 Permalink

      this is a joss tutorial

    • Rich 3:10 pm on July 20, 2009 Permalink

      Thanks for the tutorial. It’s great!

    • Aj 3:59 pm on August 18, 2009 Permalink

      Hey,

      This is an awesome tutorial and it’s much appreciated.

      I was having some trouble assigning the gestures to soft keys.
      In this tutorial, you are displaying the gestures, However for example could you please tell me how I would be able to assign the “right to left” gesture to the right key?
      Thanks.

    • Supriya Tenany 11:18 am on December 21, 2010 Permalink

      Hi,

      A really good tutorial. I am only waiting for the practical implementation now. How can I check the touch functionalities on the device central? It provides me ‘Multitouch’ but I am unable to use it.

  • pit 1:43 pm on February 19, 2009 Permalink | Reply
    Tags: , , , source code,   

    Building a dynamic fisheye menu in Flash Lite 

    Some time ago, we’ve seen how to build a fisheye menu with J2ME. Now, it’s time to see how to create the same component with Flash Lite.

    The FisheyeMenu source code

    Step 1. The menu MovieClip and external class

    Let’s create the FisheyeMenu ActionScript class, that will extend MovieClip, that will be used to implement the actual menu logic:

    class FisheyeMenu extends MovieClip
    {
    }

    Then, create an empty movie clip in your library, export it, and associate it with the FisheyeMenu class.

    Step 2. Initializing the menu

    First, define these 4 menu properties, that will hold some useful values:

    // focus index of the selected menu item
    var focusedIndex:Number;
     
    // total number of menu items
    var itemsNum:Number;
     
    // width of single menu items (in pixels)
    var itemWidth:Number;
     
    // the MovieClip that will contain the menu items
    var itemsContainer:MovieClip;

    Let’s also define an utility function that returns the currently focused item index:

    public function getFocusedIndex()
    {
    return this.focusedIndex;
    }

    And then, implement a function that will be used to initialize the menu with the items you want.

    public function initializeMenu(itemIds:Array, itemWidth:Number)
    {
    	this.itemsNum = itemIds.length;
     
    	this.focusedIndex = 0;
     
    	this.itemWidth = itemWidth;
     
    	this.initItems(itemIds);
    }
    private function initItems(itemIds:Array)
    {
    	this.itemsContainer = this.createEmptyMovieClip('itemsContainer', this.getNextHighestDepth());
     
    	for(var i:Number = 0; i < itemIds.length; i++)
    	{
    		var item:MovieClip = itemsContainer.attachMovie(itemIds[i], 'item_' + i, itemsContainer.getNextHighestDepth(), {_x: itemWidth * i, _y: 0});
     
    		if(i > 0)
    		{
    			item._xscale = 50;
    			item._yscale = 50;
    		}
    	}
    }

    The initializeMenu() function is the function you will call to initialize your fisheye menu with the items you want. Its arguments are:

    • an Array containing the id of MovieClip symbols to be used as items
    • the width of single menu items

    Once called, initializeMenu() initializes the menu properties and then calls the initItems() function, that will actually attach the item instances, scaling down the unselected items and translating the menu itself to its starting position.

    The getMenuLeft() function returns the x position to be used for the itemsContainer MovieClip, and depends on the focused item index:

    private function getMenuLeft():Number
    {
    	return - itemWidth * focusedIndex;
    }

    Step 3. Implement sliding funcionality

    When the user presses LEFT and RIGHT keys, you want the menu to perform these steps:

    • change the focused item, scaling down the previously focused one, and scaling up the new
    • translate the menu to be centered on the new focused item

    In ActionScript, you can do it this way:

    public function shiftItem(itemDelta:Number)
    {
    	var nextIndex:Number = focusedIndex + itemDelta;
     
    	if(nextIndex >= 0 && nextIndex < itemsNum)
    	{
    		scaleItem(focusedIndex, true);
     
    		focusedIndex = nextIndex;
     
    		scaleItem(focusedIndex, false);
     
    		moveMenu();
    	}
    }
    private function moveMenu():Void
    {
    	new Tween(itemsContainer, "_x", None.easeNone, itemsContainer._x, getMenuLeft(), .50, true);
    }
    private function scaleItem(itemIndex:Number, scaleDown:Boolean):Void
    {
    	var item:MovieClip = itemsContainer['item_' + itemIndex];
     
    	var fromScale:Number = scaleDown ? 100 : 50;
    	var toScale:Number = scaleDown ? 50 : 100;
     
    	new Tween(item, "_xscale", None.easeNone, fromScale, toScale, .50, true);
    	new Tween(item, "_yscale", None.easeNone, fromScale, toScale, .50, true);
    }

    In this code snippet, there are 3 functions:

    • shiftItem() is the function called to change the focused Item index by the passed delta argument. It checks if the change is ok, and then calls the following 2 functions:
    • moveMenu() actually translates the items container, to have the new focused item horizontally centered
    • scaleItem() scales up or down, depending on the scaleDown argument, the item corresponding at the index passed as argument

    Since here we use the Tween class, we have to add these 2 import lines at the beginning of the ActionScript file:

    import mx.transitions.Tween;
    import mx.transitions.easing.*;

    How to use the fisheye-menu

    Step 4. Create the menu items symbols

    Take back your FLA, and create 3 symbols that will be used as items within the fisheye menu. Also, remember to check the “Export for ActionScript” option, to have them actually usable from ActionScript itself.

    Step 5. Attach and initialize the menu

    Now, attach a FisheyeMenu istance directly to the _root, and initialize it with the ID of the symbols created in the previous step:

    var menu:MovieClip = _root.attachMovie('FisheyeMenu', 'main_menu', _root.getNextHighestDepth());
     
    var items:Array = new Array('Item0', 'Item1', 'Item2');
     
    menu._x = 120;
    menu._y = 120;
     
    menu.initializeMenu(items, 50);

    Step 6. Create a KeyListener to interact with the menu

    The KeyListener will be really simple, since it will simply call the shiftItem() function when the user press LEFT or RIGHT keys, and will call a custom function when the user press the ENTER key, to trace the index of the current focused item:

    var keyListener:Object = new Object();
     
    keyListener.onKeyDown = function()
    {
    	var key:Number = Key.getCode();
     
    	if(key == Key.RIGHT)
    	{
    		menu.shiftItem(1);
    	}
    	else if(key == Key.LEFT)
    	{
    		menu.shiftItem(-1);
    	}
    	else if(key == Key.ENTER)
    	{
    		menuFireAction();
    	}
    }
    Key.addListener(keyListener);
     
    function menuFireAction()
    {
    	trace("MENU ITEM PRESSED: " + menu.getFocusedIndex());
    }

    Downloads and related resources

    You can download full source code (FLA + ActionScript file) of this example here:

    If you like this article, feel free to vote it on Forum Nokia Wiki.

     
  • pit 1:04 pm on January 25, 2009 Permalink | Reply
    Tags: , , image reflection, , , source code,   

    J2ME Images: how to create a reflection effect 

    It’s surely time for some new J2ME tutorial, so this article will explain how to create a nice reflection effect starting from a simple Image.

    You can see the final effect, as usual, on the emulator page: J2ME Image reflection in action.

    Source code

    1. Method declaration

    Let’s start by our method declaration:

    public static Image createReflectedImage(Image image, int bgColor, int reflectionHeight)
    {
    }

    We have 3 arguments:

    • the original image that we want to reflect
    • the background color (used for transparent images)
    • the height of the reflection effect

    2. The mutable Image

    Now, let’s create the mutable Image that will hold the resulting effect:

    int w = image.getWidth();
     
    int h = image.getHeight();
     
    Image reflectedImage = Image.createImage(w, h + reflectionHeight);

    We store the original image width and height into 2 int variables, and then create the mutable image with the same width, but with an height equal to h (the original image) plus the specified reflection height.

    3. Copy the original Image

    Now, first drawing steps are:

    1. Getting the Graphics object of our mutable image
    2. Filling the image with the background color
    3. Drawing the original image on the upper part of the mutable one
    Graphics g = reflectedImage.getGraphics();
     
    g.setColor(bgColor);
     
    g.fillRect(0, 0, w, h + reflectionHeight);
     
    g.drawImage(image, 0, 0, Graphics.TOP | Graphics.LEFT);

    4. Create the reflection effect

    Now, let’s get to the important part of this tutorial, that is the reflection effect itself:

    • for each horizontal line of the reflected image part, take the corresponding vertical coordinate of the original image
    • get the RGBA data of the corresponding horizontal line of the original image
    • calculate the alpha to be applied to this line, and apply it to each element of the RGB data array
    • draw the RGB data into the reflected image, by using its Graphics object

    And here is the source code:

    int[] rgba = new int[w];
    int currentY = -1;
     
    for(int i = 0; i < reflectionHeight; i++)
    {
    	int y = (h - 1) - (i * h / reflectionHeight);
     
    	if(y != currentY)
    		image.getRGB(rgba, 0, w, 0, y, w, 1);
     
    	int alpha = 0xff - (i * 0xff / reflectionHeight);
     
    	for(int j = 0; j < w; j++)
    	{
    		int origAlpha = (rgba[j] >> 24);
    		int newAlpha = (alpha & origAlpha) * alpha / 0xff;
     
    		rgba[j] = (rgba[j] & 0x00ffffff);
    		rgba[j] = (rgba[j] | (newAlpha << 24));
    	}
     
    	g.drawRGB(rgba, 0, w, 0, h + i, w, 1, true);
    }

    as you can see, the rgba[] int array holds the current pixel row data, and will be refreshed only when necessary (so, when the y coordinate of the original image changes).

    Sample usage

    Using the above method is really simple, since it’s only necessary to:

    1. Create the original Image
    2. Call createReflectedImage() method by passing the original Image as argument, together with the background color and the reflection effect height
    Image originalImage = Image.createImage("/cap_man1.png");
     
    Image reflectedImage = ReflectedImage.create(originalImage, bgColor, 64);

    Downloads

    You can download the complete source code of this article here:

    Vote this article!

    If you liked this tutorial, feel free to vote it on Forum Nokia Wiki: How to create an image reflection effect in Java ME

     
    • ion 9:51 am on February 5, 2009 Permalink

      hi.. nice code

      could you help me how to draw a “Justified” Paragraf in canvas…. please !!

  • pit 3:02 pm on October 8, 2008 Permalink | Reply
    Tags: , , , ringtones, , source code,   

    Create your first Flash Lite ringtone with KuneriLite 

    For those of you who missed it (really??) latest KuneriLite versions have added support for Flash Lite ringtones, one of the coolest FlashLite features around!!

    Today, we’ll see how it is simple to create a FlashLite ringtone with caller-id support and an application that allows users to easily set and unset it.

    Step 1: The FlashLite ringtone

    To start, we’ll build a really simple FlashLite ringtone.

    Let’s start building a simple interface, with these elements:

    Now it’s time to add some ActionScript to our interface. So, let’s open frame 1 of our Actions layer.

    Important note: when using KuneriLite from a ringtone SWF, you MUST use port 2001.

    First, we’ll define a method to retrieve caller infos, and display it, depending on the returned data:

    var loader:LoadVars = new LoadVars();
     
    getCallerName();
     
    function getCallerName()
    {
    	commandOutput.text = "Getting caller's info... ";
     
    	loader.onLoad = callerNameHandler;
     
    	loader.load("http://127.0.0.1:2001/Basic/ring?klCommand=callerid");
    }
    function callerNameHandler()
    {
    	commandOutput.text += this.toString();
     
    	if(this.klError != 0)
    	{
    		callerName.text = "Command error: " + this.klError;
    	}
    	else if(this.klName != undefined)
    	{
    		callerName.text = this.klName;
    	}
    	else
    	{
    		callerName.text = this.klNumber;
    	}
    }

    And then, let’s add the call answer/reject functionality to our ringtone. Two other KuneriLite calls will do the job (note that we’ll reuse the LoadVars instance defined above):

    answer.onPress = function()
    {
    	commandOutput.text = "Answering call... ";
     
    	loader.onLoad = callCommandHandler;
     
    	loader.load("http://127.0.0.1:2001/Basic/ring?klCommand=answercall");
    }
    reject.onPress = function()
    {
    	commandOutput.text = "Rejecting call... ";
     
    	loader.onLoad = callCommandHandler;
     
    	loader.load("http://127.0.0.1:2001/Basic/ring?klCommand=hangupcall");
    }
    function callCommandHandler()
    {
    	commandOutput.text += this.toString();
    }

    Important note: since KuneriLite ringtone plugin already handles device answer and reject keys (the green and red one) you could avoid implementing your custom buttons in ringtone SWF (thanks Jukka for the reminder!)

    Step 2: Setting and unsetting the ringtone

    Now, it’s time to build the “main” SWF application, that is the one that the user would launch from phone menu to manage its FlashLite ringtones.

    As usual, let’s create a basic interface, with this layout:

    Now, let’s add the necessary ActionScript code to our Buttons.
    This is for the enable button:

    enableButton.onPress = function()
    {
    	commandOutput.text = "Enabling ringtone..";
     
    	var loader:LoadVars = new LoadVars();
     
    	loader.onLoad = handleResponse;
     
    	loader.load("http://127.0.0.1:1001/Basic/ring?klCommand=enableringswf&amp;klPath=ringtone.swf");
    }

    And similarly, this is for the disable button:

    disableButton.onPress = function()
    {
    	commandOutput.text = "Disabling ringtone..";
     
    	var loader:LoadVars = new LoadVars();
     
    	loader.onLoad = handleResponse;
     
    	loader.load("http://127.0.0.1:1001/Basic/ring?klCommand=disableringswf&amp;klPath=ringtone.swf");
    }

    And here’s the handler, used by both commands calls, to print out the KuneriLite response error code:

    function handleResponse()
    {
    	commandOutput.text += " Error code: " + this.klError;
    }

    Step 3: building and testing

    Building a KuneriLite app is easy as always, but you need to follow these 4 specific steps to make the ringtone correctly work:

    1. Select Ringtone plugin
    2. Place your ringtone SWF in a separate folder, containing only that SWF, and then select it on Wizard Step 2
    3. Select the ringtone setter as main SWF
    4. Since Ringtone plugin needs signing, on Step 3 fill in the certificate infos

    Once done, just compile and transfer your SIS on your phone, install and launch it:

    • on main app screen, click the enable button
    • check the command output, to see if the command executed successfully: you should see this message
      Enabling ringtone... Error code: 0
    • if yes, just close the app and call your own phone, and your FlashLite ringtone will magically appear!
    • within the ringtone SWF you will see the caller’s name (if available on your phonebook), otherwise its phone number
    • to answer or reject the incoming call, simply use the buttons we previously placed on stage

    That’s it!

    Conclusions

    Now, add this with the other KuneriLite features, and you could end up having:

    • browsable ringtones catalogs, directly downloadable from your FlashLite app
    • ringones for specific contacts (a phonebook plugin would be great!)
    • location-based ringones!

    Isn’t this enough?

     
    • José Xavier 6:14 pm on October 8, 2008 Permalink

      Hi,
      Can i translate your tutorial to portuguese to post in my blog and ofcourse i’ll say that tutorial is yours… sorry my english.
      :)

    • Jukka 11:07 am on October 9, 2008 Permalink

      Hi Alessandro,
      awesome tutorial as usual :)

      One comment: Handling answer and reject buttons in Flash Lite is actually unnecessary, since KuneriLite ringtone plugin handles the ‘green’ and ‘red’ dialkeys.
      They are naturally used when answering a call ;)

    • pit 11:42 am on October 9, 2008 Permalink

      Hi all!

      @José: sure, feel free to translate it to portuguese!

      @Jukka: thanks for the reminder! I’ve added this info to the article :)

  • pit 9:33 am on October 6, 2008 Permalink | Reply
    Tags: , , , , s60 5th edition, source code, touch scrolling, touch ui   

    Touch and J2ME part 1: how scroll an image 

    When you start writing your first app for the new S60 5th edition platform you’ll find that, among the first things to deal with, there is interface scrolling: when playing with touchscreen devices, users expect to be able to interact with on-screen objects by simple stylus/finger gestures, rather than by an old-fashion, on-screen keyboard.

    Today, we’ll see how to implement touch scrolling in Java ME in a simple scenario: scrolling a large Image, that doesn’t fit on the device display.

    A sample MIDlet showing this code in action is available on the emulator page: Touch scrollable image in action.

    Source Code: ScrollableImageCanvas class

    Let’s start defining the main class, that will extend the Canvas object:

    public class ScrollableImageCanvas extends Canvas
    {
    {

    Now, we define properties that we’ll use to manage:

    • image size
    • image translation
    • user touch interaction
    // image-related properties
    int imageHeight = 0;
    int imageWidth = 0;
    Image image = null;
    // scroll properties
    protected int translationX = 0;
    protected int translationY = 0;
     
    // touch properties
    protected int lastPointerX = -1;
    protected int lastPointerY = -1;

    Class constructor is quite straightforward, and only needs an Image as argument:

    public ScrollableImageCanvas(Image image)
    {
    	this.image = image;
    	this.imageWidth = image.getWidth();
    	this.imageHeight = image.getHeight();
    }

    Also paint() implementation is simple, since it simply draws the given Image at current translation x and y coordinates:

    protected void paint(Graphics g)
    {
    	g.setColor(0xffffff);
    	g.fillRect(0, 0, getWidth(), getHeight());
    	g.drawImage(image, - translationX, - translationY, Graphics.TOP | Graphics.LEFT);
    }

    Finally, we must implement the touch-based scrolling functionality. To do this, we’ll override the 3 pointer handlers provided by Canvas objects:

    • pointerPressed: called when the pointer is pressed
    • pointerReleased: called when the pointer is released
    • pointerDragged: called when the pointer is dragged
    protected void pointerPressed(int x, int y)
    {
    	lastPointerX = x;
    	lastPointerY = y;
    }
    protected void pointerReleased(int x, int y)
    {
    	lastPointerX = -1;
    	lastPointerY = -1;
    }
    protected void pointerDragged(int x, int y)
    {
    	scrollImage(lastPointerX - x, lastPointerY - y);
    	lastPointerX = x;
    	lastPointerY = y;
    }

    The scrollImage() method implementation follows. What it does is:

    • increment the current translation x and y coordinated by the given x and y deltas
    • normalize the new translation x and y coordinates, so that Image will not go out of bounds
    void scrollImage(int deltaX, int deltaY)
    {
    	if(imageWidth > getWidth())
    	{
    		translationX += deltaX;
    		if(translationX < 0)
    			translationX = 0;
    		else if(translationX + getWidth() > imageWidth)
    			translationX = imageWidth - getWidth();
    	}
     
    	if(imageHeight > getHeight())
    	{
    		translationY += deltaY;
     
    		if(translationY < 0)
    			translationY = 0;
    		else if(translationY + getHeight() > imageHeight)
    			translationY = imageHeight - getHeight();
    	}
     
    	repaint();
    }

    Complete class source code is available here: ScrollableImageCanvas.java.

    If you like this article, feel free to rate it on Forum Nokia Wiki.

    Further development

    A lot of improvements can be done to the code presented in this article. Just some examples are:

    • scrollbars: a fundamental element to let the user know how much he can scroll both in vertical and horizontal directions
    • smooth scrolling: using some inertia when applying scrolling movement will make the whole scrolling effect a lot more realistic
     
    • truf 11:44 am on October 7, 2008 Permalink

      Looking forward for part 2.

    • Bhaskar Nag 8:51 am on November 5, 2008 Permalink

      Your site is very strong in contents of j2me.I got my required codes in j2me from your site.please send me lots of j2me (mobile application code) in my mentioned emailid bellow,I would be highly obliged.
      bhaskar.nag@rediffmail.com
      Thanking You.
      Your’s truely.
      Bhaskar Nag.

    • kamil inal 1:54 pm on November 6, 2009 Permalink

      Thanks for this article:)

    • ankush 9:00 am on April 16, 2011 Permalink

      thanx a lot .. :D

    • abah 1:40 pm on September 16, 2011 Permalink

      thanks! it helps me! :D

  • pit 3:09 pm on September 15, 2008 Permalink | Reply
    Tags: , , , menu, menu transition, sliding menu, source code   

    Building a J2ME sliding menu with text and images 

    Whatever you’re building, a game or an application, you always need a menu to let users navigate through sections of your MIDlet.

    This article will show how to build a menu with text and icons, and with a nice sliding effect to go from one menu item to another. You can see the final effect on the emulator page: J2ME Sliding Menu in action.

    Source code: SlideIconsMenu class

    As always, let’s start defining our class:

    public class SlideIconsMenu
    {
    }

    Now, we define some appearance-related properties, that can be customized to change menu colors and font.

    // selected item index
    public int selectedIndex = 0;
     
    // icon label color
    public int textColor = 0xff0000;
     
    // menu bg color
    public int bgColor = 0xffffff;
     
    // icon label font
    public Font textFont = Font.getDefaultFont();
     
    // menu right and left Images
    public Image slideRightImage = null;
    public Image slideLeftImage = null;

    And some other properties, that will be internally used by the menu class itself, to handle content and the sliding animation:

    // menu size
    int width = 0;
    int height = 0;
     
    // item labels
    String[] labels = null;
    // item icons
    Image[] icons = null;
     
    // previous item index (during menu translation)
    int prevIndex = 0;
     
    // menu sliding translation properties
    public int translationDuration = 500;
    long startTranslationTime = 0;

    Now, let’s define the menu constructor. We need a constructor that will accept these arguments:

    • a set of item labels
    • a set of images, one for each item
    • the menu width
    • and the menu height
    public SlideIconsMenu(String[] labels, Image[] icons, int width, int height) throws Exception
    {
    	this.width = width;
    	this.height = height;
     
    	this.labels = labels;
    	this.icons = icons;
     
    	slideRightImage = Image.createImage("/slide_right.png");
    	slideLeftImage = Image.createImage("/slide_left.png");
    }

    The constructor also creates 2 Images to represent the left and right sliding arrows, that will be used to indicate more items on the menu left/right side. So, in your code, you must adapt those image paths to match existing ones within your project.

    Now we must handle item change, by letting our menu slide with a nice transition. To do this, we’ll manage the item change with the following slideItem() method:

    public void slideItem(int delta)
    {
    	if(!isTranslating() && selectedIndex + delta >= 0 && selectedIndex + delta < labels.length)
    	{
    		prevIndex = selectedIndex;
     
    		selectedIndex += delta;
     
    		startTranslationTime = System.currentTimeMillis();
    	}
    }
    public boolean isTranslating()
    {
    	return prevIndex != selectedIndex;
    }

    And finally, since we need to paint our menu, here is its paint() method:

    public void paint(Graphics g)
    {
    	g.setColor(bgColor);
    	g.fillRect(0, 0, width, height);
     
    	g.setColor(textColor);
     
    	if(selectedIndex > 0)
    	{
    		g.drawImage(slideLeftImage, 2, height / 2, Graphics.LEFT | Graphics.VCENTER);
    	}
    	if(selectedIndex < icons.length - 1)
    	{
    		g.drawImage(slideRightImage, width - 2, height / 2, Graphics.RIGHT | Graphics.VCENTER);
    	}
    	g.drawString(labels[selectedIndex], width / 2, height - 2, Graphics.BOTTOM | Graphics.HCENTER);
     
    	g.setClip(slideLeftImage.getWidth(), 0, width - 2 * slideLeftImage.getWidth(), height);
     
    	if(selectedIndex != prevIndex)
    	{
    		int diff = (int)(System.currentTimeMillis() - startTranslationTime);
     
    		if(diff > translationDuration)
    		{
    			diff = translationDuration;
    		}
     
    		int coeff = selectedIndex > prevIndex ? 1 : - 1;
    		int currentX = width / 2 - coeff * diff * width / translationDuration;
    		int nextX = currentX + width * coeff;
     
    		g.drawImage(icons[prevIndex], currentX, height / 2, Graphics.VCENTER | Graphics.HCENTER);
     
    		g.drawImage(icons[selectedIndex], nextX, height / 2, Graphics.VCENTER | Graphics.HCENTER);
     
    		if(diff >= translationDuration)
    		{
    			prevIndex = selectedIndex;
    		}
    	}
    	else
    	{
    		g.drawImage(icons[selectedIndex], width / 2, height / 2, Graphics.VCENTER | Graphics.HCENTER);
    	}
    }

    Sample usage

    Here’s a sample Canvas that uses the SlideIconsMenu class. The main steps are:

    • the menu constructions
    • the key handling, done within the Canvas keyPressed() method
    • the menu repainting, done periodically, to allow the sliding transition to be smoothly drawn
    import javax.microedition.lcdui.Canvas;
    import javax.microedition.lcdui.Graphics;
    import javax.microedition.lcdui.Image;
     
    public class SlideIconsCanvas extends Canvas implements Runnable
    {
    	SlideIconsMenu menu = null;
     
    	public SlideIconsCanvas()
    	{
    		Image[] im = new Image[3]; 
     
    		try
    		{
    			im[0] = Image.createImage("/item0.png");
    			im[1] = Image.createImage("/item1.png");
    			im[2] = Image.createImage("/item2.png");
     
    			menu = new SlideIconsMenu(
    				new String[]{"Item 1", "Item 2", "Item 3"},
    				im,
    				getWidth(),
    				getHeight()
    			);
     
    			new Thread(this).start();
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    	}
    	protected void paint(Graphics g)
    	{
    		menu.paint(g);
    	}
    	public void keyPressed(int key)
    	{
    		int gameKey = getGameAction(key);
     
    		if(gameKey == Canvas.RIGHT)
    		{
    			menu.slideItem(1);
    		}
    		else if(gameKey == Canvas.LEFT)
    		{
    			menu.slideItem(- 1);
    		}
    	}
    	public void run()
    	{
    		try
    		{
    			while(true)
    			{
    				repaint();
     
    				synchronized(this)
    				{
    					wait(100L);
    				}
    			}
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    	}
     
    }

    Download source code

    You can download full source code here:

     
    • deanet 7:21 pm on September 24, 2008 Permalink

      wew … nice code :mrgreen:

    • Stella 8:26 am on October 1, 2008 Permalink

      Hi ,
      this screen is brilliant, i was wondering if you could come up with a design that is similar to the carousel interface of yahoo GO!. this design is quite close to that

      byeeeee ;)
      Stella

    • pit 9:04 am on October 1, 2008 Permalink

      Thanks for your feedback :)

      @stella: check out this other article, if it could suit your needs
      http://www.jappit.com/blog/2008/04/24/building-a-fisheye-menu-in-j2me-with-jsr-226/

    • Stella 7:04 am on October 15, 2008 Permalink

      yep i seen that. but that uses JSR226 right :( what about devices that dont have JSR266

      Regards
      Stella

    • Tyler 1:22 pm on April 30, 2009 Permalink

      Hi jappit;
      i have look at your code but i think you always refresh screen and wait 100ms. right? It uses 100% processor.

    • jermaine 3:23 am on September 29, 2010 Permalink

      thanks for this bit of code…but uhm, how do i run this? i copied the source codes but i dont know where to place the jar files…

c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
shift + esc
cancel