程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> 一個定制計數器組件的編寫

一個定制計數器組件的編寫

編輯:J2ME
有時候你也許要讓你的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();
        }
    }
}    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved