<< ETQW - Connection Lost | Home | List menu with Canvas >>

'Copycat' SE menu

Creating Sony Ericsson Menu Simulator

Please take this article as a sort of guideline how you can design and develop your own user interface similar to your favourite mobile phone maker. This is not 100% bullet-proof solution! Bellow code was targeting Sony Ericsson's W810 so provided example will show differently on different screen resolution and size of different devices.

I am currently working on my MSc project in Mobile Computing that is focusing on use of mobile devices by blind or visually impaired people. Because I have no way to directly to access and edit existing system on my mobile phone (Sony Ericsson W910) I decided to create a MIDlet that will simulate behaviour of the mobile phone to help me with the presentation of the project.

The focus of this simulator is not to mirror exact functionality of the real device, but provide me with working ground. Bellow code represents drawing of the main screen view with options to go to “Menu” or “Contacts” (Contacts, currently not implemented). After selecting “Menu” option we are presented with traditional SE menu layout. Here you can move between options with use of the joystick.

These are screen shots of emulator display view.

Newly selected icon will be highlighted and appropriate title displayed above the icons. Because I am not visually creative person I used icons from ESTATO forum section (http://www.esato.com/board/) that are created by community members and free to use. Plus I re-used SE logo from MobileTelefon.RU (http://mobiltelefon.ru/i/other/june/22/sony_ericsson_logo.jpg), unfortunately I had to resize it and cut it little to get it on the canvas that is 240x266 on W910 of original 240x320.

As this is just simplified version of actual device view the bottom screen options are not displayed in correct order. The exact menu options and functionality could be achieved if Canvas.setFullScreenMode(boolean mode) used, but then I would have to put extra time and care of all the functions on the bottom of the Canvas as they change from view-to-view. Secondly, interesting thing happened. While monitoring button presses I found out that emulator used with NetBeans will on keyPressed(int key) return button name (getKeyName(key)) in capital like UP, DOWN, where on the other hand my W910 will return the name with starting letter in capital as Up, Down. This is interesting inconsistency from Sony Ericsson. (I will check on other SE model to see if it is only model or Java platform issue or SE do it across all devices.)

MIDlet code

SESimulatorMidlet.java

package sesimulator;

import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.*;

import sesimulator.menus.MainScreen;

/**
 * @author Peter Miklosko
 */
public class SESimulatorMidlet extends MIDlet {
    public static SESimulatorMidlet instance;
    private Canvas mCanvas;

    public SESimulatorMidlet() {
        this.instance = this;
    }

    public void startApp() {
        if (mCanvas == null) {
            mCanvas = new MainScreen();
        }
        Display.getDisplay(this).setCurrent(mCanvas);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    public static void quitApp() {
        instance.destroyApp(true);
        instance.notifyDestroyed();
        instance = null;
    }
}

 

MainScreen.java

package sesimulator.menus;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import sesimulator.imageloader.ImageLoader;

/**
 * * @author Peter Miklosko
 */
public class MainScreen extends Canvas implements CommandListener {
    //private final Display mDisplay; 
    private Command exitCommand;
    private Command menuCommand;
    private Command contactsCommand;
    private Image backImg;

    public MainScreen() {
        //mDisplay = d; 
        exitCommand = new Command("Exit", Command.EXIT, 0);
        addCommand(exitCommand);
        menuCommand = new Command("Menu", Command.SCREEN, 2);
        addCommand(menuCommand);
        contactsCommand = new Command("Contacts", Command.SCREEN, 1);
        addCommand(contactsCommand);
        setCommandListener(this);
        ImageLoader il = new ImageLoader();
        backImg = il.loadImage("se_logo.jpg");
    }

    public void paint(Graphics g) {
        int w = getWidth();
        int h = getHeight();
        g.drawImage(backImg, 0, 0, Graphics.TOP | Graphics.LEFT);
    }

    public void commandAction(Command c, Displayable d) {
        if (c == exitCommand) {
            sesimulator.SESimulatorMidlet.quitApp();
        }
        else if (c == menuCommand) {
            MenuScreen ms = new MenuScreen();
            Display.getDisplay(sesimulator.SESimulatorMidlet.instance).setCurrent(ms);
        }
        else if (c == contactsCommand) {
            System.out.println("Contacts pressed");
        }
    }
}

 

MenuScreen.java

package sesimulator.menus;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Image;

import sesimulator.imageloader.ImageLoader;
import sesimulator.menus.functions.MenuScreenFunctions;

/**
 * * @author Peter Miklosko
 */
public class MenuScreen extends Canvas implements CommandListener {
    private Command selectCommand;
    private Command backCommand;
    private int w, h;
    public ImageLoader il = new ImageLoader();
    private Image[][] icon = new Image[3][4];
    private Image backImg;
    private int anchor = Graphics.TOP | Graphics.LEFT;
    public MenuScreenFunctions msf = new MenuScreenFunctions();

    public MenuScreen() {
        backCommand = new Command("Back", Command.SCREEN, 0);
        addCommand(backCommand);
        selectCommand = new Command("Select", Command.SCREEN, 2);
        addCommand(selectCommand);
        setCommandListener(this);
        backImg = il.loadImage("se_logo2.jpg");
        loadMenuIcons();
    }

    public void paint(Graphics g) {
        w = getWidth();
        h = getHeight(); //Background image 
        g.drawImage(backImg, 0, 0, anchor);
        //String name of selected option 
        Font f = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE);
        g.setFont(f);
        g.setColor(0x3849ff);
        //Colour of Text 
        String drwStr = msf.getSelectedMenuStr();
        int strW = f.stringWidth(drwStr);
        int strH = f.getHeight();
        g.drawString(drwStr, (w - strW) / 2, 27 - strH, anchor);
        //Line to sepparate selected option name from icon area 
        g.setColor(0x000000);
        g.setStrokeStyle(Graphics.SOLID);
        g.drawLine(0, 29, w, 29);
        g.drawLine(0, 30, w, 30);
        for (int i = 0; i < 4; i++) {
            int imgY = msf.getY(i);
            for (int j = 0; j < 3; j++) {
                int imgX = msf.getX(j);
                if (i == msf.getSelIcon(0) && j == msf.getSelIcon(1)) {
                    g.drawImage(icon[j][i], imgX - 5, imgY - 4, anchor);
                }
                else {
                    g.drawImage(icon[j][i], imgX, imgY, anchor);
                }
            }
        }
    }

    public void commandAction(Command c, Displayable d) {
        if (c == backCommand) {
            MainScreen ms = new MainScreen();
            Display.getDisplay(sesimulator.SESimulatorMidlet.instance).setCurrent(ms);
        }
        else if (c == selectCommand) {
            System.out.println("Select pressed");
        }
    }

    protected void keyPressed(int keyCode) {
        String str = getKeyName(keyCode);
        //For SE Emulator 
        /*if(str.equals("UP") || str.equals("DOWN") || str.equals("RIGHT") || str.equals("LEFT"))*/
        //For SE device 
        if (str.equals("Up") || str.equals("Down") || str.equals("Right") || str.equals("Left")) {
            //Fro SE emulator 
            /*if (str.equals("UP")) {
                msf.moveUp();
            }
            if (str.equals("DOWN")) {
                msf.moveDown();
            }
            if (str.equals("RIGHT")) {
                msf.moveRight();
            }
            if (str.equals("LEFT")) {
                msf.moveLeft();
            } */
            //For SE device 
            if (str.equals("Up")) {
                msf.moveUp();
            }
            if (str.equals("Down")) {
                msf.moveDown();
            }
            if (str.equals("Right")) {
                msf.moveRight();
            }
            if (str.equals("Left")) {
                msf.moveLeft();
            }
            loadMenuIcons();
            repaint();
        }
    }

    private void loadMenuIcons() {
        icon = new Image[3][4];
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 3; x++) {
                String str;
                if (x == msf.getSelIcon(0) && y == msf.getSelIcon(1)) {
                    str = "Icon" + msf.getImgNum(x, y) + "_selected.png";
                }
                else {
                    str = "Icon" + msf.getImgNum(x, y) + "_unselected.png";
                }
                icon[x][y] = il.loadImage(str);
            }
        }
    }
}

 

