e int marginy = 4;
public Button(String label, int x, int y)
{
this(label, x, y, 0, 0, null);
}
public Button(String label, int x, int y, Font f)
{
this(label, x, y, 0, 0, f);
}
public Button(String label, int x, int y, int w, int h)
{
this(label, x, y, w, h, null);
}
public Button(String label, int x, int y, int w, int h, Font f)
{
super(x, y, w, h, f);
if (label == null)
label = "";
int tw = calcMinWidth(label, getFont());
int th = calcMinHeight(label, getFont());
if (tw > w)
this.w = tw;
if (th > h)
this.h = th;
this.label = label;
}
public void setModifiable(boolean flag)
{
this.modifiable = flag;
}
public static int calcMinWidth(String text, Font f)
{
return f.stringWidth(text) + 8;
}
public static int calcMinHeight(String text, Font f)
{
return f.getHeight() + 8;
}
public String getLabel()
{
return label;
}
public void setMargin(int x,int y)
{
this.marginx = x;
this.marginy = y;
}
protected void paintArea(Graphics g, boolean hasFocus)
{
g.setStrokeStyle(Graphics.SOLID);
g.drawRect(x, y, w - 1, h - 1);
if (selected)
{
g.setColor(getForeColor());
g.fillRect(x, y, w - 1, h - 1);
g.setColor(getBackColor());
} else if (hasFocus)
{
g.setStrokeStyle(Graphics.DOTTED);
g.drawRect(x + 3, y + 3, w - 7, h - 7);
g.setStrokeStyle(Graphics.SOLID);
}
g.drawString(label, x + marginx, y + marginy, Graphics.TOP | Graphics.LEFT);
}
public void keyPressed(int keyCode)
{
int num = keyCode - 48;
if (num >= 0)
{
if (modifiable)
{
this.label = num + "";
}
repaintArea(this, true);
moveFocus(true);
return;
}
int action = getGameAction(keyCode);
switch (action)
{
case UP:
case LEFT:
moveFocus(false);
break;
case DOWN:
case RIGHT:
moveFocus(true);
break;
case FIRE:
if (listener != null)
{
listener.buttonPressed(this);
}
break;
}
}
public void setLabel(String s)
{
this.label = s;
}
public void keyReleased(int keyCode)
{
}
public void setListener(ButtonListener listener)
{
this.listener = listener;
}
}
我们应该重点关注一下paintArea()方法,以及keyPressed()方法。如果我们注册了一个ButtonListener给Button的话,那么当按键事件发生的时候,buttonPressed()方法就会触发并且把这个按键传递给他,这样我们应用程序就可以根据用户的事件来处理相关的逻辑了。

我们推荐制作一个容器类来管理我们的Button,他会知道什么时候应该移动焦点,什么时候该去绘制它的“孩子”们。我们把这个类叫Manager。
package com.j2medev.numbergame;
import java.util.*;
import javax.microedition.lcdui.*;
// A subclass of Area that can act as
// the parent for other components.
public class Manager extends Area
{
protected Vector children = new Vector();
protected Area focus = null;
public Manager()
{
super(0, 0, 0, 0, null);
w = getCanvasWidth();
h = getCanvasHeight();
}
public void add(Area child)
{
if (!children.contains(child))
{
children.addElement(child);
child.setParent(this);
repaintArea(child, false);
}
}
protected Area getFocus()
{
if (focus == null && children.size() > 0)
{
focus = (Area) children.elementAt(0);
}
return focus;
}
public void keyPressed(int keyCode)
{
Area focus = getFocus();
if (focus != null && focus != this)
{
focus.keyPressed(keyCode);
}
}
public void keyReleased(int keyCode)
{
}
public void keyRepeated(int keyCode)
{
}
// Called to move the focus to the next
// or previous component
protected void moveFocus(boolean forward)
{
Area oldFocus = getFocus();
if (oldFocus != null)
{
int i = children.indexOf(oldFocus);
int last = children.size() - 2;
if (forward)
{
if (++i > last)
i = 0;
} else
{
if (--i < 0)
i = last;
}
focus = (Area) children.elementAt(i);
repaintArea(oldFocus, false);
repaintArea(focus, true);
}
}
public void remove(Area child)
{
if (children.removeElement(child))
{
child.setParent(null);
repaintArea(child, false);
}
}
protected void paint(Graphics g)
{
if (focus == null)
getFocus();
eraseBackground(g);
g.setColor(getForeColor());
int n = children.size();
for (int i = n - 1; i >= 0; --i)
{
try
{
Area area = (Area) children.elementAt(i);
area.paint(g, (focus == area));
} catch (Exception e)
{
e.printStackTrace();
}
}
}
protected void paintArea(Graphics g, boolean hasFocus)
{
}
}
在猜数字游戏中,我们还需要一个用于显示用户输入和系统返回纪录的组件,他同样继承与Area,但是他不需要获得焦点。只是显示结果。
package com.j2medev.numbergame;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
public class Mark extends Area
{
private int px;
private int py;
private int count = 0;
private int[][] ab = new int[10][2];
private int[][] input = new int[10][4];
private boolean first = true;
private boolean open = false;
public Mark(int x, int y, int w, int h)
{
super(x, y, w, h);
px = x;
py = y;
}
public Mark(int x, int y, int w, int h, Font f)
{
super(x, y, w, h, f);
px = x;
py = y;
}
public int getCount()
{
return count;
}
public