📄 menubarcanvas.java
字号:
/**
//MenuBar文档生成日期:2006.02.10
//
//(1)概述:
//类名称:MenuBarCanvas
//类说明:
// 提供在Canvas上绘制二级菜单的功能,并可以实际处理菜单命令,当然也可以将菜单命令转移到其他类中统一处理。
*
//所在子系统:MenuBar
//
//系统总描述:
我们提供的MenuBar J2ME版本 就是这么一种概念:
一个可以下载到手机(例如Nokia7610已经确实可以下载安装并运行)的Java应用程序。
他模仿Opera Mini的界面风格以及操纵模式,未来试图向ucweb学习底边状态栏的绘制。
这种风格我们称之为二级菜单,甚至多级菜单。它可以在小小的手机屏幕上展示如何提供尽可能多的菜单命令。
//(2)历史记录:
//创建人: 郑昀(2006.02.10)
//联系我: Google Talk >> zhengyun@gmail.com
//Blogs: http://blog.csdn.net/zhengyun_ustc/以及http://www.cnblogs.com/zhengyun_ustc
//(3)版权声明:
//我这个版本的MenuBar,代码您可以借鉴,但不得用于商业用途,除非得到本人的授权。
////////////////////////////////////////////////////////////////////*/
package com.ultrapower.canvas;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import com.ultrapower.gui.SoftButtonControl;
import com.ultrapower.midlet.MenuBarlet;
/**
* 拜Saltedfish所赐,终于得窥二级菜单法门,特此感谢.
* @author VictorZheng
* 旁白: 在Canvas上绘制一个二级菜单,类似于opera mini的那种风格。
*/
public class MenuBarCanvas extends Canvas implements CommandListener{
// midlet对象引用,用以在必要时候退出应用程序
protected MenuBarlet m_midlet;
////////////////////////////
// 菜单项的容器以及各种辅助参数:
// 在这里我们定义第一级弹出的菜单为主菜单,第二级菜单为子菜单;
//
protected Font m_MenuFont =
Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE); // 我们定义一个菜单字体
protected int m_MenuSelectedIndex = 0; // 第一级菜单(主菜单)选择的焦点
protected int m_MenuItemHeight = m_MenuFont.getHeight() + 2; // 每一个菜单项的绘制矩形的高度
protected int m_MenuItemWidth = 110; // 每一个菜单项的绘制矩形的宽度
protected Hashtable m_MenuTable; // 菜单的存放器(可以存储第一级菜单,也可能存储第二级菜单)
protected Hashtable m_MenuBarTable; // 第二级菜单(子菜单)的存放器
protected int m_selectedBarID = 0; // 第二级菜单(子菜单)的选择焦点
protected boolean m_showMenu = false; // 是否画菜单的标志
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
/** 屏幕最下面的Softbutton,分为两组:
* “开始菜单”和“退出应用”
* “选择”和“取消” */
protected static final Command CMD_MAINMENU =
new Command("开始菜单", Command.ITEM, 1);
/** Softbutton 选择 command */
protected static final Command CMD_SELECT =
new Command("选择", Command.ITEM, 1);
/** Softbutton 退出 command */
protected static final Command CMD_CANCEL =
new Command("取消", Command.ITEM, 1);
/** Softbutton 退出 command */
protected static final Command CMD_EXIT =
new Command("退出应用", Command.ITEM, 1);
//////////////////////////////////////////////////////////////////
/** Softbuttons of the menu canvas */
protected SoftButtonControl m_softButtons;
//////////////////////////////////////////////////////////////////
// 创建涉及到主菜单和子菜单们的所有命令
protected MenuItem MyFeedsCmd = new MenuItem(0, "我的订阅(1)", null, true);
protected MenuItem SettingsCmd = new MenuItem(1, "设置(2)", null, true);
protected MenuItem StatCmd = new MenuItem(2, "统计信息(3)", null, false);
protected MenuItem AboutMeCmd = new MenuItem(3, "关于我(4)", null, false);
protected MenuItem Feed1Cmd = new MenuItem(4, "对牛乱弹琴(4)", MyFeedsCmd, false);
protected MenuItem Feed2Cmd = new MenuItem(5, "北京女病人(2)", MyFeedsCmd, false);
protected MenuItem Feed3Cmd = new MenuItem(6, "sayonly(1)", MyFeedsCmd, false);
protected MenuItem Feed4Cmd = new MenuItem(7, "Alex Barnett", MyFeedsCmd, false);
protected MenuItem Feed5Cmd = new MenuItem(8, "TechCrunch(1)", MyFeedsCmd, false);
protected MenuItem Feed6Cmd = new MenuItem(9, "旁观者(5)", MyFeedsCmd, false);
protected MenuItem Feed7Cmd = new MenuItem(10, "搜索引擎研究", MyFeedsCmd, false);
protected MenuItem BloglinesUserNameCmd = new MenuItem(11, "Bloglines用户名", SettingsCmd, false);
protected MenuItem BloglinesUserPassCmd = new MenuItem(12, "Bloglines密码", SettingsCmd, false);
protected MenuItem UsingCmwapCmd = new MenuItem(13, "用cmwap代理", SettingsCmd, false);
//////////////////////////////////////////////////////////////////
/** Singleton instance */
protected static MenuBarCanvas m_inst = null;
//////////////////////////////////////////////////////////////////
// 这里声明关于背景图片等Image信息的参数,从而可以很容易地加入图片信息,并可加载后存储在Image Cache中
// Image keys
private static final int OFFSET_IMG = 100;
private static final int IMG_FRAME = 100;
private Image m_FrameBackgroundImg;
// Image cache
protected static Hashtable m_images = new Hashtable();
// Image resource names
protected static final String[] IMGNAME_MAP ={
"background.png",
};
//////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// 关于各种颜色的定义
/*
* 界面上的相片框边缘的填充颜色,0x8cc567是较浅的绿色
*/
protected int m_borderFillRectColor = 0xb5d794;
/*
* 界面上的选中菜单的填充颜色,0xefbe6是浅黄色
*/
protected int m_SelectedMenuItemFillRectColor = 0xefbe63;
/*
* 界面上的没有选中菜单的填充颜色,0x8cc363是较深一点的绿色
*/
protected static final int m_UnselectedMenuItemFillRectColor = 0x8cc363;
/*
* 选中的菜单的边界底色,0xbb440000是棕褐色
*/
protected static final int m_SelectedMenuItemBorderColor = 0x8cc363;
/*
* 没有选中的菜单的边界底色
*/
protected static final int m_UnselectedMenuItemBorderColor = 0xffffff;
/*
* 菜单标题文本的字体颜色,0xffffff是白色
*/
protected int m_SelectedMenutextColor = 0xffffff;
////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////
// 独立的菜单项类,用于添加到一级和二级菜单存放器中:
class MenuItem
{
public int offx,offy; // 菜单项的位置坐标
public int menuid; // 菜单的顺序编号,可以是不连续的
public String menustr;
public MenuItem MenuParent; // 父菜单
public boolean hasIssue; // 是否有子菜单
public MenuItem(int id,String str,MenuItem parent,boolean issue)
{
menuid = id;
menustr = str;
MenuParent = parent;
hasIssue = issue;
}
}
/////////////////////////////////////////////////////
/**
* Returns the singleton instance.
* @return The singleton instance.
*/
public static MenuBarCanvas getInstance(Display display, MenuBarlet midlet) throws Exception
{
if (m_inst == null)
{
m_inst = new MenuBarCanvas(display, midlet);
}
return m_inst;
}
/**
* Creates the menu and initiates the gui controls
*/
protected MenuBarCanvas(Display display, MenuBarlet midlet) throws Exception
{
System.out.println("Enter MenuBarCanvas(Display)!");
/*
* 如果装载菜单项的HashTable为空,则创建一个出来
*/
if (m_MenuTable == null)
{
m_MenuTable = new Hashtable();
}
m_midlet = midlet;
// 加载背景图片:
m_FrameBackgroundImg = getImage(IMG_FRAME);
// 初始化软键绘制对象
m_softButtons = new SoftButtonControl();
/*
* 初始化界面上的第一级菜单
*/
this.addMenu(MyFeedsCmd); // 我的Feeds
this.addMenu(SettingsCmd); // 设置
this.addMenu(StatCmd); // 统计信息
this.addMenu(AboutMeCmd); // 关于我
/*
* 计算每一个菜单项的X和Y方向偏移坐标,存储在每一个菜单项MenuItem对象中
*/
updateMenuItemCoordinate();
/*
* 设置为全屏状态
*/
setFullScreenMode(true);
/*
* Initiate softbuttons.
* init函数最后一个参数指绘制SoftButton的界面风格,是左右两个软键呢,还是一个长条的状态栏.
*
* 在初始化界面的时候,左软键是CMD_MAINMENU(“开始菜单”),右软键是CMD_EXIT("退出应用")
*/
m_softButtons.init(this,
Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE),
CMD_MAINMENU, CMD_EXIT,
false);
m_softButtons.setCommandListener(this);
System.out.println("End MenuBarCanvas(Display)!");
}
/**********************************************************
// MenuBarCanvas::paint()
//
// Description:
// 画图主方法中,判断是否画菜单,然后执行:
* 1.每次都事先清理屏幕,以防止某些区域不更新
* 2.绘制背景图片在屏幕正中间;
* 3.画菜单
* 4.画左右软键(抑或是状态栏)的菜单文字
//
// Parameters:
* g - the Graphics object to be used for rendering the Canvas
// Return Values:
// Author:
// zhengyun@ultrapower 2006.02.13
//
**********************************************************/
public void paint(Graphics g)
{
System.out.println("Enter paint!");
// 每次都将屏幕上所有东西清除掉
ClearGraphics(g);
// 绘制背景图片在屏幕正中间:
g.drawImage(m_FrameBackgroundImg,
getWidth() / 2, getHeight() / 2, Graphics.VCENTER | Graphics.HCENTER);
// 画菜单
if (m_showMenu)
{
drawMenuBarandItem(g);
}
//else
/*{
// 我们手工画左右软键的菜单文字
System.out.println("paint>>画菜单.");
g.setColor(0);
g.drawString("<选择>", 8, getHeight() - g.getFont().getHeight() - 8,
20);
g.drawString("<取消>",
getWidth() - g.getFont().stringWidth("<取消>") - 8,
getHeight() - g.getFont().getHeight() - 8, 20);
}*/
/*
* 每次都召唤SoftButtonControl绘制自身,防止被别的图样遮盖
*/
m_softButtons.paint(g);
}
/**********************************************************
// MenuBarCanvas::drawMenuBarandItem()
//
// Description:
// 被paint直接调用的画菜单方法:
* 1.让当前所选的菜单索引值始终保持在菜单集合内
* 2.画子菜单;
* 3.画主菜单;
//
// Parameters:
* g - the Graphics object to be used for rendering the Canvas
// Return Values:
// Author:
// zhengyun@ultrapower 2006.02.13
//
**********************************************************/
public void drawMenuBarandItem(Graphics g)
{
System.out.println("Enter drawMenuBarandItem!");
if(m_MenuTable == null)
{
System.out.println("MenuTable is empty!");
return;
}
// 让当前所选的菜单索引值始终保持在菜单集合内
//
if (m_MenuSelectedIndex > m_MenuTable.size() - 1)
{
m_MenuSelectedIndex = 0;
}
else if (m_MenuSelectedIndex < 0)
{
m_MenuSelectedIndex = m_MenuTable.size() - 1;
}
// 画子菜单:
// m_MenuBarTable中装载的是子菜单.
// m_selectedBarID则是子菜单上被选择的焦点索引,被选中的子菜单项绘制起来将会略有不同,
// 所以要将此数值传入drawMenu函数.
if (m_MenuBarTable != null)
{
System.out.println("开始画子菜单!被选择的焦点索引=" + m_selectedBarID);
drawMenu(m_MenuBarTable, m_selectedBarID, g);
}
// 画主菜单
// m_MenuTable中装载的是主菜单.
// m_MenuSelectedIndex则是主菜单上被选择的焦点索引,被选中的主菜单项绘制起来将会略有不同,
// 所以要将此数值传入drawMenu函数.
if(m_MenuTable != null)
{
System.out.println("开始画主菜单!被选择的焦点索引=" + m_MenuSelectedIndex);
drawMenu(m_MenuTable, m_MenuSelectedIndex, g);
}
}
/**********************************************************
// MenuBarCanvas::drawMenu()
//
// Description:
// 画菜单项列表:
* 1.圈定特定区域,也就是整个屏幕
* 2.逐个菜单绘制边框和背景色;
* 3.绘制菜单标题;
//
// Parameters:
* menutable - 给定的菜单哈希表
* selectedid - 被选中的菜单的索引值
* g - the Graphics object to be used for rendering the Canvas
// Return Values:
// Author:
// zhengyun@ultrapower 2006.02.13
//
**********************************************************/
public void drawMenu(Hashtable menutable, int selectedid, Graphics g)
{
System.out.println("Enter drawMenu:画菜单项列表!");
/*
* 圈定特定区域,也就是整个屏幕
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -