03-05-2013 03:26 AM - edited 03-05-2013 03:27 AM
Hello,
I´m using TableLayoutManager in my project. This is an example of my problem:
I have this code:
public MyScreen() {
setTitle("TableLayoutManager_Example");
VerticalFieldManager vfm0 = new VerticalFieldManager();
vfm0.setBorder(BorderFactory.createSimpleBorder(ne w XYEdges(10, 10, 10, 10), Border.STYLE_TRANSPARENT));
VerticalFieldManager vfm = new VerticalFieldManager();
vfm.setBorder(BorderFactory.createRoundedBorder(ne w XYEdges(5, 5, 5, 5)));
TableLayoutManager table = new TableLayoutManager(new int[] { TableLayoutManager.USE_PREFERRED_SIZE,
TableLayoutManager.SPLIT_REMAINING_WIDTH, }, null, 0, Manager.NO_HORIZONTAL_SCROLL
| Manager.NO_VERTICAL_SCROLL);
LabelField lb=new LabelField("Label1 ");
HorizontalFieldManager hfm=new HorizontalFieldManager();
TextField tf=new TextField();
LabelField lb2=new LabelField("Label2",Field.FOCUSABLE);
tf.setText("Text");
tf.setMaxSize(5);
hfm.add(lb2);
hfm.add(tf);
LabelField lb3=new LabelField("Label3");
LabelField lb4=new LabelField("Label4",Field.FOCUSABLE);
table.add(lb);
table.add(hfm);
table.add(new SeparatorField());
table.add(new SeparatorField());
table.add(lb3);
table.add(lb4);
vfm.add(table);
vfm0.add(vfm);
add(vfm0);
}The problem is that I can´t put the focus in the TextField. If I just add to table the components lb and hfm it works, but If I add others focusable components (like example) I can´t put the focus in the TextField, the focus set in Label4:
What can I do?
Thank you.
Solved! Go to Solution.
03-05-2013 04:48 AM
TableLayoutManager was written to handle one focusable element per 'cell' and as a result, will move focus to the next cell on focus movement events. Have a good look at the navigationMovement() method to get an idea of the assumptions and the impact that this has.
I don't think there is no easy way around this other than re-writing the focus movement methods in TableLayoutManager to detect that the cell has multiple possibilities and pass control to it for these events. This would be doable, and if I was better and these things I might think it would be easy, but this is not something I am very good at. Perhaps some other forum contributor might help if you decide that is what you want to do.
03-07-2013 05:20 AM
Finally, I´ve replaced the TableLayoutManager for GridFieldManager. However, I´m going to continue investigating about focus movement methods, like you´ve said me.
If I discover something, I will post it.
03-07-2013 10:07 AM
I´ve found a good solution. I´ve overwritten the navigationMovement method of TableLayoutManager. This is the code:
/**
* Navigation movement to allow for both cell to cell within a columns and row movement
*/
protected boolean navigationMovement(int dx, int dy, int status, int time) {
int focusIndex = getFieldWithFocusIndex();
int dirY = (dy > 0) ? 1 : -1;
int absY = Math.abs(dy);
for (int y = 0; y < absY; y++) {
focusIndex += _columns * dirY;
if (focusIndex < 0 || focusIndex >= getFieldCount()) {
//#ifdef BlackBerrySDK4.5.0
this.invalidate(); //ref #217
//#endif
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
} else
y--; // do it over again
}
}
int dirX = (dx > 0) ? 1 : -1;
int absX = Math.abs(dx);
for (int x = 0; x < absX; x++) {
focusIndex += dirX;
if (focusIndex < 0 || focusIndex >= getFieldCount()) {
//#ifdef BlackBerrySDK4.5.0
this.invalidate(); //Ref #217
//#endif
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
////////////////////////NEW CODE /////////////////////////////////////
if(f instanceof Manager){
int fieldsInManager=((Manager)f).getFieldCount();
if(fieldsInManager>0){
for(int i=0;i<fieldsInManager;i++){
Field field=((Manager)f).getField(i);
if(field.isFocusable()){
field.setFocus();
}
}
}
}
////////////////////////////////////////////////// ////////////////////
} else
x--; // do it over again
}
focusIndex += dirX;
}
//#ifdef BlackBerrySDK4.5.0
this.invalidate(); //ref #217
//#endif
return true;
}I look for a manager inside the cell. If I found it, I set the focus in its elements. This works with a manager with one or more focusable elements.
If you see it right, you could add this code to your original code
Thank you.
03-07-2013 10:45 AM
Not sure your code copes with both left and right trackpad movements properly. That said, it is along the lines I was thinking when I posted previously. I think there are Manager focus methods, like nextFocus that might make it easier to figure out. Your approach is a little 'bruteforce', I suspect there are better ways.
Anyway, if it is working well enough for you, great. I think your code would be a good start for the next person who has this problem.