Pablo
Pablo

Reputation: 3467

Create grouped tableView like mail application in blackberry

I haven't seen many explained examples about TableView. Of course I came out with a basic implementation of it (by using the Template, Model etc). However now I would like to implement sections, grouping the rows by common fields. For example date. That's why I came out with this question, how could I implement them as in the Mail Application, or maybe there are links that could help (already searched about it), or some code samples?

EDIT:

I would like to explain what I have done until now.

The intention is to sort the fields by any criteria you would like, then loop them and use a variable to register the current value of the field we are sorting, in this case it is a String. This way when the last value of that variable changes it means that the category did change also (since it's a sorted list). According to the tableModel, we could add a row with the title we would like to set for the category.

This way in the getDataFields Method we would test if the data we retrieved has just a single value and then return an array of Fields[] according to the section we would like to show in the table. Now this is what I tried, however when the category row is painted, the tableView just stops looping the other fields (obviously an exception is thrown but since the Blackberry APIs and simulator error management is sooooo extraordinary, I don't get any message to see what's going on).

This is the code I'm using currently, hope anyone can check what I'm doing wrong and suggest any improvement to the code I could make.

public class AutorizacionesScreen extends MainScreen implements HttpDelegate {

private final int ROW_HEIGHT = 30;

TableView tableView;
TableModel tableModel;
ActivityIndicatorView activityView;
SimpleSortingVector autorizaciones;

VerticalFieldManager manager;
Font listFont;
PollAutorizacionesThread pollThread;

public AutorizacionesScreen() {
    super(NO_VERTICAL_SCROLL);
    setTitle(new LabelField("Workflow Details", Field.FIELD_HCENTER
            | Field.NON_FOCUSABLE));
    manager = new VerticalFieldManager();
    tableModel = new TableModel();
    tableView = new TableView(tableModel);
    WorkflowDataTemplate template = new WorkflowDataTemplate(tableView);
    template.createRegion(new XYRect(0, 0, 1, 1));
    template.createRegion(new XYRect(1, 0, 1, 1));
    template.createRegion(new XYRect(2, 0, 1, 1));
    template.createRegion(new XYRect(3, 0, 1, 1));
    template.setColumnProperties(0, new TemplateColumnProperties(10,
            TemplateColumnProperties.PERCENTAGE_WIDTH));
    template.setColumnProperties(1, new TemplateColumnProperties(15,
            TemplateColumnProperties.PERCENTAGE_WIDTH));
    template.setColumnProperties(2, new TemplateColumnProperties(25,
            TemplateColumnProperties.PERCENTAGE_WIDTH));
    template.setColumnProperties(3, new TemplateColumnProperties(50,
            TemplateColumnProperties.PERCENTAGE_WIDTH));
    template.setRowProperties(0, new TemplateRowProperties(ROW_HEIGHT));
    template.useFixedHeight(true);
    tableView.setDataTemplate(template);

    TableController controller = new TableController(tableModel, tableView);
    controller.setFocusPolicy(TableController.ROW_FOCUS);
    tableView.setController(controller);

    FontFamily fontFamily;
    try {
        fontFamily = FontFamily.forName("BBClarity");
        listFont = fontFamily.getFont(FontFamily.CBTF_FONT, 15);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

    activityView = new ActivityIndicatorView(FIELD_HCENTER,
            new HorizontalFieldManager());
    Bitmap bitmap = Bitmap.getBitmapResource("waiting.png");
    activityView.createActivityImageField(bitmap, 12, 0);
    ActivityImageField animation = activityView.getAnimation();
    animation.setPadding(0, 5, 0, 0);
    activityView.setLabel("Por favor espere...");
    manager.add(activityView);
    manager.add(tableView);
    add(manager);

    checkServerSession();

//      if(!ApplicationPreferences.getInstance().isLoggedIn()){
//          UiApplication.getUiApplication().invokeLater(new Runnable() {
//              
//              public void run() { 
//                      UiApplication.getUiApplication().popScreen(AutorizacionesScreen.this);
//                  
//              }
//          });
//      return;
//      }

    pollThread=new PollAutorizacionesThread(30000);
    pollThread.start();
}

private void checkServerSession() {
    if (!ApplicationPreferences.getInstance().isLoggedIn()) {
        UiApplication.getUiApplication().invokeAndWait(new Runnable() {

            public void run() {
                ApplicationPreferences.getInstance().login();

            }
        });
    }

}

public void reloadData() {
    if (!ApplicationPreferences.getInstance().isLoggedIn()) {
        String url = Properties.getInstance().getProperties()
                .get("resource.base").toString()
                + Properties.getInstance().getProperties()
                        .get("ec.com.smx.workflow.autorizaciones.activas")
                        .toString();
        UiApplication.getUiApplication().invokeLater(new Runnable() {

            public void run() {
                if(manager.getField(0) instanceof TableView){
                    manager.insert(activityView, 0);
                }
            }
        });
        HttpHelper helper = new HttpHelper(url, null, this);
        helper.setOperation(HttpHelper.GET);
        helper.start();
    }
}

private class PollAutorizacionesThread extends Thread{

    private long pollTime;
    private boolean _stop=false;

    public PollAutorizacionesThread(long sleepTime) {
        pollTime=sleepTime;
    }

    public void run(){
        while(!_stop){
            try {
                reloadData();
                Thread.sleep(pollTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    public void stop(){
        _stop=true;
    }
}

private class WorkflowDataTemplate extends DataTemplate {

    public WorkflowDataTemplate(TableView view) {
        super(view, 1, 4);

    }

    public Field[] getDataFields(int modelRowIndex) {
        Object[] data = (Object[]) ((TableModel) getView().getModel())
                .getRow(modelRowIndex);
        Field[] fields=null;
        if(data.length==1){
            fields=new Field[4];
            fields[0]=new LabelField("",DrawStyle.ELLIPSIS
                    | Field.FIELD_VCENTER);
            fields[1] = new LabelField("",DrawStyle.ELLIPSIS
                    | Field.FIELD_VCENTER);
            fields[2]=new LabelField(data[0],DrawStyle.ELLIPSIS
                    | Field.FIELD_VCENTER);
            fields[3]=new LabelField("",DrawStyle.ELLIPSIS
                    | Field.FIELD_VCENTER);
            return fields;
        }
        fields = new Field[4];
        fields[0] = new BitmapField(
                Bitmap.getBitmapResource("envelope.png"),
                Field.FIELD_VCENTER);
        LabelField newField = new LabelField(data[1],
                LabelField.FIELD_VCENTER | LabelField.FIELD_RIGHT) {
            public void paint(Graphics g) {
                g.drawText(getText(), 0, (ROW_HEIGHT - getFont()
                        .getHeight()) / 2);
            }

            protected void layout(int width, int height) {
                super.layout(
                        Math.min(width,
                                this.getFont().getAdvance(this.getText())),
                        40); // height of the bitmap);
                setExtent(
                        Math.min(width,
                                this.getFont().getAdvance(this.getText())),
                        40); // height of the bitmap);
            }
        };
        newField.setFont(listFont);
        fields[1] = newField;

        fields[2] = new LabelField(data[2], DrawStyle.ELLIPSIS
                | Field.FIELD_VCENTER);
        fields[3] = new LabelField(data[3], DrawStyle.ELLIPSIS
                | Field.FIELD_VCENTER);
        return fields;
    }

}

private class AutorizacionComparator implements Comparator{

    public int compare(Object o1, Object o2) {
        Calendar c1=Calendar.getInstance();
        c1.setTime(((Autorizacion)o1).getFechaCreacionAutorizacion());
        Calendar c2=Calendar.getInstance();
        c2.setTime(((Autorizacion)o2).getFechaCreacionAutorizacion());
        long deltaSeconds = (c2.getTime().getTime()-c1.getTime().getTime())/1000;
        if(deltaSeconds==0) return 0;
        if(deltaSeconds>0) return -1;
        return 1;
    }

}

public void didReceiveData(byte[] data) {
    AutorizacionesParser autorizacionesParser = new AutorizacionesParser();
    try {
        autorizacionesParser.initialize(data);
        Vector autorizacionesVector=autorizacionesParser.readObjects();
        autorizaciones=new SimpleSortingVector();
        autorizaciones.setSortComparator(new AutorizacionComparator());
        for (int i = 0; i < autorizacionesVector.size(); i++) {
            autorizaciones.addElement(autorizacionesVector.elementAt(i));
        }
        autorizaciones.setSort(true);
        autorizaciones.reSort();

        for (int i = 0; i < autorizacionesVector.size(); i++) {
            System.out.println(((Autorizacion)autorizaciones.elementAt(i)).getFechaCreacionAutorizacion());
        }
    } catch (ParserException e) {
        e.printStackTrace();
    }
    int count=tableModel.getNumberOfRows();
    for (int i = 0; i < count; i++) {
        tableModel.removeRowAt(0);
    }

    Calendar dateCalendar=Calendar.getInstance();
    String lastDay="";
    for (int i = 0; i < autorizaciones.size(); i++) {
        Autorizacion item = (Autorizacion) autorizaciones
                .elementAt(i);
        dateCalendar.setTime(item.getFechaCreacionAutorizacion());
        String day=String.valueOf(dateCalendar.get(Calendar.DAY_OF_MONTH))+"//"+
                   String.valueOf(dateCalendar.get(Calendar.MONTH)+1)+"//"+
                   String.valueOf(dateCalendar.get(Calendar.YEAR));

        if(!lastDay.equals(day)){
            lastDay=day;
            tableModel.addRow(new Object[]{day});
        }

        tableModel.addRow(new Object[] { item.getEstado().toString(),
                (new Integer(item.getNumeroAutorizacion()).toString()),
                item.getFechaCreacionAutorizacion().toString(),
                item.getObservacionAutorizacion()});
    }


    UiApplication.getUiApplication().invokeLater(new Runnable() {

        public void run() {

            try{
            if(manager.getField(0) instanceof ActivityIndicatorView){
                manager.delete(activityView);
                tableView.invalidate();

            }
            }catch (NullPointerException e) {
                // TODO: WORKAROUND BECAUSE RIM APIS ARE BUGGY

            }
        }
    });

}

public void didReceiveUnauthorizedResponse() {
    // TODO: HANDLE ERRORS

}

public void didReceiveResponse(int statusCode) {
    // TODO: IN CASE OF POST REQUEST THIS COULD BE USED

}

public boolean onClose() {

    if(pollThread!=null)
        pollThread.stop();
    return super.onClose();
}

}

Upvotes: 0

Views: 487

Answers (1)

Maksym Gontar
Maksym Gontar

Reputation: 22775

I would advice you to do following:

Add more error logging

Add more try-catch stuff with error logging. In this particular case try to catch(Exception e) just to be sure you will not miss anything, and do logging in every catch.

I would suggest to put following methods totally in try-catch:

AutorizacionesScreen.checkServerSession()
AutorizacionesScreen.reloadData()
AutorizacionComparator.compare()
AutorizacionesScreen.didReceiveData()

Share exception details with us.

Cleanup code in question

Code you have came up with is not operable since there are lots of custom classes there (ex Autorizacion, AutorizacionesParser, ParserException, HttpHelper, Properties, ApplicationPreferences, HttpDelegate) and also it require some server side, is that right?

You should try to help others helping you: please, separate your issue from your project.

For this, create a new Eclipse workspace and create new BlackBerry project there, put this code there and remove all unrelated classes. If you need additional classes, put it into the same *.java file.

Remove server calls if its possible, if not, replace them with mockup data (just create some arrey of data objects in the same class file you have issued).

With this done, you will get help from us a very very most likely!

Upvotes: 1

Related Questions