Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Contributor
june_misuki
Posts: 27
Registered: ‎06-19-2012
My Device: Developer
Accepted Solution

Issues with design of table with scroll

 

Hi,

 

I have used TableLayoutManager in my code to draw a table. The leftmost column is frozen.ie.it has no vertical/horizontal scroll. the other columns to its right are horizontally scrollable.ie.since the table has around 9 columns and last column is only seen if you scroll.

 

In reality to acheive this, i have drawn two tables. The first column is a seperate table alltogether without scroll and the rest of the columns are a different table. But its designed to feel like a single table.

 

Ok. Here is the problem. If the table has a lot of rows the main manager should have vertical scroll to view the rows at the bottom. But then if you are looking at the last row, the first row, which contains the the title of the columns is not visible.

 

To solve this, i can make four tables. table 1 for column heading of col1, table 2 for column heading of col2-col9.

table 3 for all other rows of col 1 and table 4 for all other rows of col2-col9. 

 

But then col2-col9 have to be horizontally scrollable. But since col2-col9 are now made up of 2 tables.ie.table 2 and table 4, it does not scroll as one whole unit.

 

Please help. I have been stuck with this for a few days now.

 

Developer
peter_strange
Posts: 19,609
Registered: ‎07-14-2008
My Device: Not Specified

Re: Issues with design of table with scroll

I have wondered what I would do if someone asked me to do something similar.

 

I think there are these choices:

 

a) Have one Table, and update the Cell contents each time.  This is actually simpler than you might think provided the size of these cells does not change.  In that case all you effectively do is provided each Field in the Table with the details of the data it is to paint. This does mean that scrolling is done only on cell boundaries.

 

b) have one Table, but update the Field contents each time.  This of course would force a relayout each time the table scrolled, but would means that the Cells can have different shapes and sizes.  Once again, scrolling would be on Cell boundaries. 

 

c) Have three tables, one that has the fixed rows, one that has the fixed columns and one that has all the data.  Then have the two Managers both become scroll Listener and react whenever the one that has all the data is moved. 

 

Personally I would make sure my requirement could not be satisfied with Option (a), and if not, then I would try to implement Option (c).  I think Option (b) is likely to perform quite badly. 

 

Contributor
june_misuki
Posts: 27
Registered: ‎06-19-2012
My Device: Developer

Re: Issues with design of table with scroll

I tried to implement c. But manually setting the scroll using scroll using scrolllistener, results in a scroll delay. Its like the table with fixed row/col is trying to catch up with the table with all data whwnever scroll happens. 

Super Contributor
pp
Posts: 278
Registered: ‎11-04-2010
My Device: 4.5 and above

Re: Issues with design of table with scroll

Hi,

I have desined the same using horizontalField manger. The other part you have to manage. if so then ill give the scrollabel manager and the navigation part of screen.

Regards,
pp
Contributor
june_misuki
Posts: 27
Registered: ‎06-19-2012
My Device: Developer

Re: Issues with design of table with scroll

[ Edited ]

Thanks for the code. That would help me a lot. Thanks pp.

Contributor
june_misuki
Posts: 27
Registered: ‎06-19-2012
My Device: Developer

Re: Issues with design of table with scroll

[ Edited ]

By the way, is there a way i could join 2 managers dynamically at runtime depending on scroll? If there is, there is a simple way to do this.

Super Contributor
pp
Posts: 278
Registered: ‎11-04-2010
My Device: 4.5 and above

Re: Issues with design of table with scroll

Hi,

join 2 managers dynamically at runtime depending on scroll?
what this meant.. when scroll remove this manager and place another manager?

Regards,
pp
Developer
peter_strange
Posts: 19,609
Registered: ‎07-14-2008
My Device: Not Specified

Re: Issues with design of table with scroll

"is there a way i could join 2 managers dynamically at runtime depending on scroll?"

 

I am not aware of a way to do this. 

 

Super Contributor
pp
Posts: 278
Registered: ‎11-04-2010
My Device: 4.5 and above

Re: Issues with design of table with scroll

Hi,

 

here is the idea... i have done this only for title field of table... you can apply same for whole table...

 

This is for the mainscreen class

