📄 command.java
字号:
package com.podome.ui;
import java.util.Vector;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import com.podome.log.Logger;
import com.podome.style.IStyle;
import com.podome.style.Style;
import com.podome.tool.Config;
import com.podome.tool.Key;
/**
* 只有第0级菜单的X,Y坐标有效,其他的坐标都必须以0级为参照
* 用偏移量xOffset和yOffset来控制子菜单的起始位置,左菜单
* 或右菜单都是一个0级菜单
* @author Leadj
* 菜单切换机制说明
* 弹出/正常切换(需要重新计算子菜单位置和视图位置)
* 左手/右手切换(需要重新设置视图位置和重画子菜单)
*/
public class Command implements Paint,EventDispatch,IStyle {
/**
* 第一级菜单的展现方式 true-扩展 false-收缩
*/
public boolean isExpend = false; //
/**
* 是否是左边的菜单项
*/
boolean isLeft = true;
/**
* 系统级命令,不对当前选中的选项操作
*/
boolean isLevelUser = false;
/**
* 是否是弹出菜单
*/
boolean isPopCommand = false;
int level = 0; //菜单的级别
Style style = null;
String commandstr = null; //命令字符
EventDispatch cmdDispatcher; //向注册者通知菜单命名被选取事件
Command parent; //父节点
Vector child; //子节点
Command pre; //前一个兄弟节点
Command next; //下一个兄弟节点
Command currentChild; //当前子菜单
boolean enable = true; //是否可以获取焦点
boolean visble = true; //是否显示在屏幕上
boolean isFocus = false; //是否获得了焦点
int childWidth; //子菜单最大宽度
int childHeight; //子菜单的总高度
int width; //字符宽度(包括左右填充)
int height; //字符高度(包括上下填充 )
int[][] bonds = new int[2][2]; //实际占用空间
int xoffset; //子菜单在X轴方向的偏移量
int yoffset; //子菜单在Y轴方向的偏移量
int vXpos; //子菜单视图的起始X位置
int vYpos; //子菜单视图的起始Y位置
int vWidth; //子菜单可以显示的宽度(视窗宽度)
int vHeight; //子菜单可以显示的最大高度(视窗高度)
boolean isOpen = false;
protected Image offImage = null; //把文字画成图片,然后再画到画布上
//protected int[] offImageRBG;
protected boolean isOffImageRepaint = true;
//重新计算子菜单的相对位置和相对坐标
boolean isChildPositionReset = true;
//重新设设置子菜单的视窗
boolean isChildViewerReset = true;
public Command(String label){
this.commandstr = label;
this.isLevelUser = true;
this.calculateSelfFactWidth();
}
public Command(String label, boolean userCmd ){
this(label);
this.isLevelUser = userCmd;
}
public void keyPressed(int keyCode){
if(keyCode == Key.KEY_OK){
this.keyOKImpl();
}
else if(keyCode == Key.KEY_LEFT && this.isLeft ){
this.keyLeftImpl();
}
else if(keyCode == Key.KEY_LEFT && !this.isLeft ){
this.keyLeftForRightImpl();
}
else if(keyCode == Key.KEY_RIGHT && this.isLeft ){
this.keyRightImpl();
}
else if(keyCode == Key.KEY_RIGHT && !this.isLeft ){
this.keyRightForRightImpl();
}
else if(keyCode == Key.KEY_UP){
this.keyUpImpl();
}
else if(keyCode == Key.KEY_DOWN){
this.keyDownImpl();
}
}
void keyOKImpl(){
if(!this.hasChild() ){
this.execute();
}
else if(this.currentChild != null &&
!this.currentChild.hasChild()){
this.execute();
}
else if(this.currentChild != null &&
this.currentChild.isOpened()){
this.currentChild.keyPressed(Key.KEY_OK);
}
else{
currentChild.open();
}
}
void keyLeftImpl(){
if(this.currentChild != null &&
!this.currentChild.isOpened() &&
this.level > 0 ){
close();
}
else if(this.currentChild != null &&
this.currentChild.hasChild() &&
this.currentChild.isOpened()){
this.currentChild.keyPressed(Key.KEY_LEFT);
}
}
void keyLeftForRightImpl(){
if(this.currentChild != null &&
this.currentChild.hasChild() &&
!this.currentChild.isOpened() ){
currentChild.open();
}
else if(this.currentChild != null &&
this.currentChild.hasChild() &&
this.currentChild.isOpened()){
this.currentChild.keyPressed(Key.KEY_LEFT);
}
}
void keyRightImpl(){
if(this.currentChild != null &&
this.currentChild.hasChild() &&
!this.currentChild.isOpened() ){
currentChild.open();
}
else if(this.currentChild != null &&
this.currentChild.hasChild() &&
this.currentChild.isOpened()){
this.currentChild.keyPressed(Key.KEY_RIGHT);
}
}
void keyRightForRightImpl(){
if(this.currentChild != null &&
!this.currentChild.isOpened() &&
this.level > 0 ){
close();
}
else if(this.currentChild != null &&
this.currentChild.hasChild() &&
this.currentChild.isOpened()){
this.currentChild.keyPressed(Key.KEY_RIGHT);
}
}
void keyUpImpl(){
if(this.currentChild != null &&
!this.currentChild.isOpened() ){
this.focusPre();
}
else if(this.currentChild != null &&
this.currentChild.hasChild() &&
this.currentChild.isOpened()){
this.currentChild.keyPressed(Key.KEY_UP);
}
}
void keyDownImpl(){
if(this.currentChild != null &&
!this.currentChild.isOpened() ){
this.focusNext();
}
else if(this.currentChild != null &&
this.currentChild.hasChild() &&
this.currentChild.isOpened()){
this.currentChild.keyPressed(Key.KEY_DOWN);
}
}
/**
* 设置菜单的监听器对象
* @param lstr
*/
void setCommandDispatcher(EventDispatch dispatcher ){
this.cmdDispatcher = dispatcher;
}
EventDispatch getCommandDispatcher(){
if( this.cmdDispatcher != null){
return this.cmdDispatcher;
}
else if(this.parent != null){
return parent.getCommandDispatcher();
}
else{
return null;
}
}
/**
* 执行了OK键
*/
void execute(){
EventDispatch dis = getCommandDispatcher();
if( dis != null ){
if(currentChild != null){
dis.notifyCommand(currentChild);
}
else{
dis.notifyCommand(this);
}
}
}
public void paint(Graphics g) {
Logger.info("Painting " + this.commandstr);
//弹出式菜单跳过系统命令项
if(this.isPopCommand &&
!this.isLevelUser() &&
this.level > 0 ){
return;
}
this.setChildPosition();
this.setChildViewer();
Style s = this.getStyle();
int x = this.getX();
int y = this.getY();
int w = this.getWidth();
int h = this.getHeight();
if(this.level == 0 ){ //Level = 0 不画自身,直接画子节点,自身标签文字由Menu对象来控制
this.paintChild(g);
return;
}
else if(this.isOffImageRepaint ){
isOffImageRepaint = false;
if(this.offImage == null){
this.offImage = Image.createImage(w,h);
}
Graphics offGraphics = this.offImage.getGraphics();
offGraphics.setColor(s.bColorNormal);
offGraphics.fillRect(0, 0, w, h);
//设置背景颜色
offGraphics.setColor(this.hasFocus()?s.bColorFocus:s.bColorNormal);
if(!this.enable )
offGraphics.setColor(s.bColorEnable);
offGraphics.fillRoundRect(1, 1, w-3, h-2, s.rountWidth, s.roundHeight);
//画背景图片
if(this.hasFocus()&& !this.isPopCommand ){
if(s.bImageMidFocus != null)
offGraphics.drawImage(s.bImageMidFocus, w/2+2, h/2+2, Graphics.VCENTER | Graphics.HCENTER);
if(s.bImageLeftTopFocus != null)
offGraphics.drawImage(s.bImageLeftTopFocus, 0, 0, Graphics.TOP | Graphics.LEFT);
if(s.bImageRightTopFocus != null)
offGraphics.drawImage(s.bImageRightTopFocus,w, 0,Graphics.TOP|Graphics.RIGHT);
if(s.bImageLeftBottomFocus != null)
offGraphics.drawImage(s.bImageLeftBottomFocus, 0, h, Graphics.BOTTOM | Graphics.LEFT);
if(s.bImageRightBottomFocus != null)
offGraphics.drawImage(s.bImageRightBottomFocus,w, h,Graphics.BOTTOM|Graphics.RIGHT);
}
else if( !this.isPopCommand ){
if(s.bImageMid != null)
offGraphics.drawImage(s.bImageMid, w/2+2, h/2+2, Graphics.VCENTER | Graphics.HCENTER);
if(s.bImageLeftTop != null)
offGraphics.drawImage(s.bImageLeftTop, 0, 0, Graphics.TOP | Graphics.LEFT);
if(s.bImageRightTop != null)
offGraphics.drawImage(s.bImageRightTop,w, 0,Graphics.TOP|Graphics.RIGHT);
if(s.bImageLeftBottom != null)
offGraphics.drawImage(s.bImageLeftBottom, 0, h, Graphics.BOTTOM | Graphics.LEFT);
if(s.bImageRightBottom != null)
offGraphics.drawImage(s.bImageRightBottom,w, h,Graphics.BOTTOM|Graphics.RIGHT);
}
//设置文字颜色
offGraphics.setColor(this.hasFocus()?s.fColorFocus:s.fColorNormal);
if(!this.enable )
offGraphics.setColor(s.fColorEnable);
offGraphics.setFont(s.dfont);
//计算对齐方式
int yText = s.paddingTop + (h-s.paddingTop-s.paddingBottom-s.dfont.getHeight())/2;
if( this.isLeft ){
offGraphics.drawString(this.commandstr, s.paddingLeft,yText , Graphics.LEFT | Graphics.TOP);
}
else{
offGraphics.drawString(this.commandstr, w-s.paddingRight,yText, Graphics.RIGHT | Graphics.TOP);
}
}
//设置可见区域
if( y + h > Stage.getCH() - Menu.getHeight()){
h = Stage.getCH() - Menu.getHeight() - y;
}
w = Stage.getCW();
g.setClip(0, 0,w,500);
g.drawImage(offImage, x, y, Graphics.TOP | Graphics.LEFT);
//画子菜单的指示箭头
this.paintChildArrow(g);
this.paintChild(g);
}
/**
* 画子菜单的指示箭头
* @param g
*/
void paintChildArrow(Graphics g){
if( isLeft ){
paintLeftChildArrow(g);
}
else{
paintRightChildArrow(g);
}
}
private void paintLeftChildArrow(Graphics g){
if(this.level == 0 ||
this.child == null ||
this.child.size() == 0 ) {
return;
}
Style s = this.getStyle();
int xCenter, yCenter;
xCenter = this.getX() + this.getWidth() - Config.MENU_ARROW_WIDTH;
yCenter = this.getY() + this.getHeight() / 2;
int iBgColor = s.fColorNormal;
if( this.isOpened() ){
iBgColor = s.fColorFocus;
}
g.setColor(iBgColor);
g.fillTriangle(xCenter, yCenter - Config.MENU_ARROW_WIDTH/2, xCenter, yCenter + Config.MENU_ARROW_WIDTH/2, xCenter + Config.MENU_ARROW_WIDTH/2,
yCenter);
}
private void paintRightChildArrow(Graphics g){
if(this.level == 0 ||
this.child == null ||
this.child.size() == 0 ) {
return;
}
Style s = this.getStyle();
int xCenter, yCenter;
xCenter = this.getX() + Config.MENU_ARROW_WIDTH;
yCenter = this.getY() + this.getHeight() / 2;
int iBgColor = s.fColorNormal;
if( this.isOpened() ){
iBgColor = s.fColorFocus;
}
g.setColor(iBgColor);
g.fillTriangle(xCenter, yCenter - Config.MENU_ARROW_WIDTH/2, xCenter, yCenter + Config.MENU_ARROW_WIDTH/2, xCenter - Config.MENU_ARROW_WIDTH/2,
yCenter);
}
/**
* 画全部的子菜单
*/
void paintChild(Graphics g){
//画子菜单,展开状态子的菜单最后画
if(this.child == null ||
this.child.size() == 0 ||
!isOpened() ){
return;
}
Command cItem = null;
Command oItem = null;
for(int i=0; i< this.child.size(); i++){
cItem = (Command)this.child.elementAt(i);
if( !cItem.isOpened()){
cItem.paint(g);
}
else{
oItem = cItem;
}
}
if(oItem != null){
oItem.paint(g);
}
}
/**
* 获取控件在屏幕上的X坐标
* @return int
*/
public int getX(){
if( this.parent != null ){
return this.parent.vXpos +
this.parent.xoffset +
this.bonds[0][0];
}
else{
return this.bonds[0][0];
}
}
/**
* 获取控件在屏幕上的Y坐标。
* @return int
*/
public int getY(){
if( this.parent != null ){
return this.parent.vYpos +
this.parent.yoffset +
this.bonds[0][1];
}
else{
return this.bonds[0][1];
}
}
/**
* 获取控件在屏幕上实际占用宽度
* @return int
*/
public int getWidth(){
return this.bonds[1][0] - this.bonds[0][0];
}
/**
* 获取控件在屏幕上实际占用高度
* @return
*/
public int getHeight(){
return this.bonds[1][1] - this.bonds[0][1];
}
void setLevel(int level){
this.level = level;
}
/**
* 设置菜单项的宽度,如果w小于菜单标签的宽度,则无效。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -