资源大全 | 神秘文化 | 在线翻译 | QQ专区 | 视频教程 | 彩信频道 | 搜索引擎 | BT下载 |  | 网站地图
设为首页
加入收藏
联系站长
您现在的位置: 一百网络 >> JSP编程 >> J2ME >> 文档正文
最近更新
普通文档 移动开发:J2ME中定点库
普通文档 MIDlet生命周期的深入理
普通文档 移动开发:RMS概念解析与
普通文档 在基于MIDP的应用程序上
普通文档 教您如何在MIDP开发中实
普通文档 开发经验谈:贪吃蛇游戏
普通文档 J2ME学习系列之如何将J2
普通文档 教您如何解决J2ME开发中
普通文档 用实例讲解一个定制计数
普通文档 熟练使用J2ME在实际开发
推荐文章
  • 此栏目下没有推荐文档
  • 用实例讲解一个定制计数器组件的编写

    文章作者:佚名 录入时间:2006-7-5 来源:不详
    网站声明:本站的文章除部分特别声明禁止转载的专稿外,可以自由转载.但请务必注明出处和原始作者,文章版权归本网站与文章作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。


    有时候你也许要让你的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();
    
            }
    
        }
    
    }

  • 上一篇文档:

  • 下一篇文档:
  •     查找更多“用实例讲解一个定制计数器组件的编写”的内容  
    相关连接
  • 移动开发:J2ME中定点库MathFP使用入门

  • MIDlet生命周期的深入理解及游戏死机问题

  • 移动开发:RMS概念解析与使用指南

  • 在基于MIDP的应用程序上使用JDBC

  • 教您如何在MIDP开发中实现图片放缩