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

来源:百度文库 编辑:神马文学网 时间:2024/09/30 03:34:32
[常见问题] 用Canvas创建高级菜单
这个案例描述了如何使用低级UI API,也就是Canvas来创建高级菜单,界面如下图所示:
 
本案例共包括三个类,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; privateGraphics g; privateFont font; private int width = 0; private int height = 0; privateMenu menu; privateString leftOption; privateString rightOption; privateString[] 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 = newString[] {"Option #1", "Option #2", "Option #3", "Option #4"}; menu = newMenu(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 classMenu { privateString leftOption; // will be displayed when menu is inactive privateString rightOption; // will be displayed when menu is inactive privateString cancelOption = "Cancel"; // also may be "Back" or something else privateString[] menuOptions; private int padding = 5; // just like in CSS   /** * Creates a new instance of Menu. */ publicMenu(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 fontFont 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 fontFont 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