MenuScreenFunctions.java

package sesimulator.menus.functions;

/**
 * * @author Peter Miklosko
 */
public class MenuScreenFunctions {
    private int[] selIcon = {1, 1};

    private void setSelIcon(int x, int y) {
        selIcon[x] = y;
    }

    public int[] getSelIcon() {
        return selIcon;
    }

    public int getSelIcon(int x) {
        return selIcon[x];
    }

    private String[][] mOptions = {{"JukeBox", "Web'n'Walk", "Entertainment"}, 
            {"Camera", "Messages", "Media"}, 
            {"Radio", "Contacts", "Walkman"}, 
            {"Calls", "Organizer", "Settings"}};

    public String getSelectedMenuStr() {
        return mOptions[getSelIcon(1)][getSelIcon(0)];
    }

    private int[][] imgNum = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}};

    public int getImgNum(int x, int y) {
        return imgNum[y][x];
    } 
    /* 
    * Update coordinates of currently selected item based on received input. 
    * */

    public void moveUp() {
        if (getSelIcon(1) == 0) {
            setSelIcon(1, 3);
        }
        else {
            setSelIcon(1, getSelIcon(1) - 1);
        }
    }

    public void moveDown() {
        if (getSelIcon(1) == 3) {
            setSelIcon(1, 0);
        }
        else {
            setSelIcon(1, getSelIcon(1) + 1);
        }
    }

    public void moveRight() {
        if (getSelIcon(0) == 2) {
            if (getSelIcon(1) == 3) {
                setSelIcon(1, 0);
            }
            else {
                setSelIcon(1, getSelIcon(1) + 1);
            }
            setSelIcon(0, 0);
        }
        else {
            setSelIcon(0, getSelIcon(0) + 1);
        }
    }

    public void moveLeft() {
        if (getSelIcon(0) == 0) {
            if (getSelIcon(1) == 0) {
                setSelIcon(1, 3);
            }
            else {
                setSelIcon(1, getSelIcon(1) - 1);
            }
            setSelIcon(0, 2);
        }
        else {
            setSelIcon(0, getSelIcon(0) - 1);
        }
    }

    public int getY(int a) {
        int r = 0;
        switch (a) {
            case 0:
                r = 46;
                break;
            case 1:
                r = 100;
                break;
            case 2:
                r = 154;
                break;
            case 3:
                r = 208;
                break;
            default:
                break;
        }
        return r;
    }

    public int getX(int a) {
        int r = 0;
        switch (a) {
            case 0:
                r = 20;
                break;
            case 1:
                r = 94;
                break;
            case 2:
                r = 168;
                break;
            default:
                break;
        }
        return r;
    }
}

 



Compressed source folder
SESimulator.rar

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!