BlackBerry - How to create sub menu?

2020-03-06 17:06发布

问题:

i want to create sub menu for a BB application when i click on menu item it shows

Option 1
Option 2
Option 3

When i click on option 3 it should display

1
2
3

as sub menu items..

using j2me + eclipse

回答1:

Always wanted to do this )
alt text http://img380.imageshack.us/img380/3874/menugy.jpg

class Scr extends MainScreen {
    SubMenu menu = new SubMenu();

    public Scr() {

        for (int i = 0; i < 3; i++) {
            SubMenu sMenu = new SubMenu();
            menu.add(new SubMenuItem(i + " item", sMenu));
            for (int k = 0; k < 3; k++) {
                SubMenu sSMenu = new SubMenu();
                sMenu.add(new SubMenuItem(i + "-" + k + " item", sSMenu));
                for (int l = 0; l < 3; l++) {
                    sSMenu
                            .add(new SubMenuItem(i + "-" + k + "-" + l
                                    + " item"));
                }
            }
        }

        add(new LabelField("testing menu", FOCUSABLE) {
            protected void makeContextMenu(ContextMenu contextMenu) {
                menu.mRectangle.x = this.getContentRect().X2();
                menu.mRectangle.y = this.getContentRect().Y2();
                Ui.getUiEngine().pushScreen(menu);

                EventInjector.invokeEvent(new KeyEvent(KeyEvent.KEY_DOWN,
                        Characters.ESCAPE, 0));
            }
        });
    }
}

class SubMenu extends PopupScreen implements ListFieldCallback {
    private static final int MAX_WIDTH = Font.getDefault().getAdvance(
            "max menu item text");
    XYRect mRectangle = new XYRect();
    Vector mSubMenuItems = new Vector();
    ListField mListField;

    public SubMenu() {
        super(new SubMenuItemManager(), DEFAULT_CLOSE);
        int rowHeight = getFont().getHeight() + 2;
        mListField = new ListField() {
            protected boolean navigationClick(int status, int time) {
                runMenuItem(getSelectedIndex());
                return super.navigationClick(status, time);
            }
        };
        mListField.setRowHeight(rowHeight);
        add(mListField);
        mListField.setCallback(this);
        updateMenuItems();
    }

    public void add(SubMenuItem subMenuItem) {
        mSubMenuItems.addElement(subMenuItem);
        subMenuItem.mMenu = this;
        updateMenuItems();
    }

    private void updateMenuItems() {
        int rowCounts = mSubMenuItems.size();
        mRectangle.width = getMaxObjectToStringWidth(mSubMenuItems);
        mRectangle.height = mListField.getRowHeight() * rowCounts;
        mListField.setSize(rowCounts);
    }

    private void runMenuItem(int index) {
        SubMenuItem item = (SubMenuItem) get(mListField, index);
        if (null != item.mSubMenu) {
            item.mSubMenu.setSubMenuPosition(getSubMenuRect(index));
            Ui.getUiEngine().pushScreen(item.mSubMenu);
        } else {
            item.run();
        }
    }

    private XYRect getSubMenuRect(int index) {
        SubMenuItem item = (SubMenuItem) get(mListField, index);
        XYRect result = item.mSubMenu.mRectangle;
        result.x = mRectangle.x + mRectangle.width;
        result.y = mRectangle.y + mListField.getRowHeight() * index;
        int testWidth = Display.getWidth() - (mRectangle.width + mRectangle.x);
        if (testWidth < result.width) {
            result.width = testWidth;
        }

        int testHeight = Display.getHeight()
                - (mRectangle.height + mRectangle.y);
        if (testHeight < result.height)
            result.height = testHeight;

        return result;
    }

    public void setSubMenuPosition(XYRect rect) {
        mRectangle = rect;
    }

    protected void sublayout(int width, int height) {
        super.sublayout(mRectangle.width, mRectangle.height);
        setPosition(mRectangle.x, mRectangle.y);
        setExtent(mRectangle.width, mRectangle.height);
    }

    private int getMaxObjectToStringWidth(Vector objects) {
        int result = 0;
        for (int i = 0; i < objects.size(); i++) {
            int width = getFont().getAdvance(objects.elementAt(i).toString());
            if (width > result) {
                if (width > MAX_WIDTH) {
                    result = MAX_WIDTH;
                    break;
                } else {
                    result = width;
                }
            }
        }
        return result;
    }

    public void drawListRow(ListField field, Graphics g, int i, int y, int w) {
        // Draw the text.
        String text = get(field, i).toString();
        g.setColor(Color.WHITE);
        g.drawText(text, 0, y, DrawStyle.ELLIPSIS, w);
    }

    public Object get(ListField listField, int index) {
        return mSubMenuItems.elementAt(index);
    }

    public int getPreferredWidth(ListField listField) {
        return mRectangle.width;
    }

    public int indexOfList(ListField listField, String prefix, int start) {
        return 0;
    }
}

class SubMenuItemManager extends VerticalFieldManager {
    public SubMenuItemManager() {
        super(USE_ALL_HEIGHT | USE_ALL_WIDTH);
    }

    public int getPreferredWidth() {
        return ((SubMenu) getScreen()).mRectangle.width;
    }

    public int getPreferredHeight() {
        return ((SubMenu) getScreen()).mRectangle.height;
    }

    protected void sublayout(int maxWidth, int maxHeight) {
        maxWidth = getPreferredWidth();
        maxHeight = getPreferredHeight();
        super.sublayout(maxWidth, maxHeight);
        setExtent(maxWidth, maxHeight);
    }

}

class SubMenuItem implements Runnable {
    String mName;
    SubMenu mMenu;
    SubMenu mSubMenu;

    public SubMenuItem(String name) {
        this(name, null);
    }

    public SubMenuItem(String name, SubMenu subMenu) {
        mName = name;
        mSubMenu = subMenu;
    }

    public String toString() {
        return mName;
    }

    public void run() {

    }
}


回答2:

Submenus are not part of the standard BlackBerry API. If you want to do this, you'll have to make your own custom menu+submenu control.