Отображение дополнительных строк в ListField - PullRequest
0 голосов
/ 09 мая 2011

Я пытаюсь отобразить дополнительную строку в верхней части ListField, которая называется «Добавить элемент», и она почти работает, но самая последняя строка «Элемент 4» моих данных не отображается.

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); , но получить исключение ArrayIndexOutOfBoundsException, выданное Vector.elementAt (4)

ОБНОВЛЕНИЕ:

По предложению Майкла я переключился с 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)называется inbetween - потому что я на мгновение вижу последний ряд, а потом он снова исчезает.

Спасибо!Alex

Ответы [ 3 ]

1 голос
/ 09 мая 2011

Вы не хотите использовать ObjectListField, поднимитесь на один уровень в иерархии типов до ListField , а затем вы можете выполнить setSize (), как вам будет угодно.

0 голосов
/ 10 мая 2011

Вот мое собственное решение - переопределить setSize () ListField:

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 голосов
/ 09 мая 2011

Полагаю, это должно сработать:

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

Или я что-то упустил?:)

...