📄 menu.java
字号:
// Copyright (c) 2005 Sony Ericsson Mobile Communications AB
//
// This software is provided "AS IS," without a warranty of any kind.
// ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
// INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
//
// THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se)
package bluegammon.gui.menu;
import java.util.Stack;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import bluegammon.Device;
/**
* <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 Peter Andersson
*/
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)
{
if (keyCode == Device.KEYCODE_BACK)
{
goBack();
return;
}
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()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -