在 ListField 中显示额外的行
我试图在 ListField 的顶部显示一个额外的行 - 称为“添加项目”,它几乎可以工作,但我的数据的最后一行“项目 4”未显示。
您将如何解决此问题?
请参阅下面我非常简单的测试代码 MyList.java:
package mypackage;
import java.util.*;
import net.rim.device.api.collection.*;
import net.rim.device.api.collection.util.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.util.*;
public class MyList extends UiApplication {
public static void main(String args[]) {
MyList app = new MyList();
app.enterEventDispatcher();
}
public MyList() {
pushScreen(new MyScreen());
}
}
class MyScreen extends MainScreen {
ObjectListField myList = new ObjectListField() {
public void drawListRow(ListField list,
Graphics g,
int index,
int y,
int width) {
if (index == 0) {
Font i = getFont().derive(Font.ITALIC);
g.setFont(i);
g.drawText("Add Item", 0, y);
} else {
String str = (String) get(this, index - 1);
g.drawText(str, 0, y);
}
}
protected boolean navigationClick(int status, int time) {
int index = myList.getSelectedIndex();
String str = (index > 0 ? (String) get(this, index - 1) :
"Add item");
Status.show("You have clicked: " + str);
return true;
}
};
public MyScreen() {
setTitle("How to display an extra row?");
myList.set(new String[]{"Item 1","Item 2","Item 3","Item 4",});
// myList.setSize(5);
add(myList);
}
}
我尝试添加 myList.setSize(5); 但得到 Vector.elementAt(4) 抛出的 ArrayIndexOutOfBoundsException
更新:
根据Michael的建议,我已从ObjectListField切换到KeywordFilterField(这是我在实际程序中实际使用的),现在我可以调用myList.setSize(5)没有任何异常被抛出。
但最后一行仍然没有显示:
package mypackage;
import java.util.*;
import net.rim.device.api.collection.*;
import net.rim.device.api.collection.util.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.util.*;
public class MyList extends UiApplication {
public static void main(String args[]) {
MyList app = new MyList();
app.enterEventDispatcher();
}
public MyList() {
pushScreen(new MyScreen());
}
}
class MyScreen extends MainScreen {
static final int EXTRA_ROWS = 1;
MyItemList myItems = new MyItemList();
KeywordFilterField myList = new KeywordFilterField() {
protected boolean navigationClick(int status, int time) {
int index = getSelectedIndex();
String str = (index < EXTRA_ROWS ? "Add item" :
((MyItem) getElementAt(index - EXTRA_ROWS)).toString());
Status.show("You have clicked - " + str);
return true;
}
};
public MyScreen() {
setTitle(myList.getKeywordField());
myList.setSourceList(myItems, new MyItem.MyProvider());
myItems.doAdd(new MyItem(1, "Eins"));
myItems.doAdd(new MyItem(2, "Zwei"));
myItems.doAdd(new MyItem(3, "Drei"));
myItems.doAdd(new MyItem(4, "Vier"));
myList.setSourceList(myItems, new MyItem.MyProvider());
myList.setCallback(new MyListFieldCallback());
myList.setSize(myItems.size() + EXTRA_ROWS);
myList.updateList();
add(myList);
}
private class MyListFieldCallback implements ListFieldCallback {
public void drawListRow(ListField list, Graphics g, int index, int y, int width) {
if (index < EXTRA_ROWS) {
Font i = getFont().derive(Font.ITALIC);
g.setFont(i);
g.drawText("Add Item", 0, y);
return;
}
if (index >= EXTRA_ROWS) {
MyItem item = (MyItem) ((KeywordFilterField) list).getElementAt(index - EXTRA_ROWS);
g.drawText(item.toString(), 0, y);
return;
}
g.drawText(list.getEmptyString(), 0, y);
}
public Object get(ListField listField, int index) {
return null;
}
public int getPreferredWidth(ListField listField) {
return 0;
}
public int indexOfList(ListField listField, String prefix, int start) {
return 0;
}
}
}
class MyItemList extends SortedReadableList {
public MyItemList() {
super(new MyItem.MyComparator());
}
protected void doAdd(Object obj) {
super.doAdd(obj);
}
protected boolean doRemove(Object obj) {
return super.doRemove(obj);
}
}
class MyItem {
int _num;
String _name;
public MyItem(int num, String name) {
_num = num;
_name = name;
}
public String toString() {
return _num + ": " + _name;
}
static class MyComparator implements Comparator {
public int compare(Object obj1, Object obj2) {
MyItem item1 = (MyItem) obj1;
MyItem item2 = (MyItem) obj2;
return item1.toString().compareTo(item2.toString());
}
}
static class MyProvider implements KeywordProvider {
public String[] getKeywords(Object obj) {
MyItem item = (MyItem) obj;
return new String[]{ Integer.toString(item._num), item._name };
}
}
}
我有一种感觉,setSize(4) (而不是 5)被称为中间 - 因为我看到最后一行一会儿,然后它再次消失。
谢谢你! 亚历克斯
I'm trying to display an extra row at the top of a ListField - called "Add Item" and it almost works, but the very last row "Item 4" of my data is not displayed.
How would you fix this issue?
Please see my very simple test code MyList.java below:
package mypackage;
import java.util.*;
import net.rim.device.api.collection.*;
import net.rim.device.api.collection.util.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.util.*;
public class MyList extends UiApplication {
public static void main(String args[]) {
MyList app = new MyList();
app.enterEventDispatcher();
}
public MyList() {
pushScreen(new MyScreen());
}
}
class MyScreen extends MainScreen {
ObjectListField myList = new ObjectListField() {
public void drawListRow(ListField list,
Graphics g,
int index,
int y,
int width) {
if (index == 0) {
Font i = getFont().derive(Font.ITALIC);
g.setFont(i);
g.drawText("Add Item", 0, y);
} else {
String str = (String) get(this, index - 1);
g.drawText(str, 0, y);
}
}
protected boolean navigationClick(int status, int time) {
int index = myList.getSelectedIndex();
String str = (index > 0 ? (String) get(this, index - 1) :
"Add item");
Status.show("You have clicked: " + str);
return true;
}
};
public MyScreen() {
setTitle("How to display an extra row?");
myList.set(new String[]{"Item 1","Item 2","Item 3","Item 4",});
// myList.setSize(5);
add(myList);
}
}
I've tried adding myList.setSize(5); but get an ArrayIndexOutOfBoundsException thrown by Vector.elementAt(4)
UPDATE:
On Michael's suggestion I've switched from ObjectListField to KeywordFilterField (which is what I actually use in my real program) and now I can call myList.setSize(5) without any exception being thrown.
But the last row is still not displayed:
package mypackage;
import java.util.*;
import net.rim.device.api.collection.*;
import net.rim.device.api.collection.util.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.util.*;
public class MyList extends UiApplication {
public static void main(String args[]) {
MyList app = new MyList();
app.enterEventDispatcher();
}
public MyList() {
pushScreen(new MyScreen());
}
}
class MyScreen extends MainScreen {
static final int EXTRA_ROWS = 1;
MyItemList myItems = new MyItemList();
KeywordFilterField myList = new KeywordFilterField() {
protected boolean navigationClick(int status, int time) {
int index = getSelectedIndex();
String str = (index < EXTRA_ROWS ? "Add item" :
((MyItem) getElementAt(index - EXTRA_ROWS)).toString());
Status.show("You have clicked - " + str);
return true;
}
};
public MyScreen() {
setTitle(myList.getKeywordField());
myList.setSourceList(myItems, new MyItem.MyProvider());
myItems.doAdd(new MyItem(1, "Eins"));
myItems.doAdd(new MyItem(2, "Zwei"));
myItems.doAdd(new MyItem(3, "Drei"));
myItems.doAdd(new MyItem(4, "Vier"));
myList.setSourceList(myItems, new MyItem.MyProvider());
myList.setCallback(new MyListFieldCallback());
myList.setSize(myItems.size() + EXTRA_ROWS);
myList.updateList();
add(myList);
}
private class MyListFieldCallback implements ListFieldCallback {
public void drawListRow(ListField list, Graphics g, int index, int y, int width) {
if (index < EXTRA_ROWS) {
Font i = getFont().derive(Font.ITALIC);
g.setFont(i);
g.drawText("Add Item", 0, y);
return;
}
if (index >= EXTRA_ROWS) {
MyItem item = (MyItem) ((KeywordFilterField) list).getElementAt(index - EXTRA_ROWS);
g.drawText(item.toString(), 0, y);
return;
}
g.drawText(list.getEmptyString(), 0, y);
}
public Object get(ListField listField, int index) {
return null;
}
public int getPreferredWidth(ListField listField) {
return 0;
}
public int indexOfList(ListField listField, String prefix, int start) {
return 0;
}
}
}
class MyItemList extends SortedReadableList {
public MyItemList() {
super(new MyItem.MyComparator());
}
protected void doAdd(Object obj) {
super.doAdd(obj);
}
protected boolean doRemove(Object obj) {
return super.doRemove(obj);
}
}
class MyItem {
int _num;
String _name;
public MyItem(int num, String name) {
_num = num;
_name = name;
}
public String toString() {
return _num + ": " + _name;
}
static class MyComparator implements Comparator {
public int compare(Object obj1, Object obj2) {
MyItem item1 = (MyItem) obj1;
MyItem item2 = (MyItem) obj2;
return item1.toString().compareTo(item2.toString());
}
}
static class MyProvider implements KeywordProvider {
public String[] getKeywords(Object obj) {
MyItem item = (MyItem) obj;
return new String[]{ Integer.toString(item._num), item._name };
}
}
}
I have a feeling, that setSize(4) (instead of 5) is called inbetween - because I see the last row for a moment and then it disappears again.
Thank you!
Alex
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您不想使用 ObjectListField,请在类型层次结构中上一级到 ListField,然后你可以随意执行 setSize() 。
You don't want to use an ObjectListField, go up one level in the type hierarchy to ListField, and then you can do setSize() as you please.
我想这应该有用:
或者我错过了什么? :)
I guess this should work:
Or am I missing smth? :)
这是我自己的解决方案 - 覆盖 ListField 的 setSize():
(上面的屏幕截图有 EXTRA_ROWS = 3,仍然可以正常工作)。
Here is my own solution - override the setSize() of the ListField:
(the screenshot above has EXTRA_ROWS = 3, which still works ok).