protected boolean navigationMovement (final int dx,final int dy, int status, int time ) {
        focusIndex = scrollManager.getFieldWithFocusIndex();
        if(dx < 0 || dx > 0){
            if(dx < 0){
                focusIndex -= 1;
            }else if(dx > 0){
                focusIndex += 1;
            }
            if (focusIndex < 0 || focusIndex >= TOTAL_DAYS+1) {
                return false;
            } else {
                UiApplication.getUiApplication().invokeLater(new Runnable() { 
                    public void run() {
                        index = focusIndex;
                        if(dx < 0){
                            labelField oldField = (labelField)scrollManager.getField(focusIndex+1);
                            oldField.setOnFocus(false);
                        }else if(dx > 0){
                            labelField oldField = (labelField)scrollManager.getField(focusIndex-1);
                            oldField.setOnFocus(false);
                        }
                        labelField field = (labelField)scrollManager.getField(focusIndex);
                        field.setOnFocus(true);
                        scrollManager.focusChangeNotify();
                    }
                });
            }
        }else if(dy > 0 || dy < 0){
            return super.navigationMovement(dx,dy, status, time );
        }
        /*if(isKeepGoing){
            return super.navigationMovement(dx,dy, status, time );
        }*/
        return true;
    }
    protected boolean touchEvent(TouchEvent message) {
        TouchGesture gesture = message.getGesture();
        int eventCode = message.getEvent();
        if (message.getEvent() == TouchEvent.CLICK) {
            int x = message.getX(1);
            int y = message.getY(1);
            XYRect r = scrollManager.getExtent();
            if (r.contains(x, y)) {
                labelField oldField = (labelField)scrollManager.getField(scrollManager.getFieldWithFocusIndex());
                oldField.setOnFocus(false);
                labelField newField = (labelField)scrollManager.getField(scrollManager.getFieldAtLocation(x,y));
                focusIndex = newField.getIndex();
                index = focusIndex;
                newField.setOnFocus(true);
                scrollManager.focusChangeNotify();
            }
        }else if(eventCode == TouchEvent.GESTURE) {
            int gestureCode = gesture.getEvent();
            if (gestureCode == TouchGesture.SWIPE) {
                final int swipeDirection = gesture.getSwipeDirection();
                if(swipeDirection == TouchGesture.SWIPE_EAST || swipeDirection == (TouchGesture.SWIPE_NORTH| TouchGesture.SWIPE_EAST)){
                    focusIndex -= 1;
                }else if(swipeDirection == TouchGesture.SWIPE_WEST || swipeDirection == (TouchGesture.SWIPE_SOUTH|TouchGesture.SWIPE_WEST)){
                    focusIndex += 1;
                }else{
                    return super.touchEvent(message);
                }
                if (focusIndex < 0 || focusIndex >= TOTAL_DAYS+1) {
                    return false;
                } else {
                    UiApplication.getUiApplication().invokeLater(new Runnable() { 
                        public void run() {
                            index = focusIndex;
                            if(swipeDirection == TouchGesture.SWIPE_EAST || swipeDirection == (TouchGesture.SWIPE_NORTH| TouchGesture.SWIPE_EAST)){
                                labelField oldField = (labelField)scrollManager.getField(focusIndex+1);
                                oldField.setOnFocus(false);
                            }else if(swipeDirection == TouchGesture.SWIPE_WEST || swipeDirection == (TouchGesture.SWIPE_SOUTH|TouchGesture.SWIPE_WEST)){
                                labelField oldField = (labelField)scrollManager.getField(focusIndex-1);
                                oldField.setOnFocus(false);
                            }
                            labelField field = (labelField)scrollManager.getField(focusIndex);
                            field.setOnFocus(true);
                            scrollManager.focusChangeNotify();
                        }
                    });
                }
            }
        }
        return super.touchEvent(message);
    }

 declare the required values globally...

 

and this is my scrollable hfm

 

class CentricHFManager extends HorizontalFieldManager {
        int focusedFieldIndex = 0;
        int scroll;
        int middlePoint;
        int position;
        int focusedFieldIndexNew = 0;
        
