2011-04-15 31 views
3

我準備了一個簡單的測試用例來演示我的問題。黑莓:更改KeywordFilterField的排序

它只是1個文件(CheckMenu.java,下面列出),並可立即運行。

一旦用戶通過選擇2個MenuItems中的一個來更改排序方法,我該如何重新繪製底層的KeywordFilterField?我試過呼叫myList.updateList()myList.invalidate() - 它沒有幫助 - myList項目不重組。

另外我想知道,使用什麼來代替棄用的MenuItem.setText(String)?

enter image description here

package mypackage; 

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.util.Comparator; 
import net.rim.device.api.util.StringUtilities; 
import net.rim.device.api.collection.util.*; 

public class CheckMenu extends UiApplication { 
    public static void main(String[] args) { 
     CheckMenu myApp = new CheckMenu();  
     myApp.enterEventDispatcher(); 
    } 

    public CheckMenu() {   
     pushScreen(new MyScreen()); 
    }  
} 

class MyScreen extends MainScreen { 
    KeywordFilterField myList = new KeywordFilterField(); 
    MyItemList myItems = new MyItemList(); 

    public MyScreen() { 
     setTitle(myList.getKeywordField()); 

     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()); 
     // XXX commenting the line below does not help 
     myList.setCallback(new MyListFieldCallback()); 
     add(myList); 
    } 

    private MenuItem numMenu = new MenuItem("num sort", 0, 0) { 
     public void run() { 
      MyItem.NUMERIC_SORT = true; 
      Status.show("Use " + toString()); 
      setText("num sort \u221A"); 
      alphaMenu.setText("alpha sort"); 
      myList.updateList(); 
     } 
    }; 
    private MenuItem alphaMenu = new MenuItem("alpha sort", 1, 0) { 
     public void run() { 
      MyItem.NUMERIC_SORT = false; 
      Status.show("Use " + toString()); 
      setText("alpha sort \u221A"); 
      numMenu.setText("num sort"); 
      myList.updateList(); 
     } 
    }; 

    protected void makeMenu(Menu menu, int instance) { 
     super.makeMenu(menu, instance); 
     menu.add(numMenu); 
     menu.add(alphaMenu); 
    } 

    private class MyListFieldCallback implements ListFieldCallback { 

     public void drawListRow(ListField list, Graphics g, int index, int y, int width) { 
      Object obj = ((KeywordFilterField)list).getElementAt(index); 
      if(obj != null && obj instanceof MyItem) { 
       MyItem item = (MyItem) obj; 
       g.drawText(item.toString(), 20 * (1 + index), y); 
      } else if(index == 0) { 
       g.drawText(list.getEmptyString(), 0, y); 
      } 
     } 

     public Object get(ListField list, int index) { 
      return null; 
     } 

     public int getPreferredWidth(ListField list) { 
      return 0; 
     } 

     public int indexOfList(ListField list, 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 { 
    public static boolean NUMERIC_SORT; 

    private int _num; 
    private 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) { 
      if (! (obj1 instanceof MyItem && obj2 instanceof MyItem)) 
       throw new IllegalArgumentException("Cannot compare non-MyItems"); 

      MyItem item1 = (MyItem) obj1; 
      MyItem item2 = (MyItem) obj2; 

      if (MyItem.NUMERIC_SORT) { 
       if (item1._num == item2._num) 
        return 0; 
       return (item1._num > item2._num ? 1 : -1); 
      } 

      return item1._name.compareTo(item2._name); 
     } 
    } 

    static class MyProvider implements KeywordProvider { 
     public String[] getKeywords(Object obj) { 
      if (obj instanceof MyItem) { 
       MyItem item = (MyItem) obj; 
       return new String[]{ Integer.toString(item._num), item._name }; 
      } 
      return null; 
     } 
    } 
} 

更新:我已經更新了代碼,使用列出MakeMenu()由Arhimed的建議。 我也發佈了我的問題at the BlackBerry forum

謝謝! Alex

+0

+1對於完美結構化/準備好的問題。 – 2011-04-15 19:48:13

回答

1

也許我不明白你的問題.....但正如我所看到的,此代碼在模擬器上工作正常

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.util.Comparator; 
import net.rim.device.api.util.StringUtilities; 
import net.rim.device.api.collection.util.*; 

public class CheckMenu extends UiApplication { 
    public static void main(String[] args) { 
     CheckMenu myApp = new CheckMenu();  
     myApp.enterEventDispatcher(); 
    } 

    public CheckMenu() {   
     pushScreen(new MyScreen()); 
    }  
} 

class MyScreen extends MainScreen { 
    KeywordFilterField myList = new KeywordFilterField(); 
    MyItemList myItems = new MyItemList(); 

    public MyScreen() { 
     setTitle(myList.getKeywordField()); 

     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()); 
     // XXX commenting the line below does not help 
     myList.setCallback(new MyListFieldCallback()); 
     add(myList); 
    } 

    private MenuItem numMenu = new MenuItem("num sort", 0, 0) { 
    public void run() { 
     MyItem.NUMERIC_SORT = true; 
     Status.show("Use " + toString()); 
     setText("num sort \u221A"); 
     alphaMenu.setText("alpha sort"); 
     myItems.sort(); 
     myList.updateList(); 
    } 
}; 
private MenuItem alphaMenu = new MenuItem("alpha sort", 1, 0) { 
    public void run() { 
     MyItem.NUMERIC_SORT = false; 
     Status.show("Use " + toString()); 
     setText("alpha sort \u221A"); 
     numMenu.setText("num sort"); 
     myItems.sort(); 
     myList.updateList(); 
    } 
}; 

protected void makeMenu(Menu menu, int instance) { 
    super.makeMenu(menu, instance); 
    menu.add(numMenu); 
    menu.add(alphaMenu); 
} 

private class MyListFieldCallback implements ListFieldCallback { 

    public void drawListRow(ListField listField, Graphics g, int index, int y, int width) { 
     Object obj = ((KeywordFilterField)listField).getElementAt(index); 
     if(obj != null && obj instanceof MyItem) { 
      MyItem item = (MyItem) obj; 
      g.drawText(item.toString(), 20 * (1 + index), y); 
     } else if(index == 0) { 
      g.drawText("ssssssss", 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 { 
    public static boolean NUMERIC_SORT; 

    private int _num; 
    private 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) { 
      if (! (obj1 instanceof MyItem && obj2 instanceof MyItem)) 
       throw new IllegalArgumentException("Cannot compare non-MyItems"); 

      MyItem item1 = (MyItem) obj1; 
      MyItem item2 = (MyItem) obj2; 

      if (MyItem.NUMERIC_SORT) { 
       if (item1._num == item2._num) 
        return 0; 
       return (item1._num > item2._num ? 1 : -1); 
      } 

      return item1._name.compareTo(item2._name); 
     } 
    } 

    static class MyProvider implements KeywordProvider { 
     public String[] getKeywords(Object obj) { 
      if (obj instanceof MyItem) { 
       MyItem item = (MyItem) obj; 
       return new String[]{ Integer.toString(item._num), item._name }; 
      } 
     return null; 
    } 
} 
} 
+0

當您在菜單中更改字母排序數字<->時 - ListField應該按不同順序顯示4行 – 2011-04-19 15:19:26

+0

是的。當我在菜單中更改字母排序數字<-> - ListField按不同順序顯示4行。我只是添加myItems.sort();到你的代碼。 – oxigen 2011-04-19 15:23:32

+0

的確,這是我的問題的解決方案(對不起,最初錯過了你的加入)!對於我來說,看起來更自然,而不是像Arhimed那樣重新分配比較器。 – 2011-04-19 15:38:41

0

1)。我如何修改MenuItem文本?我想 喜歡顯示/隱藏複選標記 符號\ u221A - 取決於哪個 排序順序目前是由 用戶選擇的。 setText(String text) 方法已棄用,我不確定 如何使用setText(StringProvider text)?

代替使用addMenuItem(myMenu1);倍率makeMenu(Menu menu, int instance)的:

protected void makeMenu(Menu menu, int instance) { 
    super.makeMenu(menu, instance); 

    // add menu items on-the-fly 
    // generating their labels in accordance to some conditions 
    menu.add(new MenuItem("any label", 1, 1) { 
     public void run() { 
      // do smth useful 
     } 
    }); 
} 

2)。一旦用戶通過選擇菜單項中的一個來更改排序方法,我如何重新繪製 底層的KeywordFilterField?我已經嘗試調用myList.updateList()和 myList.invalidate() - 它沒有幫助。

嘗試註釋掉myList.setCallback(new MyListFieldCallback());線。我相信KeywordFilterField已經以某種特定方式實現了此回調,因此通過設置自定義ListFieldCallback可以打破默認/預期行爲。

UPDATE關於菜單項:

完全擺脫private MenuItem alphaMenuprivate MenuItem numMenu領域。在運行中生成這些菜單項:在重大問題

protected void makeMenu(Menu menu, int instance) { 
    super.makeMenu(menu, instance); 

    String label = "num sort" + (MyItem.NUMERIC_SORT ? " \u221A" : ""); 

    menu.add(new MenuItem(label, 0, 0) { 
     public void run() { 
      MyItem.NUMERIC_SORT = true; 
      Status.show("Use " + toString()); 
      // setText("num sort \u221A"); 
      // alphaMenu.setText("alpha sort"); 
      myList.updateList(); 
     } 
    }); 

    label = "alpha sort" + (MyItem.NUMERIC_SORT ? "" : " \u221A"); 

    menu.add(new MenuItem(label, 1, 0) { 
     public void run() { 
      MyItem.NUMERIC_SORT = false; 
      Status.show("Use " + toString()); 
      // setText("alpha sort \u221A"); 
      // numMenu.setText("num sort"); 
      myList.updateList(); 
     } 
    }); 
} 

UPDATE

class MyScreen extends MainScreen { 
    KeywordFilterField myList = new KeywordFilterField(); 
    MyItemList myItems = new MyItemList(); 

    public MyScreen() { 
     setTitle(myList.getKeywordField()); 

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

     // XXX commenting the line below does not help 
     myList.setCallback(new MyListFieldCallback()); 
     add(myList); 
    } 

    protected void makeMenu(Menu menu, int instance) { 
     super.makeMenu(menu, instance); 

     String label = "num sort" + (MyItem.NUMERIC_SORT ? " \u221A" : ""); 

     menu.add(new MenuItem(label, 0, 0) { 
      public void run() { 
       MyItem.NUMERIC_SORT = true; 
       Status.show("Use " + toString()); 
       // setText("num sort \u221A"); 
       // alphaMenu.setText("alpha sort"); 

       myItems.setComparator(new MyItem.MyComparator()); 
       myList.updateList(); 
      } 
     }); 

     label = "alpha sort" + (MyItem.NUMERIC_SORT ? "" : " \u221A"); 

     menu.add(new MenuItem(label, 1, 0) { 
      public void run() { 
       MyItem.NUMERIC_SORT = false; 
       Status.show("Use " + toString()); 
       // setText("alpha sort \u221A"); 
       // numMenu.setText("num sort"); 

       myItems.setComparator(new MyItem.MyComparator()); 
       myList.updateList(); 
      } 
     }); 

    } 

// .. the rest of the code is the same 
+0

1)謝謝,但如何從addMenuItem更改爲makeMenu幫助我在運行時更改菜單文本? – 2011-04-15 20:20:02

+0

使你的菜單文本變量,並通過條件改變它們,makeMenu()是一個動態的方法,它只發生在菜單被請求時 – Dan 2011-04-16 16:08:35

+0

是的,我的意思是根本不使用'addMenuItem'。改爲使用'makeMenu',每次用戶按下設備上的菜單按鈕時都會調用它。 – 2011-04-17 18:45:10