07-23-2012 01:59 AM
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.
Solved! Go to Solution.
07-23-2012 07:22 AM
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.
07-23-2012 07:34 AM
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.
07-23-2012 08:40 AM
07-24-2012 01:41 AM - edited 07-24-2012 01:57 AM
Thanks for the code. That would help me a lot. Thanks pp.
07-24-2012 01:54 AM - edited 07-24-2012 02:24 AM
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.
07-24-2012 05:10 AM
07-24-2012 05:14 AM
"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.
07-24-2012 05:18 AM
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.g etFieldWithFocusIndex());
oldField.setOnFocus(false);
labelField newField = (labelField)scrollManager.getField(scrollManager.g etFieldAtLocation(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[focusedFieldInde xNew];
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_HEAD ER_IMAGE,0,0);
}
}else {
for(int i = 1; i < getWidth(); i++){
graphics.drawBitmap(i,0,1,getHeight()-1,HEADER_IMA GE,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())/tem p.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,LabelFontSiz e,Color.LIGHTGREY)and add to scrollmanager... you can do this in forloop
scrollManager = new CentricHFManager();
scrollManager.add(field);
07-24-2012 06:21 AM