Wednesday, May 25, 2011

Barcode Scanner for BlackBerry SDK 5.0

Since in BlackBerry SDK 5.0 have no built-in barcode lib API as in BlackBerry SDK 6.0. So I decide to create my own package to provide similar functionality to scan barcode (I'm using QR Code)

I'm using BlackBerry Java Plugin 1.3 Eclipse.
And Simulator of 9300.

You can download the package classes here.

Example of Usage:

        BarcodeScanner scanner;
        BarcodeDecoder decoder;
        BarcodeDecoderListener listener;
        Field viewFinder;

            Hashtable hints = new Hashtable(1);
            Vector formats = new Vector(1);
            formats.addElement(BarcodeFormat.QR_CODE);
            hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);

            decoder = new BarcodeDecoder(hints);

            listener = new BarcodeDecoderListener() {

                public void barcodeFailDecoded(Exception ex) {
                  
                }

                public void barcodeDecoded(String rawText) {

                    synchronized(Application.getEventLock()){
                       barcodeResult.setText(rawText);

                      
                    }
                }

                public void barcodeDecodeProcessFinish() {
                     synchronized(Application.getEventLock()){

                         UiApplication.getUiApplication.
                            popScreen(ViewFinderScreen.this);

                     }
                }
            };
            try {
                scanner = new BarcodeScanner(decoder, listener);
                viewFinder = scanner.getViewFinder();

                scanner.getVideoControl.setDisplayFullScreen(true);
                add(viewFinder);
              
                scanner.startScan();
            } catch (Exception e) {
                Status.show(e.getMessage());
                e.printStackTrace();
            }       

To stop scan

            try {
          scanner.stopScan();
     } catch (MediaException e) {
         e.printStackTrace();
     }


Dowload sample usages here
QR Code Sample

Friday, May 20, 2011

Building Zxing to Use in Blackberry Java Development

Zxing is a open source tools to read/writer various format of Barcode. Currently I'm using it for my blackberry java application.

This tutorials is about how to build zxing core using Ant.
  1. Dowloand zxing from http://code.google.com/p/zxing/
  2. Download Apache Ant http://ant.apache.org/
  3. Extract the Apache ant to a folder e.g. C:\apache-ant-1.8.2
  4. Extract the zxing (I'm using version 1.6) to a folder e.g C:\zxing-1.6
  5. Type this to build zxing core.jar

    C:\zxing-1.6> ant -f core/build.xml

    Make sure ant.bat is accessible from System Path, or you can type full directory such as
    C:\apache-ant-1.8.2\bin\ant instead of ant.
  6. Build zxing j2me.jar
    Make sure you have set the WTK-home in the build.properties
    (check C:\zxing-1.6\build.properties)

    WTK-home=D:\\Java_ME_platform_SDK_3.0

    (this is the location of Java ME SDK 3.0 installation folder)

    Set the location of Proguard.jar

    proguard-jar=D:\\proguard4.6\\proguard4.6\\lib\\proguard.jar



    Note: notice that in Java ME SDK 3.0 untuk JSR135 Mobile Media API (MMAPI) using JSR135_1.1 version, and there's no JSR135_1.2 version.

    So, edit build.xml for javame build (check C:\zxing-1.6\javame\build.xml)
    REPLACE jsr135_1.2.jar with jsr135_1.1.jar

    Then type in the console: 

    C:\zxing-1.6> ant -f javame/build.xml -lib D:\Java_ME_platform_SDK_3.0\lib;D:\proguard4.6\lib
  7. Generate zxing for rim client (rim build)

    zxing-1.6 using preverify1.1.exe, but Java ME SDK 3.0 only have preverify.exe

    edit rim/build.xml
    Find text preverify1.1, and replace with preverify

    Type in the console:

    C:\zxing-1.6> ant -f rim/build.xml


    Note: -lib in the ant command is used for specifying the classpath. For multiple classpath, we can use semicolon (;)
    See http://ant.apache.org/manual/running.html for more details

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

Wednesday, May 11, 2011

Global Filter Bean in JSF

I come to idea to save user search criteria in a bean. The bean will be in Session scope, because each user will have different search criteria to use. When user, redirected to another page, the search value still exist while in session scope. If the session expired or invalidated, then the value is gone.

I'm using JSF 2.0, Mojarra 2.0.4. With ajax features built-in. So in the bean I will save the search criteria per view. Each view will have it's own map (HashMap)

FilterBean

package com.mycompany;

import java.io.Serializable;
import java.util.HashMap;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.mycompany.DTO;

@Component("filterBean")
@Scope("session")
public class FilterBean implements Serializable {

    HashMap<String, DTO> map = new HashMap<String, DTO>();

    public DTO getData() {
        String currentViewId = getFacesContext().getViewRoot().getViewId();
        if (!map.containsKey(currentViewId)) {
            // create a new key
            map.put(currentViewId, new DTO());
        }
        return this.map.get(currentViewId);
    }

}
DTO is Data Transfer Object which there is HashMap<String, Object> inside

public class DTO implements Serializable {
         private HashMap<String, Object> map;

         //setter or getter
}

Tuesday, May 10, 2011

Integrating JSF + Spring

I'm have been using JSF since 1.x release. and still confusing with lot of xml configurations. Then when come to JSF 2.0 there's a lot of improvement, in navigation, annotations etc. Then I'm using Spring to integrate with JSF. Then come into a conclusion, what do you need to know when using JSF only or using JSF + Spring. This is based on my own experience. Anyone feel free to correctme if I'm wrong, or adding any more information.


Using JSF only
When using JSF, without Spring, mostly dependency-injection will be performed by JSF itself. This one is declaring a managed bean in session scope.

@ManagedBean
@SessionScope
public class LoginBean {

}

When you want inject other bean in this bean. You will use @ManagedProperty annotation given by JSF.

@ManagedBean
@SessionScope
public class LoginBean {
     @ManagedProperty(value="#{otherBean}")
     OtherBean otherBean;

     //make sure create the setter for injection
     public void setOtherBean(OtherBean otherBean){
        this.otherBean = otherBean;
     }
}

@ManagedBean
@SessionScope
public class OtherBean {
  
}


How to enable JSF auto completion support in Eclipse

Currently i have a project using JSF 2.0 with Spring integration. And using several cool framework like Primefaces I really a auto completion when working with .xhtml (Facelets)

I'm staring a project as Maven project web app. Then i create the web page in .xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.prime.com.tr/ui">


</html>

I want when I type <p: and press Ctrl + Space, it should show the auto completion to help my work.

The steps are very easy:
  1. Download Eclipse bundle release Helios
  2. Goto your project, right click, then click on Properties
  3. Goto Project Facest (see left menu)
  4. Convert the project, choose the configuration as JavaServer Faces 2.0 Projects
  5. Applying to your project (the eclipse will rebuild your project)
  6. Done!