参考文档:
http://www.iteye.com/topic/479217
MenuMidlet类:是主类;Menu类:Menu的绘制;MenuScreen类:Menu事件处理。
1. 菜单绘制
(1)菜单有两种状态:激活状态和非激活状态。
在激活状态下,显示菜单项,并且可以接受用户的上下选择事件;在非激活状态下,隐藏菜单项,不接受用户的上下选择事件。
(2)菜单的绘制包括激活状态下的菜单绘制和非激活状态下的菜单绘制
非激活状态下的菜单绘制包括:左菜单(options)和右菜单(exit)绘制;激活状态下的菜单绘制包括:左菜单(options)和右菜单(cancel)绘制,左菜单项(新建,设定,记录,帮助,关于)绘制。
2.菜单事件处理
Canvas提供了keyPressed(int key)来响应用户的按键;Canvas中的gameAction是将手机键盘映射成为游戏动作的机制。
3.代码
public class Menu {
private String leftOption;
private String rightOption;
private String cancelOption = "Cancel";
private String[] menuOptions;
private int padding = 5;
// 颜色设置
private static final int defaultFontColor = 0x000000; // 默认字体颜色
private static final int selectedFontColor = 0xfff000; // 选中后字体颜色
private static final int bgColor = 0xCCCCCC;// 菜单背景色
private static final int highLight = 0x0000ff;// 选中的菜单高亮显示颜色
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(bgColor); // grey color
g.fillRect(0, height - fontHeight - 2 * padding, width, height);
// draw left and right menu options
g.setFont(font);
g.setColor(defaultFontColor); // black
g.drawString(leftOption, padding, height - padding, Graphics.LEFT | Graphics.BOTTOM);
g.drawString(rightOption, width - padding, height - padding, Graphics.RIGHT | Graphics.BOTTOM);
canvas.flushGraphics();
} // end drawInactiveMenu
public void drawActiveMenu(GameCanvas canvas, Graphics g, int selectedOptionIndex) {
Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM);
int fontHeight = font.getHeight();
int width = canvas.getWidth();
int height = canvas.getHeight();
g.setColor(bgColor);
g.fillRect(0, height - fontHeight - 2 * padding, width, height);
// draw default menu bar options
g.setFont(font);
g.setColor(0x000000); // black
g.drawString(leftOption, padding, height - padding, Graphics.LEFT | Graphics.BOTTOM);
// draw "Cancel" option
g.drawString(cancelOption, width - padding, height - padding, Graphics.RIGHT | Graphics.BOTTOM);
canvas.flushGraphics();
// draw menu options
if (menuOptions != null) {
// 确定菜单的最大宽度、最大高度
int menuMaxWidth = 0;
int menuMaxHeight = 0;
int currentWidth = 0;
for (int i = 0; i < menuOptions.length; i++) {
currentWidth = font.stringWidth(menuOptions[i]);
if (currentWidth > menuMaxWidth) {
menuMaxWidth = currentWidth;
}
menuMaxHeight += fontHeight + padding;
}
menuMaxWidth += 6 * padding;
g.setColor(bgColor);
g.fillRect(0, // x
height - fontHeight - 2 * padding - menuMaxHeight, // y
menuMaxWidth, menuMaxHeight);
g.setFont(font);
int menuOptionX = padding;
int menuOptionY = height - fontHeight - 2 * padding - menuMaxHeight
+ padding;
for (int i = 0; i <= menuOptions.length; i++) {
g.setColor(highLight);
int lineOptionY = height - fontHeight - 2 * padding
- menuMaxHeight + i * (fontHeight + padding);
g.drawLine(0, lineOptionY, menuMaxWidth - 1, lineOptionY);
}
for (int i = 0; i < menuOptions.length; i++) {
if (i != selectedOptionIndex) {
// draw unselected menu option
g.setColor(defaultFontColor); // black
g.drawString(menuOptions[i], menuOptionX, menuOptionY, Graphics.LEFT | Graphics.TOP);
} else {
// draw selected menu option
g.setColor(highLight);
int highOptionY = height - fontHeight - 2 * padding
- menuMaxHeight + i * (fontHeight + padding);
g.fillRect(0, highOptionY, menuMaxWidth, fontHeight
+ padding);
g.setColor(selectedFontColor);
g.drawString(menuOptions[i], menuOptionX, menuOptionY, Graphics.LEFT | Graphics.TOP);
}
menuOptionY += padding + fontHeight;
}
canvas.flushGraphics();
}
}
}
public class MenuScreen extends GameCanvas {
static int width; // screen width
static int height; // screen height
private int LEFT_SOFTKEY_CODE = -6;
private int RIGHT_SOFTKEY_CODE = -7;
// Menu Item Labels
static final String[] menuOptions = { "新建", "设置", "记录", "帮助", "关于" };
static int menuIdx;// 记录是在第几个菜单处按下的确定键。
private int currentlySelectedIndex = 0;
private boolean menuIsActive = false;
private String leftOption;
private String rightOption;
private Graphics g;
private Menu menu;
// Constructor
public MenuScreen(MenuMidlet midlet) {
super(false);
// Get Width and Height of Canvas
width = getWidth();
height = getHeight();
setFullScreenMode(true);
menuIdx = 0;
g = getGraphics();
leftOption = "Options";
rightOption = "Exit";
menu = new Menu(leftOption, rightOption, menuOptions);
start();
midlet.display.setCurrent(this);
}
public void start() {
clearScreen();
menu.drawInactiveMenu(this, g);
}
public void clearScreen() {
g.setColor(0xffffff); // white
g.fillRect(0, 0, width, height);
flushGraphics();
}
protected void keyPressed(int keyCode) {
if (menuIsActive) {
if (keyCode == RIGHT_SOFTKEY_CODE) {
// draw inactive menu again
clearScreen();
menu.drawInactiveMenu(this, g);
menuIsActive = false;
}
keyCode = getGameAction(keyCode);
if (keyCode == UP) {
currentlySelectedIndex--;
if (currentlySelectedIndex < 0) {
currentlySelectedIndex = 0; // stay within limits
}
menu.drawActiveMenu(this, g, currentlySelectedIndex);
} else if (keyCode == DOWN) {
currentlySelectedIndex++;
if (currentlySelectedIndex >= menuOptions.length) {
currentlySelectedIndex = menuOptions.length - 1;
}
menu.drawActiveMenu(this, g, currentlySelectedIndex);
} else if (keyCode == FIRE) {
clearScreen();
g.setColor(0x000000);
g.drawString("[" + menuOptions[currentlySelectedIndex]
+ "] was selected", 10, 15, Graphics.LEFT | Graphics.TOP);
menu.drawInactiveMenu(this, g);
menuIsActive = false;
}
} else {
if (keyCode == LEFT_SOFTKEY_CODE) { // "Options" pressed
menu.drawActiveMenu(this, g, currentlySelectedIndex);
menuIsActive = true;
} else if (keyCode == RIGHT_SOFTKEY_CODE) {
}
}
}
}
public class MenuMidlet extends MIDlet {
private MenuScreen menuScreen;
Display display;
public MenuMidlet() {
display= Display.getDisplay(this);
menuScreen = new MenuScreen(this);
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
}
}
4.http://www.iteye.com/topic/31909
http://www.iteye.com/topic/35427
本博文未完,误发布了。把自己过去半年来自己写的customized ui总结上来。