📄 nov01_ericg.txt
字号:
addCommand( okCommand );
if( save ){
addCommand( cancelCommand );
}
setCommandListener( this );
}
public void commandAction( Command c,
Displayable d ){
Alert alert = null;
Date date = dateField.getDate();
if(
save && date != null && c == okCommand ){
if( editDate != null ){
int mode = dateField.getInputMode();
if( mode == DateField.DATE ){
editDate = combineDateTime(
date, editDate );
} else if(
mode == DateField.TIME ){
editDate = combineDateTime(
editDate, date );
} else {
editDate = date;
}
} else {
editDate = date;
}
Calendar cal = Calendar.getInstance();
cal.setTime( editDate );
alert = new Alert( "New date/time" );
alert.setString(
"The saved date/time is now " + cal );
alert.setTimeout( Alert.FOREVER );
}
if( alert != null ){
display.setCurrent( alert, testList );
} else {
display.setCurrent( testList );
}
}
private DateField dateField;
private boolean save;
}
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DEVELOPING CUSTOM COMPONENTS FOR THE MOBILE INFORMATION DEVICE
PROFILE
A question that novice Mobile Information Device Profile (MIDP)
programmers often ask is "How can I extend the MIDP user
interface classes to define my own custom components?" You might
want to extend the TextField class, for example, to support more
kinds of constraints or alternate forms of input. Or you might
want to define a completely new kind of user interface (UI)
component.
Unlike the Abstract Windowing Toolkit (AWT) in J2SE, however, the
MIDP user interface classes are not written with extensibility
in mind. In particular, the classes that make up the high-level
user interface API are not extensible. For example, the Item
class, which serves as the base class for all components that can
be placed on a Form, does not expose any public or protected
constructors. More importantly, none of the high-level UI classes
expose the low-level painting or input events required to write
custom components. The only class suitable for extension is the
Canvas class. This class is part of the low-level user interface
API which does expose the necessary information. Unfortunately,
you can't use components from both the low-level and high-level
APIs at the same time. In other words, you can't place a canvas
on a form, or place a form item on a canvas. While a canvas is
extensible, you pay for this flexibility with increased
responsibility. The canvas is responsible for painting the entire
screen and for responding to all input events, except for the
selection and triggering of Command objects. After you decide to
write your own component class, there's no going back -- it's
really an all-or-none proposition.
Be sure to explore the alternatives before you decide to write
your own component class. Do you truly need a new component, or
can you get by with the predefined MIDP classes? The high-level
API defines a set of abstract user interface components,
components that are adapted by a device manufacturer to suit the
display and input characteristics of the device. Any components
you write do not share this adaptability, so careful design
and testing are required for them to work well across all
devices. The components also increase the size of your application.
There are many possible implementations for custom components,
but, in general, you need at least two classes: one class to
define a "container" or "manager" for the components, and another
to define the base class for those components. Here is an
implementation of a possible base class:
import javax.microedition.lcdui.*;
// A root class for Canvas-based components.
// Because Area extends Canvas, you can actually
// use a component directly as a Canvas, although
// it's recommended you place it on Manager.
public abstract class Area extends Canvas {
protected int x;
protected int y;
protected int w;
protected int h;
protected Font font;
protected Manager parent;
protected int backcolor = -1;
protected int forecolor = -1;
protected Area( int x, int y, int w, int h ){
this( x, y, w, h, null );
}
protected Area( int x, int y,
int w, int h, Font f ){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.font = font;
}
// Erase the background using backcolor
protected void eraseBackground( Graphics g ){
g.setColor( getBackColor() );
if( parent == null ){
g.fillRect( 0, 0, getCanvasWidth(),
getCanvasHeight() );
} else {
g.fillRect( 0, 0, w, h );
}
}
public final int getBackColor(){
if( backcolor == -1 ){
if( parent != null ){
return parent.getBackColor();
}
backcolor = 0xFFFFFF;
}
return backcolor;
}
protected final int getCanvasHeight(){
return super.getHeight();
}
protected final int getCanvasWidth(){
return super.getWidth();
}
public final int getHeight(){ return h; }
public final int getWidth(){ return w; }
public final int getX(){ return x; }
public final int getY(){ return y; }
public final Font getFont(){
if( font == null ){
if( parent != null ){
return parent.getFont();
}
font = Font.getDefaultFont();
}
return font;
}
public final int getForeColor(){
if( forecolor == -1 ){
if( parent != null ){
return parent.getForeColor();
}
forecolor = 0;
}
return forecolor;
}
public Manager getParent(){ return parent; }
public void keyPressed( int keyCode ){
}
public void keyReleased( int keyCode ){
}
public void keyRepeated( int keyCode ){
}
protected void moveFocus( boolean forward ){
if( parent != null ){
parent.moveFocus( forward );
}
}
// If the area is acting like a Canvas, call
// the real paint routine
protected void paint( Graphics g ){
eraseBackground( g );
g.setColor( getForeColor() );
g.setFont( getFont() );
paintArea( g, true );
}
// The manager calls this paint routine on each of
// its children
public final void paint( Graphics g,
boolean hasFocus ){
int cx = g.getClipX();
int cy = g.getClipY();
int ch = g.getClipHeight();
int cw = g.getClipWidth();
Font f = g.getFont();
int col = g.getColor();
eraseBackground( g );
g.setClip( x, y, w, h );
g.setFont( getFont() );
g.setColor( getForeColor() );
paintArea( g, hasFocus );
g.setClip( cx, cy, cw, ch );
g.setFont( f );
g.setColor( col );
}
// Subclass implements to do actual painting
protected abstract void paintArea(
Graphics g, boolean hasFocus );
// Repaint the area of the given child
public void repaintArea( Area child, boolean now ){
if( parent != null ){
parent.repaintArea( child, now );
} else {
repaint( child.getX(),
child.getY(),
child.getWidth(),
child.getHeight() );
if( now ){
serviceRepaints();
}
}
}
public void setBackColor( int col ){
backcolor = col;
}
public void setForeColor( int col ){
forecolor = col;
}
protected void setParent( Manager parent ){
this.parent = parent;
}
}
Although the root class is fairly simple, it does handle the
basics. It stores the position, dimensions, colors, and fonts of
the component. The Area class is meant to be subclassed. Here's
an example of a simple push button component that extends Area:
import javax.microedition.lcdui.*;
public class PushButton extends Area {
// Define the listener interface
public interface Listener {
void buttonPressed( PushButton which );
}
private String label;
private boolean selected;
private Listener listener;
public PushButton( String label,
int x, int y ){
this( label, x, y, 0, 0, null );
}
public PushButton( String label,
int x, int y,
Font f ){
this( label, x, y, 0, 0, f );
}
public PushButton( String label,
int x, int y,
int w, int h ){
this( label, x, y, w, h, null );
}
public PushButton( 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -