分享
 
 
 

一个定制计数器组件的编写

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

有时候你也许要让你的MIDP应用程序显示一个计数器,比如某些操作从开始操作到现在进行了多少秒,这还算是一个简单的可以自动更新显示计数的定制组件,一些简单的代码便可使你让这些代码和Canvas完美整合,定制的绘制屏幕程序一般都继承自Cnavas, 或者用Form在MIDP2.0里的新组件---------CustomItem 。

制作一个双重目的的组件的关键是把它的描绘屏幕部分和控制部分分开,理由是没有一个概念能够让组件和Canvas作为一个整体起作用;应用程序必须本身能够绘制和控制整个Canvas,一个定制的Item,从某一方面说,是一个真实的组件,系统分派绘制屏幕的任务给这个组件,而对其他的大部分操作进行控制,你可以定义一个回调的接口让你的组件使用它们,并把这些控制任务交给合适的代码处理。

下面是有一个简单计数器例子的核心代码,CounterArea class:

import Javax.microedition.lcdui.*;

// The counter class, which can be used on a canvas

// or wrapped within a custom item.

public class CounterArea {

public static final int DEFAULT_RATE = 500;

public static final int MIN_RATE = 100;

// The callback interface by which we notify

// the counter owner of certain events.

public interface Callback {

void invalidateCounter( CounterArea counter );

void repaintCounter( CounterArea counter );

void resizeCounter( CounterArea counter );

}

public CounterArea(){

}

public CounterArea( int width, int height ){

_width = width;

_height = height;

}

public int getBackColor(){

return _backColor;

}

public Callback getCallback(){

return _callback;

}

public Font getFont(){

return _font;

}

public Font getFontForDrawing(){

return _font != null ? _font :

Font.getDefaultFont();

}

public int getHeight(){

if( _height < 0 ){

_height = getMinHeight();

}

return _height;

}

public int getMinHeight(){

return getFontForDrawing().getHeight();

}

public int getMinWidth(){

Font f = getFontForDrawing();

return f.stringWidth( Integer.toString( _value ) );

}

public int getRate(){

return _rate;

}

public int getTextColor(){

return _textColor;

}

public int getValue(){

return _value;

}

public int getWidth(){

if( _width < 0 ){

_width = getMinWidth();

}

return _width;

}

private void invalidate(){

if( _callback != null ){

_callback.invalidateCounter( this );

}

}

public boolean isCounting(){

return _timer != null;

}

public void paint( Graphics g ){

String s = Integer.toString( _value );

Font f = getFontForDrawing();

int w = f.stringWidth( s );

int h = f.getHeight();

int aw = getWidth();

int ah = getHeight();

g.setColor( _backColor );

g.fillRect( _left, _top, aw, ah );

g.setColor( _textColor );

g.drawString( s, _left + aw - w,

_top + ( ah - h ) / 2,

g.TOP g.LEFT );

if( w > aw h > ah ){

resize();

}

}

private void repaint(){

if( _callback != null ){

_callback.repaintCounter( this );

}

}

private void resize(){

if( _callback != null ){

_callback.resizeCounter( this );

}

}

private synchronized boolean increment( Runnable source ){

if( source != _timer ) return false;

++_value;

repaint();

return true;

}

public void setBackColor( int color ){

_backColor = color;

invalidate();

}

public void setCallback( Callback callback ){

_callback = callback;

}

public void setLeft( int left ){

_left = left;

}

public void setFont( Font f ){

_font = f;

invalidate();

}

public void setHeight( int h ){

_height = h;

}

public void setRate( int rate ){

_rate = ( rate < MIN_RATE ? MIN_RATE : rate );

}

public void setTextColor( int color ){

_textColor = color;

invalidate();

}

public void setTop( int top ){

_top = top;

}

public synchronized void setValue( int value ){

_value = value;

}

public void setWidth( int w ){

_width = w;

}

public synchronized void start(){

_timer = new CounterTimer();

new Thread( _timer ).start();

}

public synchronized void stop(){

_timer = null;

}

private int _backColor = 0x00FFFFFF;

private Callback _callback;

private Font _font;

private int _height = -1;

private int _index;

private int _left;

private int _rate = DEFAULT_RATE;

private int _textColor = 0x00000000;

private Runnable _timer;

private int _top;

private int _width = -1;

private int _value;

//-------------------------------------------------

// A very simple timer that sleeps and wakes

// up at regular intervals.

private class CounterTimer implements Runnable {

public void run(){

Thread t = Thread.currentThread();

while( true ){

try {

t.sleep( _rate );

}

catch( InterruptedException e ){

}

if( !increment( this ) ) break;

}

}

}

}

