问题
I can't find solution for the following problem. I have custom list field, which overlaps the boundaries of its layout manager. List field consumes navigation events from manager to highlight currently selected row with special color. Layout manager is configured to support scrolling. When I scroll trackwheel down, layout manager invokes scrolling and then passes navigation event to its child, the list field. It results in inproper scrolling, because manager scrolls the whole list down to its bottom hiding list rows on the top including the selected row.
What I want is to ignore scrolling while currently selected list row is still visible and employ it otherwise.
I'm using JDE 4.2.1
回答1:
Let's say we have ListField implementation:
class LabelListField extends ListField implements ListFieldCallback {
private Vector mValues;
public LabelListField(Vector values) {
super(0);
setRowHeight(getFont().getHeight() + 10);
setCallback(this);
mValues = values;
setSize(mValues.size());
}
public void drawListRow(ListField listField, Graphics g, int index, int y,
int width) {
g.drawText((String) mValues.elementAt(index), 0, y);
}
public Object get(ListField list, int index) {
return mValues.elementAt(index);
}
public int indexOfList(ListField list, String prefix, int start) {
for (int x = start; x < mValues.size(); ++x) {
String value = (String) mValues.elementAt(x);
if (value.startsWith(prefix)) {
return x;
}
}
return -1;
}
public int getPreferredWidth(ListField list) {
return Display.getWidth();
}
}
If we want to align this list within upper and lower fields this way:
ListField with scroll http://img6.imageshack.us/img6/7025/8800j.png
we can limit it's height using custom manager:
class ListManager extends HorizontalFieldManager {
ListField mListField;
public ListManager(ListField listField) {
super(VERTICAL_SCROLL | VERTICAL_SCROLLBAR);
mListField = listField;
add(mListField);
}
public int getPreferredHeight() {
int result = Display.getHeight();
Manager manager = getManager();
if (null != manager) {
for (int i = 0, count = manager.getFieldCount(); i < count; i++) {
if (manager.getField(i) != this)
result -= manager.getField(i).getPreferredHeight();
}
}
// size down to fit max rows without splitting
result = result - result % mListField.getRowHeight();
return result;
}
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(maxWidth, maxHeight);
setExtent(maxWidth, getPreferredHeight());
}
}
Now we can use it:
class Scr extends FullScreen implements FieldChangeListener {
LabelField mHeader;
ListManager mHFMList;
HorizontalFieldManager mHFMButton;
LabelListField mListField;
ButtonField mButton;
public Scr() {
super(DEFAULT_MENU | DEFAULT_CLOSE);
mHeader = new LabelField("List Field", FIELD_HCENTER);
add(mHeader);
Vector values = new Vector();
values.addElement("first");
values.addElement("second");
values.addElement("third");
values.addElement("fourth");
values.addElement("fifth");
values.addElement("sixth");
values.addElement("seventh");
values.addElement("eight");
mListField = new LabelListField(values);
mHFMList = new ListManager(mListField);
add(mHFMList);
mHFMButton = new HorizontalFieldManager(FIELD_HCENTER);
add(mHFMButton);
mButton = new ButtonField("Exit", ButtonField.CONSUME_CLICK);
mButton.setChangeListener(this);
mHFMButton.add(mButton);
}
public void fieldChanged(Field field, int context) {
if (mButton == field)
close();
}
}
Tested on eJDE 4.2.1.17 8800
回答2:
all here's the solution that helped me. By overriding moveFocus in such specific way I managed to modify default behavior of scrolling in layout manager - it skips first items of list field allowing them to stay on top.
public int moveFocus(int amount, int status, int time) {
invalidate(getSelectedIndex());
int unused = super.moveFocus(amount, status, time);
return Math.abs(unused) + 1;
}
来源:https://stackoverflow.com/questions/1379391/cancel-scrolling-in-layout-manager