Wednesday, May 18, 2011

Implementing Tab Control in Blackberry Java Application

Currently I'm on the project in the Blackberry, and wondering how to implement Tab Control UI for the Java Application Development. So after research, and do some deep search and learning, and of course some modifications base on my need. I have this kind of pattern

First, I create TabButton, this component is extended from Field. You can use built-in BitmapField, LabelField, or any other Field. In my case, I need to make my own field for full customization.
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;

public class TabButton extends Field  {
    String _label;
    Bitmap _image;
    static int _height = 44; // according to image size
    static int _weight = 44;
    int _backgroundColor;
    int _focusColor;
    private int _statusBit;
   
    public TabButton(String label,
                     Bitmap image,
                     long style) {

        super(style);
        this._label = label;
        this._image = image;
        this._backgroundColor = 0x00cccccc;
        this._focusColor = 0x00ffcc00;
    }
   
   
    protected void paint(Graphics graphics) {
        // Draw background


        graphics.setBackgroundColor(_backgroundColor);
        graphics.clear();


        graphics.setColor(
           isFocus() ? _focusColor : _backgroundColor);

        graphics.fillRoundRect(
           0, 0, _image.getHeight(), _image.getWidth(),
           15, 15);

       
        if (_image != null) {
            graphics.drawBitmap(0, 0, _image.getWidth(),
                    _image.getHeight(), _image, 0, 0);
        }
    }


    protected void layout(int maxWidth, int maxHeight) {
        setExtent(_weight, _height);
    }


    public boolean isFocusable() {
        return true;
    }


    protected void drawFocus(Graphics graphics,
                             boolean on) {
        // Don't draw the
default focus
    }


    protected void onFocus(int direction) {
        super.onFocus(direction);
        invalidate();
    }


    protected void onUnfocus() {
        super.onUnfocus();
        invalidate();
    }




    protected boolean navigationClick(int status,
                                      int time) {

        fieldChangeNotify(1);
        return true;
    }
}
Now the TabControlScreen (the main screen of our application)

public class TabControlScreen extends MainScreen   
                        implements FieldChangeListener {
    //to manage the tab button
    HorizontalFieldManager _tabManager;

    TabButton _tab1;
    TabButton _tab2;
    TabButton _tab3;
    VerticalFieldManager _tabArea;


    LabelField _title1;
    LabelField _title2;
    LabelField _title3;


    VerticalFieldManager _tab1Mgr;
    VerticalFieldManager _tab2Mgr;
    VerticalFieldManager _tab3Mgr;

    private Bitmap bmp1;
    private Bitmap bmp2;
    private Bitmap bmp3;

    public TabControlScreen() {
        super();

        //set main manager background color
        getMainManager().setBackground(
                BackgroundFactory.createSolidBackground(0x00eeeeee));

        bmp1 = Bitmap.getBitmapResource("img/image1.png");
        bmp2 = Bitmap.getBitmapResource("img/image2.png");
        bmp3 = Bitmap.getBitmapResource("img/image3.png");

        _tab1 = new TabButton("Tab 1", bmp1, Field.FOCUSABLE  | Field.FIELD_HCENTER);
        _tab2 = new TabButton("Tab 2", bmp2, Field.FOCUSABLE  | Field.FIELD_HCENTER);
        _tab3 = new TabButton("Tab 3", bmp3, Field.FOCUSABLE  | Field.FIELD_HCENTER);

        _tab1.setChangeListener(this);
        _tab2.setChangeListener(this);
        _tab3.setChangeListener(this);
        
        _tabManager= new HorizontalFieldManager(USE_ALL_WIDTH);
        _tabManager.setBackground(BackgroundFactory
                .createSolidBackground(0x00cccccc));
        _tabManager.add(_tab1);
        _tabManager.add(_tab2);
        _tabManager.add(_tab3);

        add(_tabManager); //add to main manager

        add(new SeparatorField());

        _tab1Mgr = new VerticalFieldManager(Field.USE_ALL_WIDTH);
        _tab2Mgr = new VerticalFieldManager(Field.USE_ALL_WIDTH);
        _tab3Mgr = new VerticalFieldManager(Field.USE_ALL_WIDTH);

        _tabArea = displayTab1();
        add( _tabArea);
    }

    private VerticalFieldManager displayTab1(){
          if(_title1==null){
                _title1 = new LabelField("Content 1", Field.USE_ALL_WIDTH);
                _tab1Mgr.add( _title1);
          }
          return _tab1Mgr;
    }

    private VerticalFieldManager displayTab2(){
          if(_title2==null){
                _title2 = new LabelField("Content 2", Field.USE_ALL_WIDTH);
                _tab2Mgr.add( _title2);
          }
          return _tab2Mgr;
    }
    private VerticalFieldManager displayTab3(){
          if(_title3==null){
                _title3 = new LabelField("Content 3", Field.USE_ALL_WIDTH);
                _tab3Mgr.add( _title3);
          }
          return _tab3Mgr;
    }

    public void fieldChanged(Field field, int context) {
        if (_tabArea != null) {
            if (field == _tab1) {
                delete(_tabArea);
                _tabArea = displayTab1();
                add(_tabArea);
            } else if (field == _tab2) {
                delete(_tabArea);
                _tabArea = displayTab2();
                add(_tabArea);
            } else if (field == _tab3) {
                delete(_tabArea);
                _tabArea = displayTab3();
                add(_tabArea);
            }
        }
    }
}

Download samples here

5 comments:

Anonymous said...

Trying to implement you code now for days and I keep getting this error.

http://imageshack.us/photo/my-images/228/9670.png/

It will greatly be appreciated if i solve the problem. Thanks....

Anonymous said...

debugger stopped here
//---------------

graphics.fillRoundRect(0, 0, _image.getHeight(), _image.getWidth(), 15, 15);


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

Ali Irawan (Wen) said...

Hi there. May i know what version of BB OS that you are using for development ?

And what simulator?

I'll try to make a new Simple project so you can download it.

Download samples here

Note: I'm using BB SDK 5.0
and Simulator version 9300.

Anonymous said...

Thanks, I implemented the code on OS 5 with 9700. Form the Sample Code....

Jota said...

Hi Wen, I have a problem, when I'm scrolling the content, the tabBar get a kind of move like if it wanna get scroll...
What's the reason??
Than you..