📄 menu.java
字号:
package myGame.gui.menu;
import java.util.Stack;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
/**
* <p>
* The <code>Menu</code> class takes care of coordination between
* <code>MenuPage</code>s, <code>PageItem</code>s and user interaction. It
* contains a navigation stack to handle breadcrumb behaviour. It handles the
* painting of the menu via a <code>MenuPainter</code>.
* </p>
* <p>
* The navigation tree can either be implemented in the <code>PageItem</code>s
* constructor, or via an implementation of <code>ItemAction</code> that uses
* the method <code>gotoPage</code> in this class.
* </p>
* <p>
* A common example for using a <code>Menu</code>:
* </p>
* <p>
*
* <pre>
* public class MenuCanvas extends Canvas implements ItemAction {
* static final int PRINT_1 = 1;
*
* static final int PRINT_2 = 2;
*
* Menu m_menu;
*
* public MenuCanvas() {
* // Create pages
* MenuPage mainPage = new MenuPage("STARTPAGE".toCharArray(), null);
* MenuPage nextPage = new MenuPage("NEXTPAGE".toCharArray(), null);
*
* // Create menu items
* PageItem anItem = new PageItem("Goto next page".toCharArray(), null,
* null, nextPage);
* PageItem anotherItem = new PageItem("Print 1".toCharArray(), null,
* this, null, PRINT_1);
* PageItem yetAnotherItem = new PageItem("Print 2".toCharArray(), null,
* this, null, PRINT_2);
*
* // Assign items to pages
* mainPage.addItem(anItem);
* mainPage.addItem(anotherItem);
* nextPage.addItem(yetAnotherItem);
*
* // Create and setup menu
* m_menu = new Menu(mainPage, this, new DefaultMenuPainter());
* int menuPadding = 16;
* m_menu.setLocation(0, menuPadding);
* m_menu.setDimensions(getWidth(), getHeight() - menuPadding * 2);
* m_menu.setFrameData(10, 20); // 10 frames per transition, 20 ms between each frame
* m_menu.start();
* }
*
* protected void paint(Graphics g) {
* g.setColor(0x000000);
* g.fillRect(0, 0, getWidth(), getHeight());
* m_menu.paint(g);
* }
*
* protected void keyPressed(int keyCode) {
* m_menu.keyPressed(keyCode);
* }
*
* public void itemAction(MenuPage page, PageItem item) {
* int id = item.getId();
* switch (id) {
* case PRINT_1:
* System.out.println("Item 1 is invoked");
* break;
* case PRINT_2:
* System.out.println("Item 2 is invoked");
* break;
* }
* }
* }
* </pre>
*
* </p>
*
* @author YuBingxing
*/
public class Menu implements Runnable {
/** The menu painter */
protected MenuPainter m_painter;
/** The start page of this menu */
protected MenuPage m_startPage;
/** Current page */
protected MenuPage m_curPage;
/** Current selected item index in current page */
protected int m_curItemIndex;
/** Transition flag */
protected boolean m_inTransition;
/** Back transition flag */
protected boolean m_transitionBack;
/** Transition destination page */
protected MenuPage m_transPage;
/** Current transition frame */
protected int m_frame;
/** Maximum transition frames */
protected int m_frames;
/** Transition frame delay in milliseconds, 500 as default */
protected long m_frameDelay = 500;
/**
* The menu listener. For a compact framework, we allow only one listener.
*/
protected MenuListener m_listener;
/** Animation lock */
protected final Object ANIM_LOCK = new Object();
/** Thread running flag */
protected volatile boolean m_running = true;
/** The canvas that renders this menu */
protected Canvas m_canvas;
/** The navigation trail stack */
protected Stack m_history = new Stack();
/** Menu width */
protected int m_width = 0;
/** Menu height */
protected int m_height = 0;
/** Menu x offset */
protected int m_x = 0;
/** Menu y offset */
protected int m_y = 0;
/**
* Creates a new menu.
*
* @param startPage
* The first page in this menu.
* @param canvas
* The canvas that this menu is drawn upon.
* @param painter
* The painter used to draw this menu.
*/
public Menu(MenuPage startPage, Canvas canvas, MenuPainter painter) {
m_startPage = startPage;
setCanvas(canvas);
setPainter(painter);
}
/**
* Activates this menu and jumps to the starting page.
*/
public void start() {
new Thread(this, "Menu thread").start();
gotoPage(m_startPage);
}
/**
* Call this from your displayable's paint method to paint the menu.
*
* @param g
* The graphics context.
*/
public void paint(Graphics g) {
if (m_width == 0 && m_height == 0 && m_canvas != null) {
m_width = m_canvas.getWidth() - m_x;
m_height = m_canvas.getHeight() - m_y;
}
if (m_inTransition && m_frames > 0) {
m_painter.paintTransition(g, m_curPage, m_transPage, m_x, m_y,
m_width, m_height, m_frame, m_frames, m_transitionBack);
} else {
m_painter.paintMenu(g, m_curPage, m_x, m_y, m_width, m_height);
}
}
/**
* Call this from your displayable's keyPressed or keyRepeated method invoke
* user interaction on the menu.
*
* @param keyCode
* The keyCode.
*/
public void keyPressed(int keyCode) {
MenuPage curPage = getCurrentPage();
if (curPage != null && m_canvas != null) {
int gameCode = m_canvas.getGameAction(keyCode);
switch (gameCode) {
case Canvas.LEFT:
goBack();
break;
case Canvas.FIRE:
case Canvas.RIGHT:
PageItem item = getSelectedItem();
if (gameCode == Canvas.FIRE && item != null
&& item.getAction() != null) {
doAction(item.getAction(), curPage, item);
}
if (item != null && item.getSubPage() != null) {
gotoPage(item.getSubPage());
}
break;
case Canvas.UP:
setSelectedItemIndex(getSelectedItemIndex() - 1);
break;
case Canvas.DOWN:
setSelectedItemIndex(getSelectedItemIndex() + 1);
break;
}
}
}
/**
* Steps forward to a new page.
*
* @param newPage
* The new page.
*/
public void gotoPage(MenuPage newPage) {
MenuPage curPage = null;
synchronized (ANIM_LOCK) {
curPage = getCurrentPage();
if (curPage != null) {
m_history.push(curPage);
}
}
if (m_listener != null) {
m_listener.newPage(curPage, newPage, false);
m_listener.itemSelected(newPage, null, newPage == null ? null
: (newPage.itemAt(newPage.getSelectedIndex())));
}
startTransition(curPage, newPage, false);
}
/**
* Steps back to previous page. Does nothing if there are no previous pages.
*/
public void goBack() {
MenuPage curPage = null;
MenuPage backPage = null;
synchronized (ANIM_LOCK) {
curPage = getCurrentPage();
if (m_history.size() > 0) {
backPage = (MenuPage) m_history.pop();
}
}
if (backPage != null) {
if (m_listener != null) {
m_listener.newPage(curPage, backPage, true);
m_listener.itemSelected(backPage, null, backPage == null ? null
: (backPage.itemAt(backPage.getSelectedIndex())));
}
startTransition(curPage, backPage, true);
}
}
/**
* Executes specified action.
*
* @param action
* The action to execute.
* @param page
* The page from which the action was executed.
* @param item
* The item the action is called from.
*/
protected void doAction(final ItemAction action, final MenuPage page,
final PageItem item) {
new Thread(new Runnable() {
public void run() {
try {
action.itemAction(page, item);
if (m_listener != null) {
m_listener.actionCalled(page, item, action);
}
if (m_canvas != null) {
m_canvas.repaint();
}
} catch (Throwable t) {
System.out.println("Exception in ItemAction");
t.printStackTrace();
}
}
}, "ItemAction runner").start();
}
/**
* Returns current page. If a transition between pages are ongoing, the
* destination page of the transition is returned.
*
* @return Current page.
*/
public MenuPage getCurrentPage() {
MenuPage curPage = null;
synchronized (ANIM_LOCK) {
if (m_inTransition) {
curPage = m_transPage;
} else {
curPage = m_curPage;
}
}
return curPage;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -