2011-05-09 82 views
0

我想在ListField的頂部顯示一個額外的行 - 名爲「Add Item」,它幾乎可以工作,但是我的數據的最後一行「Item 4」沒有顯示。在ListField中顯示額外的行

Screenshot, 1 row is missing

你會如何解決這個問題?

請參閱我非常簡單的測試代碼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拋出一個ArrayIndexOutOfBoundsException(4)

UPDATE:

在邁克爾的建議,我已經從ObjectListField切換到KeywordFilterField(這是我在實際的程序中實際使用的),現在我可以撥打myList.setSize(5),不會引發任何異常。

但仍未顯示最後一行:

screenshot

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)被稱爲其間的 - 因爲我看到了最後一排,然後再次消失。

謝謝! 亞歷

+0

我也學到了艱辛的方式KeywordFilterField.setKeyword(空)比setKeyword(「」) – 2011-05-11 16:56:02

回答

0

這是我自己的解決方案 - 覆蓋ListField定義的setSize():

enter image description here

(上面的截圖中有EXTRA_ROWS = 3,這仍然工程確定)。

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 = 3; 

    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 void setSize(int count) { 
      super.setSize(count + EXTRA_ROWS); 
     } 
    }; 

    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()); 
     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 }; 
     } 
    } 
} 
0

我想這應該工作:

public MyScreen() { 
    setTitle("How to display an extra row?"); 
    myList.set(new String[] { "Add Item", "Item 1","Item 2","Item 3","Item 4"}); 
    add(myList); 
} 

還是我失去了不便? :)

+0

不幸的是,對我不好的更好的解決方案 - 因爲在我的真正的程序(相對於簡單的測試用例以上)我使用KeywordFilterField顯示一些對象(不是字符串)的SortedReadableList。如果我將「添加項」添加到該SortedReadableList,我將遇到問題,將它作爲第一行排序在我的KeywordFilterField中。所以我希望有另一種解決方案... – 2011-05-09 15:32:48

+0

所以也許這只是一個實施排序的問題,所以結果總是有「添加項目」的第一個地方? – 2011-05-09 17:51:16

1

你不想使用ObjectListField,在類型層次結構中上升一層到ListField,然後你可以隨心所欲地執行setSize()。

+0

我已經切換到KeywordFilterField,現在可以調用setSize(),但最後一行仍然丟失。我已經更新了我的測試用例 – 2011-05-10 12:25:43

+0

ListField不是抽象的。我建議你直接使用它。 – 2011-05-10 17:39:04

相關問題