        CentricHFManager(){
            super(Manager.HORIZONTAL_SCROLL | Manager.NO_VERTICAL_SCROLL);
        }
        protected void sublayout(int maxWidth, int maxHeight) {
            int x = -scrollpos;
            for (int i = 0; i < getFieldCount(); i++) {
                layoutChild(getField(i), 0, maxHeight);
                setPositionChild(getField(i), x , 0);
                x = x + getField(i).getWidth();
            }
            setExtent(getPreferredWidth(),getPreferredHeight());         
        }
        public int getFieldWithFocusIndex(){
            for(int i = 0; i < getFieldCount(); i++){
                labelField field = (labelField)getField(i);
                if(field.getIsOnFocus()){
                    return i;
                }
            }
            return 0;
        }
        public void focusChangeNotify(){
            focusedFieldIndexNew = getFieldWithFocusIndex();
            if (focusedFieldIndexNew >= 0 && focusedFieldIndexNew != focusedFieldIndex && focusedFieldIndexNew < getFieldCount()) {
                labelField focus = (labelField)getField(focusedFieldIndexNew);
                position  = focus.getPreferredWidth() * focusedFieldIndexNew;//xPositions[focusedFieldIndexNew];
                isKeepGoing = true;
                if (focusedFieldIndexNew - focusedFieldIndex > 0){
                    if(focusedFieldIndexNew == getFieldCount() - 1){
                        middlePoint = Display.getWidth() - getField(focusedFieldIndexNew).getPreferredWidth();
                        scroll = position - middlePoint;
                    }else {
                        middlePoint = (Display.getWidth() - getField(focusedFieldIndexNew).getPreferredWidth())/2;
                        scroll = position - middlePoint;
                    }
                    if(focusedFieldIndexNew != 0  && !(scroll < 0)){
                         new Thread(){
                            public void run(){
                                while(isKeepGoing){
                                    scrollpos = scrollpos + 10;
                                    if(scrollpos < scroll){
                                        isKeepGoing = true;
                                        sublayout(getPreferredWidth(), getPreferredHeight());
                                        invalidate();
                                    }else {
                                        isKeepGoing = false;
                                        scrollpos = scroll;
                                        sublayout(getPreferredWidth(), getPreferredHeight());
                                        invalidate();
                                    }
                                    try{sleep(10);}catch(Exception e){System.out.println("Exception Thrown here :"+ e);}
                                }
                            }
                        }.start();
                    }
                } else {
                    if(focusedFieldIndexNew == 0){
                        scroll = 0;
                    }else {
                        middlePoint = (Display.getWidth() - getField(focusedFieldIndexNew).getPreferredWidth())/2;
                        scroll = position - middlePoint;
                    }
                    if(focusedFieldIndexNew != getFieldCount()-1  && !(scroll < 0)){
                         new Thread(){
                            public void run(){
                                while(isKeepGoing){
                                    scrollpos = scrollpos - 10;
                                    if(scrollpos > scroll){
                                        isKeepGoing = true;
                                        sublayout(getPreferredWidth(), getPreferredHeight());
                                        invalidate();
                                    }else {
                                        isKeepGoing = false;
                                        scrollpos = scroll;
                                        sublayout(getPreferredWidth(), getPreferredHeight());
                                        invalidate();
                                    }
                                    try{sleep(10);}catch(Exception e){System.out.println("Exception Thrown here :"+ e);}
                                }
                            }
                        }.start();
                    }
                }
                focusedFieldIndex = focusedFieldIndexNew;
            }
        }
        public void add(Field field) {
            super.add(field);
        }
    }

 and this is my lable field

public class labelField extends Field {
        Font font = Font.getDefault().derive(Font.PLAIN,20);
        String label = "";
        private boolean onFocus = false;
        private int ScreenWidth = Display.getWidth();
        
        labelField(String label,long style){
            super(style);
            this.label = label;
        }
        public int getPreferredWidth() {
            if(ScreenWidth <= 320 && DateArray.length > 2){
                return 150;
            }else if(ScreenWidth > 320 && DateArray.length > 3){
                return ScreenWidth/3;
            }else {
                return ScreenWidth/DateArray.length;
            }
        }
        public int getPreferredHeight() {
            return 30;
        }
        public boolean getIsOnFocus(){
            return onFocus;
        }
        public void setOnFocus(boolean value){
            onFocus = value;
            if(onFocus){
                addLeaveMembers();      
            }
            invalidate();
        }  
        protected void layout(int width, int height){
            setExtent(getPreferredWidth(), Math.max(getHeight(), getPreferredHeight()));
        }
        protected void paint(Graphics graphics) {
            if(onFocus){
                for(int i = 1; i < getWidth(); i++){
                    graphics.drawBitmap(i,0,1,getHeight()-1,LABEL_HEADER_IMAGE,0,0);
                }
            }else {
                for(int i = 1; i < getWidth(); i++){
                    graphics.drawBitmap(i,0,1,getHeight()-1,HEADER_IMAGE,0,0);
                }
            }
            graphics.setFont(font);
            graphics.setColor(onFocus ? Color.BLACK : Color.WHITE);
            LineEnumeration e = new LineEnumeration(font,label,getWidth()-5);
            Vector temp = new Vector();
            while ( e.hasMoreElements() ) {
                temp.addElement(e.nextElement());
            }
            for(int i = 0 ; i < temp.size(); i++ ){
                if(i == 0){
                    graphics.drawText((String)temp.elementAt(i), (getWidth() - font.getAdvance((String)temp.elementAt(i)))/2, ((i*font.getHeight())+(((getPreferredHeight())/temp.size()) - font.getHeight() )/2) ); 
                } else {
                    graphics.drawText((String)temp.elementAt(i), (getWidth() - font.getAdvance((String)temp.elementAt(i)))/2, ((i*font.getHeight())+(((getPreferredHeight()+10)/temp.size()) - font.getHeight() )/4) );   
                }
            }
        }
    }
} 

 dont worry about LineEnumeration ... this is just a class.... just drawText as usual... and TOTAL_DAYS IS no of columns..

 

how to add to mainscreen ...

create new label field 

new CustomLabelField("Status:",Font.PLAIN,LabelFontSize,Color.LIGHTGREY)

and add to scrollmanager... you can do this in forloop

scrollManager = new CentricHFManager();
scrollManager.add(field);
Contributor
june_misuki
Posts: 27
Registered: ‎06-19-2012
My Device: Developer

Re: Issues with design of table with scroll

No. Its like for example, vfm main has hfm1, hfm2 and hfm3. If horizontal scroll, you put hfm1 and 2 in a vfm. and then put this vfm in vfm main.then put hfm3 seperately in vfm main.

If vertical scroll, u similarly join hfm2 and 3.

Is something like this possible??