分享

[常见问题] 用Canvas创建高级菜单

 CevenCheng 2010-11-02

[常见问题] 用Canvas创建高级菜单

这个案例描述了如何使用低级UI API,也就是Canvas来创建高级菜单,界面如下图所示:

Image:Inactive_menu.png Image:Active_menu.png

本案例共包括三个类,MIDlet,GUI和Menu。其中,当MIDlet启动后,Options和exit会绘制在屏幕

的底部,当用户按左或者右软键的时候,程序会根据键值响应不同的动作。例如选择options后,

会弹出menu供用户选择。

GUI类持有一个Menu对象,并且根据用户的输入来改变Menu的状态,然后重新绘制屏幕。事实上menu只有两种状态,一种是激活的,一种是非激活的。只有激活状态下,菜单才会显示出来,并且可以接受用户的上下左右选择,当用户选择了Menu里面的选项之后,GUI会把用户的选择显示在屏幕上。代码如下所示:

Midlet.java

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
 
 
 
public class Midlet extends MIDlet {
    
    private Display display;
    
    private GUI gui;
    
    
    
    
    
    public void startApp() {
 
        display = Display.getDisplay(this);
        
        
        if (display == null) {
            
            destroyApp(false);
            
        } // end if display is not allocated
        
 
        gui = new GUI(this);
        
        display.setCurrent(gui);
        
        gui.start();
        
    } // end startApp
    
    
    
    
    
    public void pauseApp() {
    } // end pauseApp
    
    
    
    
    
    public void destroyApp(boolean unconditional) {
        
        display.setCurrent(null);
        
        notifyDestroyed();
        
    } // end destroyApp
    
} // end Midlet.java


GUI.java


import java.util.*;
 
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
 
import javax.microedition.media.*;
import javax.microedition.media.control.*;
 
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;
 
 
 
class GUI extends GameCanvas {
    
    private Midlet midlet;
    
    private Display display;
    
    private Graphics g;
    
    private Font font;
    
    private int width = 0;
    private int height = 0;
    
    
    private Menu menu;
    
    private String leftOption;
    private String rightOption;
    private String[] menuOptions;
    
    private int currentlySelectedIndex = 0;
    
    private boolean menuIsActive = false;
    
    
    
    
    /**
     * Creates a new instance of GUI.
     */
    public GUI(Midlet midlet) {
        
        super(false);
        
        this.midlet = midlet;
        
        font = Font.getFont(Font.FACE_SYSTEM, 
Font.STYLE_PLAIN, Font.SIZE_SMALL);
        
        setFullScreenMode(true);
        
        width = getWidth();
        height = getHeight();
        
        
        g = getGraphics();
        
        
        leftOption = "Options";
 // will be displayed only when menu is not active
        rightOption = "Exit"; 
// will be displayed only when menu is not active
        menuOptions = new String[] 
{"Option #1", "Option #2", "Option #3", "Option #4"};
        
        menu = new Menu(leftOption, rightOption, menuOptions);
        
    } // end constructor
    
    
    
    
    
    public void start() {
        
        clearScreen();
        
        menu.drawInactiveMenu(this, g);
        
    } // end start
    
    
    
    
    // softkey codes may vary from phone to phone
    // -6 and -7 values are OK on Nokia phones
 
    private int LEFT_SOFTKEY_CODE = -6; 
// check it for your phone model
    private int RIGHT_SOFTKEY_CODE = -7; 
// check it for your phone model
    
    
    protected void keyPressed(int keyCode) {
        
        
        // work with menu according to its current state
        
        if (menuIsActive) { // draw active menu
            
            
            if (keyCode == RIGHT_SOFTKEY_CODE) {
                
                // draw inactive menu again
                
                clearScreen();
                
                menu.drawInactiveMenu(this, g);
                
                menuIsActive = false;
                
            } // end if "Cancel" was pressed on active menu
            
            
            // otherwise check navigation
            
            keyCode = getGameAction(keyCode);
 
            
            if (keyCode == UP) {
 
                currentlySelectedIndex--;
 
                if (currentlySelectedIndex < 0) {
 
                    currentlySelectedIndex = 0; // stay within limits
 
                }
                
                clearScreen();
                
                menu.drawActiveMenu(this, g, currentlySelectedIndex); 
// repaint active menu
 
            } // end if UP button was pressed
            else if (keyCode == DOWN) {
 
                currentlySelectedIndex++;
 
                if (currentlySelectedIndex >= menuOptions.length) {
 
                    currentlySelectedIndex = menuOptions.length - 1; 
// stay within limits
                
                }
                
                clearScreen();
                
                menu.drawActiveMenu(this, g, currentlySelectedIndex);
 // repaint active menu
 
            } // end if DOWN button was pressed
            else if (keyCode == FIRE) {
                
                // menu option is selected
                
                // simply draw selected option
                
                clearScreen();
                
                g.setColor(0x000000); // black
                
                g.drawString("[" +
 menuOptions[currentlySelectedIndex] + 
"] was selected", 10, 15, g.LEFT | g.TOP);
                
                menu.drawInactiveMenu(this, g);
                
                menuIsActive = false;
                
            } // end if FIRE button was pressed
            
            
        } // end if menu is active
        else { // draw inactive menu
            
            // check if the "Options" or "Exit" buttons were pressed
            
            if (keyCode == LEFT_SOFTKEY_CODE) { // "Options" pressed
                
                clearScreen();
                
                currentlySelectedIndex = 0;
                
                menu.drawActiveMenu(this, g, currentlySelectedIndex); 
// activate menu
                
                menuIsActive = true;
                
            } // end if "Options" was pressed
            else if (keyCode == RIGHT_SOFTKEY_CODE) {
                
                exitGUI();
                
            } // end if "Exit" was pressed
            
        } // end if menu is not active
        
    } // end keyPressed
    
    
    
    
    