这个计数器在中垂线和横垂线的焦点绘制计数器数值,而且可以在绘制区域尺寸太小的情况下,自动更改合适的尺寸。它同时定义了一个公有的嵌套接口,CounterArea.Callback,将组件的无效性,重绘,自适应大小传递给适当的控制段,一个私有的内隐类,CounterTimer,负责在后台更新计数器的数值。

CounterArea类可以直接在一个Canvas中使用,但是你也可以把它和一个定制的Item封装在一起,外覆类,CounterItem,如下所示:

import javax.microedition.lcdui.*;

// A custom component for MIDP 2.0 that wraps

// a CounterArea instance.

public class CounterItem extends CustomItem

implements CounterArea.Callback {

public CounterItem(){

super( null );

_area = new CounterArea();

_area.setCallback( this );

}

public Font getFont(){

return _area.getFont();

}

public int getMinContentHeight(){

return _area.getMinHeight();

}

public int getMinContentWidth(){

return _area.getMinWidth();

}

public int getPrefContentHeight( int width ){

return getMinContentHeight();

}

public int getPrefContentWidth( int height ){

return getMinContentWidth();

}

public int getValue(){

return _area.getValue();

}

protected void hideNotify(){

_area.stop();

}

public void invalidateCounter( CounterArea counter )

if( counter == _area ){

invalidate();

}

}

protected void paint( Graphics g, int width, int height ){

_area.paint( g );

}

public void repaintCounter( CounterArea counter ){

if( counter == _area ){

repaint();

}

}

public void resizeCounter( CounterArea counter ){

if( counter == _area ){

invalidate();

}

}

protected void sizeChanged( int w, int h ){

_area.setWidth( w );

_area.setHeight( h );

}

public void setFont( Font f ){

_area.setFont( f );

}

public void setValue( int value ){

_area.setValue( value );

}

protected void showNotify(){

_area.start();

}

public boolean traverse( int dir, int vw, int vh,

int[] vrect ){

return false;

}

private CounterArea _area;

}

外覆类只是起到接收回递函数给控制段,自动开始和关闭计数器的作用,当然,任何时候如果这个Item显示或者隐藏,你都希望能够改变它的行为。

最后, 是一个简单的测试 MIDlet去验证这个计数器的作用:

import java.io.*;

import java.util.*;

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

// A simple MIDlet to test the custom counter

// component.

public class CounterItemTest extends MIDlet

implements CommandListener {

private Display display;

public static final Command exitCommand =

new Command( "Exit",

Command.EXIT, 1 );

public CounterItemTest(){

}

public void commandAction( Command c,

Displayable d ){

if( c == exitCommand ){

exitMIDlet();

}

}

protected void destroyApp( boolean unconditional )

throws MIDletStateChangeException {

exitMIDlet();

}

public void exitMIDlet(){

notifyDestroyed();

}

public Display getDisplay(){ return display; }

protected void initMIDlet(){

Form f = new Form( "CounterItem Test" );

f.addCommand( exitCommand );

f.setCommandListener( this );

CounterItem counter = new CounterItem();

counter.setLayout( Item.LAYOUT_CENTER

Item.LAYOUT_NEWLINE_BEFORE

Item.LAYOUT_NEWLINE_AFTER );

f.append( counter );

getDisplay().setCurrent( f );

}

protected void pauseApp(){

}

protected void startApp()

throws MIDletStateChangeException {

if( display == null ){

display = Display.getDisplay( this );

initMIDlet();

}

}

}

原文作者: Eric Giguere

原文地址:http://developers.sun.com/techtopics/mobility/midp/ttips/counteritem/

(出处:http://www.knowsky.com)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有