    public void exitGUI() {
        
        midlet.destroyApp(false);
        midlet.notifyDestroyed();
        
    } // end exitGUI
    
    
    
    
    
    public void clearScreen() {
        
        g.setColor(0xffffff); // white
        g.fillRect(0, 0, width, height);
        flushGraphics();
        
    } // end clearScreen
    
} // end GUI.java


Menu.java


import java.util.*;
 
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
 
 
 
public class Menu {
    
    private String leftOption; 
// will be displayed when menu is inactive
    private String rightOption; 
// will be displayed when menu is inactive
    private String cancelOption = "Cancel"; 
// also may be "Back" or something else
    private String[] menuOptions;
    
    private int padding = 5; // just like in CSS
 
 
    
    
    
    /**
     * Creates a new instance of Menu.
     */
    public Menu(String leftOption, String rightOption, String[] 
menuOptions) {
        
        this.leftOption = leftOption;
        this.rightOption = rightOption;
        this.menuOptions = menuOptions;
        
    } // end constructor
    
    
    
    
    
    public void drawInactiveMenu(GameCanvas canvas, Graphics g) {
        
        // create inactive menu font
        
        Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
 Font.SIZE_MEDIUM);
        
        int fontHeight = font.getHeight();
        
        
        // clear inactive menu background
        
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        
        g.setColor(0xcccccc); // grey color
        g.fillRect(0, height - fontHeight - 2 * padding, width, height);
        
        
        // draw left and right menu options
        
        g.setFont(font);
        g.setColor(0x000000); // black
        
        g.drawString(leftOption, padding, height - padding, 
g.LEFT | g.BOTTOM);
        g.drawString(rightOption, width - padding, height - padding, 
g.RIGHT | g.BOTTOM);
        canvas.flushGraphics();
        
    } // end drawInactiveMenu
    
    
    
    
    
    
    public void drawActiveMenu(GameCanvas canvas,
 Graphics g, int selectedOptionIndex) {
        
        // create active menu font
        
        Font font = Font.getFont(Font.FACE_SYSTEM,
 Font.STYLE_BOLD, Font.SIZE_MEDIUM);
        
        int fontHeight = font.getHeight();
        
        
        // clear menu bar background
        
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        
        g.setColor(0xcccccc);
        g.fillRect(0, height - fontHeight - 2 * padding, 
width, height);
        
        
        // draw default menu bar options
        
        g.setFont(font);
        g.setColor(0x000000); // black
        
        // draw "Cancel" option
        g.drawString(cancelOption, width - padding, height - padding,
 g.RIGHT | g.BOTTOM);
        canvas.flushGraphics();
        
        
        // draw menu options
        
        if (menuOptions != null) {
            
            // check out the max width of a menu
 (for the specified menu font)
            
            int menuMaxWidth = 0;
            int menuMaxHeight = 0;
            int currentWidth = 0;
 
            // we'll simply check each option and find the
 maximal width
 
            for (int i = 0; i < menuOptions.length; i++) {
                
                currentWidth = font.stringWidth(menuOptions[i]);
                
                if (currentWidth > menuMaxWidth) {
                    menuMaxWidth = currentWidth; // update
                }
                
                menuMaxHeight += fontHeight + padding; 
// for a current menu option
                
            } // end for each menu option
            
            
            menuMaxWidth += 2 * padding; 
// padding from left and right
            
            
            // now we know the bounds of active menu
            
            
            // draw active menu's background
            
            g.setColor(0xcccccc);
            g.fillRect(0, // x
                       height - fontHeight - 
2 * padding - menuMaxHeight, // y
                       menuMaxWidth,
                       menuMaxHeight);
            
            
            // draw menu options (from up to bottom)
            
            g.setFont(font);
            
            int menuOptionX = padding;
            int menuOptionY = height - fontHeight - 2 * padding
 - menuMaxHeight + padding;
            
            for (int i = 0; i < menuOptions.length; i++) {
                
                if (i != selectedOptionIndex) { 
// draw unselected menu option
                    
                    g.setColor(0x000000); // black
                    
                } // end if draw unselected menu option
                else { // draw selected menu option
                    
                         g.setColor(0x0000ff); // blue
                    
                } // end if draw selected menu option
                
                
                g.drawString(menuOptions[i], menuOptionX, 
menuOptionY, g.LEFT | g.TOP);
                
                menuOptionY += padding + fontHeight;
                
            } // end for each menu option
            
            
            canvas.flushGraphics();
            
            
        } // end if menu options were specified
        
    } // end drawActiveMenu
    
} // end Menu.java

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多