]> source.dussan.org Git - vaadin-framework.git/commitdiff
Copied the new MenuBar component from Incubator to Trunk. Fixes #1852.
authorMarko Grönroos <magi@iki.fi>
Thu, 26 Jun 2008 13:29:27 +0000 (13:29 +0000)
committerMarko Grönroos <magi@iki.fi>
Thu, 26 Jun 2008 13:29:27 +0000 (13:29 +0000)
svn changeset:4955/svn branch:trunk

WebContent/ITMILL/themes/default/styles.css
src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IMenuBar.java [new file with mode: 0644]
src/com/itmill/toolkit/tests/tickets/Ticket1598.java [new file with mode: 0644]
src/com/itmill/toolkit/ui/MenuBar.java [new file with mode: 0644]

index a8005c02e64654235f406c38156e7d825ff4d3c6..e3e43cde7afc0c5b3c9d3a3e6e6299ea4e5fcc95 100644 (file)
@@ -602,6 +602,64 @@ input.i-modified,
 .i-gridlayout-spacing .i-gridlayout-firstrow {
        padding-top: 0;
 }
+/*Set the style for the menu bar itself */
+.i-menubar table{
+    border-right: 2px solid #c6cbcc;
+       border-bottom: 2px solid #c6cbcc;
+       border-top: 1px solid #d0d4d5;
+       border-left: 1px solid #d0d4d5;
+       
+       padding 3px;
+}
+
+/*Set the style for the main menu menu items */
+.i-menubar .gwt-MenuItem {
+    cursor                      :   hand;
+    cursor                      :   pointer;
+       
+       padding : 1px 10px;
+       margin : 1px 10px;      
+       }
+
+/*Set the style for the selected main menu menu item */
+.i-menubar .gwt-MenuItem-selected {
+                background-color            :   #fff;
+       }
+
+
+/*Set the style for the submenus */
+.gwt-MenuBar { 
+    font-size                   :   12px;
+    padding                     :   3px;
+    font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;
+    color: #464f52;
+    
+    border-right: 2px solid #c6cbcc;
+       border-bottom: 2px solid #c6cbcc;
+       border-top: 1px solid #d0d4d5;
+       border-left: 1px solid #d0d4d5;
+}
+
+/*Set style for the submenu menu items */
+.gwt-MenuBar .gwt-MenuItem { 
+    cursor                      :   hand;
+    cursor                      :   pointer;
+
+    //border                      :   1px solid #999;
+    //background-color            :   #eee;
+    padding                     :   2px 10px;
+}
+
+/*Set style for the selected submenu item */
+.gwt-MenuBar .gwt-MenuItem-selected { 
+        background-color            :   #fff;
+}
+
+.gwt-MenuItem p{
+       padding : 0;
+       margin : 0;
+       line-height : normal;
+ }
 
 .i-Notification {
        font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;
index d43c26d6b1877586dbc88d1c8af364432227e5a2..227becbe7cea8859f0c08c4badc4fb20b3049c5c 100644 (file)
@@ -25,6 +25,7 @@ import com.itmill.toolkit.terminal.gwt.client.ui.IHorizontalExpandLayout;
 import com.itmill.toolkit.terminal.gwt.client.ui.ILabel;
 import com.itmill.toolkit.terminal.gwt.client.ui.ILink;
 import com.itmill.toolkit.terminal.gwt.client.ui.IListSelect;
+import com.itmill.toolkit.terminal.gwt.client.ui.IMenuBar;
 import com.itmill.toolkit.terminal.gwt.client.ui.INativeSelect;
 import com.itmill.toolkit.terminal.gwt.client.ui.IOptionGroup;
 import com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayoutHorizontal;
@@ -190,6 +191,9 @@ public class DefaultWidgetSet implements WidgetSet {
         } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IAccordion"
                 .equals(className)) {
             return new IAccordion();
+        } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IMenuBar"
+                .equals(className)) {
+            return new IMenuBar();
         }
 
         return new IUnknownComponent();
@@ -320,6 +324,8 @@ public class DefaultWidgetSet implements WidgetSet {
             } else {
                 return "com.itmill.toolkit.terminal.gwt.client.ui.IExpandLayout";
             }
+        } else if ("menubar".equals(tag)) {
+            return "com.itmill.toolkit.terminal.gwt.client.ui.IMenuBar";
         }
 
         return "com.itmill.toolkit.terminal.gwt.client.ui.IUnknownComponent";
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IMenuBar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IMenuBar.java
new file mode 100644 (file)
index 0000000..58d6f6f
--- /dev/null
@@ -0,0 +1,152 @@
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+import java.util.Stack;
+
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.MenuItem;
+import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IMenuBar extends MenuBar implements Paintable {
+
+    /** Set the CSS class name to allow styling. */
+    public static final String CLASSNAME = "i-menubar";
+
+    /** Component identifier in UIDL communications. */
+    protected String uidlId;
+
+    /** Reference to the server connection object. */
+    protected ApplicationConnection client;
+
+    /** A host reference for the Command objects */
+    protected final IMenuBar hostReference = this;
+
+    /**
+     * The constructor should first call super() to initialize the component and
+     * then handle any initialization relevant to IT Mill Toolkit.
+     */
+    public IMenuBar() {
+        // The superclass has a lot of relevant initialization
+        super();
+
+        // This method call of the Paintable interface sets the component
+        // style name in DOM tree
+        setStyleName(CLASSNAME);
+    }
+
+    /**
+     * This method must be implemented to update the client-side component from
+     * UIDL data received from server.
+     * 
+     * This method is called when the page is loaded for the first time, and
+     * every time UI changes in the component are received from the server.
+     */
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+        // This call should be made first. Ensure correct implementation,
+        // and let the containing layout manage caption, etc.
+        if (client.updateComponent(this, uidl, true)) {
+            return;
+        }
+
+        // Save reference to server connection object to be able to send
+        // user interaction later
+        this.client = client;
+
+        // Save the UIDL identifier for the component
+        uidlId = uidl.getId();
+
+        // Empty the menu every time it receives new information
+        if (!this.getItems().isEmpty()) {
+            this.clearItems();
+        }
+
+        /* Get tree received from server and actualize it in the GWT-MenuBar */
+
+        // For GWT 1.5
+        // this.setAnimationEnabled(uidl.getBooleanAttribute("animationEnabled"));
+        UIDL items = uidl.getChildUIDL(1);
+        Iterator itr = items.getChildIterator();
+        Stack iteratorStack = new Stack();
+        Stack menuStack = new Stack();
+        MenuBar currentMenu = this;
+
+        // Construct an empty command to be used when the item has no command
+        // associated
+        Command emptyCommand = new Command() {
+            public void execute() {
+            }
+        };
+
+        while (itr.hasNext()) {
+            UIDL item = (UIDL) itr.next();
+            MenuItem menuItem = null; // For receiving the item
+
+            String itemText = item.getStringAttribute("text");
+            final int itemId = item.getIntAttribute("id");
+
+            boolean itemHasCommand = item.getBooleanAttribute("command");
+
+            // Construct html from the text and the optional icon
+            if (!item.hasAttribute("icon")) {
+                itemText = "<p>" + itemText + "</p>";
+            } else {
+                itemText = "<p>"
+                        + "<img src=\""
+                        + client.translateToolkitUri(item
+                                .getStringAttribute("icon")) + "\"</img>"
+                        + itemText + "</p>";
+            }
+
+            // Check if we need to attach a command to this item
+            if (itemHasCommand) {
+                // Construct a command that fires onMenuClick(int) with the
+                // item's id-number
+                Command normalCommand = new Command() {
+                    public void execute() {
+                        hostReference.onMenuClick(itemId);
+                    }
+                };
+
+                menuItem = currentMenu.addItem(itemText, true, normalCommand);
+
+            } else {
+                menuItem = currentMenu.addItem(itemText, true, emptyCommand);
+            }
+
+            if (item.getChildCount() > 0) {
+                menuStack.push(currentMenu);
+                iteratorStack.push(itr);
+                itr = item.getChildIterator();
+                currentMenu = new MenuBar(true);
+                menuItem.setSubMenu(currentMenu);
+            }
+
+            if (!itr.hasNext() && !iteratorStack.empty()) {
+                itr = (Iterator) iteratorStack.pop();
+                currentMenu = (MenuBar) menuStack.pop();
+            }
+        }// while
+
+    }// updateFromUIDL
+
+    /**
+     * This is called by the items in the menu and it communicates the
+     * information to the server
+     * 
+     * @param clickedItemId
+     *                id of the item that was clicked
+     */
+    public void onMenuClick(int clickedItemId) {
+        // Updating the state to the server can not be done before
+        // the server connection is known, i.e., before updateFromUIDL()
+        // has been called.
+        if (uidlId != null && client != null) {
+            // Communicate the user interaction parameters to server. This call
+            // will initiate an AJAX request to the server.
+            client.updateVariable(uidlId, "clickedId", clickedItemId, true);
+        }
+    }
+}// class IMenuBar
diff --git a/src/com/itmill/toolkit/tests/tickets/Ticket1598.java b/src/com/itmill/toolkit/tests/tickets/Ticket1598.java
new file mode 100644 (file)
index 0000000..90ecadb
--- /dev/null
@@ -0,0 +1,110 @@
+package com.itmill.toolkit.tests.tickets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.itmill.toolkit.Application;
+import com.itmill.toolkit.terminal.ThemeResource;
+import com.itmill.toolkit.ui.MenuBar;
+import com.itmill.toolkit.ui.Window;
+import com.itmill.toolkit.ui.MenuBar.Command;
+import com.itmill.toolkit.ui.MenuBar.Item;
+
+public class Ticket1598 extends Application {
+
+    Window main = new Window("MenuBar test");
+
+    final MenuBar menuBar = new MenuBar();
+
+    public void init() {
+        setMainWindow(main);
+        setTheme("default");
+
+        List itemList = new ArrayList();
+        // Populate the menubar
+        for (int i = 0; i < 5; i++) {
+            itemList.add(menuBar.addItem(new String("Menu " + i), null, null));
+        }
+
+        Item first = (Item) itemList.get(0);
+
+        for (int i = 0; i < 5; i++) {
+            first.addItem(new String("Submenu item" + i), null, new Command() {
+
+                public void menuSelected(Item selected) {
+                    main.showNotification("Action " + selected.getText());
+                }
+            });
+        }
+
+        Item firstSecond = (Item) first.getChildren().get(1);
+
+        for (int i = 0; i < 3; i++) {
+            firstSecond.addItem(new String("Subsubmenu item" + i), null,
+                    new Command() {
+
+                        public void menuSelected(Item selected) {
+                            main.showNotification("Action "
+                                    + selected.getText());
+                        }
+                    });
+        }
+
+        Item second = (Item) menuBar.getItems().get(1);
+
+        for (int i = 0; i < 5; i++) {
+            second.addItem(new String("Second submenu item" + i), null,
+                    new Command() {
+
+                        public void menuSelected(Item selected) {
+                            main.showNotification("Action "
+                                    + selected.getText());
+                        }
+                    });
+        }
+
+        Item third = (Item) menuBar.getItems().get(2);
+        third.setIcon(new ThemeResource("icons/16/document.png"));
+
+        for (int i = 2; i <= 3; i++)
+            ((Item) menuBar.getItems().get(i)).setCommand(new Command() {
+
+                public void menuSelected(Item selectedItem) {
+                    main.showNotification("Action " + selectedItem.getText());
+                }
+            });
+
+        final Item fourth = (Item) menuBar.getItems().get(3);
+        fourth.setText("Toggle animation");
+
+        fourth.setCommand(new Command() {
+            public void menuSelected(Item selected) {
+                menuBar
+                        .addItemBefore("No animation yet...", null, null,
+                                fourth);
+                // menuBar.setAnimation(!menuBar.hasAnimation());
+            }
+        });
+
+        final Item last = (Item) menuBar.getItems().get(menuBar.getSize() - 1);
+        last.setText("Remove me!");
+
+        // A command for removing the selected menuitem
+        Command removeCommand = new Command() {
+
+            public void menuSelected(Item selected) {
+                Item parent = selected.getParent();
+                if (parent != null) {
+                    parent.removeChild(selected);
+                } else {
+                    menuBar.removeItem(selected);
+                }
+            }
+        };
+
+        last.setCommand(removeCommand);
+
+        main.addComponent(menuBar);
+
+    }
+}
\ No newline at end of file
diff --git a/src/com/itmill/toolkit/ui/MenuBar.java b/src/com/itmill/toolkit/ui/MenuBar.java
new file mode 100644 (file)
index 0000000..da1d457
--- /dev/null
@@ -0,0 +1,511 @@
+package com.itmill.toolkit.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import com.itmill.toolkit.terminal.PaintException;
+import com.itmill.toolkit.terminal.PaintTarget;
+import com.itmill.toolkit.terminal.Resource;
+
+/**
+ * The top-level menu class. This can contain MenuItems, which in turn can
+ * contain Submenus and MenuCommands.
+ * 
+ */
+public class MenuBar extends AbstractComponent {
+
+    // Items of the top-level menu
+    private List menuItems;
+
+    // Number of items in this menu
+    private static int numberOfItems = 0;
+
+    private boolean animationEnabled;
+
+    /** Tag is the UIDL element name for client-server communications. */
+    public java.lang.String getTag() {
+        return "menubar";
+    }
+
+    /** Paint (serialize) the component for the client. */
+    public void paintContent(PaintTarget target) throws PaintException {
+
+        // Superclass writes any common attributes in the paint target.
+        super.paintContent(target);
+
+        // Stack for list iterators
+        Stack iteratorStack = new Stack();
+
+        target.startTag("options");
+        target.addAttribute("animationEnabled", animationEnabled);
+        target.endTag("options");
+        target.startTag("items");
+
+        Iterator itr = menuItems.iterator();
+
+        // This generates the tree from the contents of the menu
+        while (itr.hasNext()) {
+
+            Item item = (Item) itr.next();
+
+            target.startTag("item");
+
+            target.addAttribute("text", item.getText());
+            target.addAttribute("id", item.getId());
+
+            Command command = item.getCommand();
+            if (command != null) {
+                target.addAttribute("command", true);
+            } else {
+                target.addAttribute("command", false);
+            }
+
+            Resource icon = item.getIcon();
+            if (icon != null) {
+                target.addAttribute("icon", icon);
+            }
+
+            if (item.hasChildren()) {
+                iteratorStack.push(itr); // For later use
+
+                // Go through the children
+                itr = item.getChildren().iterator();
+            } else {
+                target.endTag("item"); // Item had no children, end description
+            }
+
+            if (!itr.hasNext() && !iteratorStack.empty()) { // The end submenu
+                itr = (Iterator) iteratorStack.pop();
+                target.endTag("item");
+            }
+
+        }
+
+        target.endTag("items");
+    }
+
+    /** Deserialize changes received from client. */
+    public void changeVariables(Object source, Map variables) {
+        Stack items = new Stack();
+        boolean found = false;
+
+        if (variables.containsKey("clickedId")) {
+
+            Integer clickedId = (Integer) variables.get("clickedId");
+            Iterator itr = this.getItems().iterator();
+            while (itr.hasNext()) {
+                items.push((Item) itr.next());
+            }
+
+            Item tmpItem = null;
+
+            // Go through all the items in the menu
+            while (!found && !items.empty()) {
+                tmpItem = (Item) items.pop();
+                found = (clickedId.intValue() == tmpItem.getId());
+
+                if (tmpItem.hasChildren()) {
+                    itr = tmpItem.getChildren().iterator();
+                    while (itr.hasNext()) {
+                        items.push(itr.next());
+                    }
+                }
+
+            }
+            // If we got the clicked item, launch the command.
+            if (found) {
+                tmpItem.getCommand().menuSelected(tmpItem);
+            }// while
+        }// if
+    }// changeVariables
+
+    /**
+     * Constructs an empty, horizontal menu
+     */
+    public MenuBar() {
+        menuItems = new ArrayList();
+        animationEnabled = false;
+    }
+
+    /**
+     * Add a new item to the menubar. Icon and command can be null, but a
+     * caption must be given.
+     * 
+     * @param caption
+     *                the text for the menu item
+     * @param icon
+     *                the icon for the menu item
+     * @param command
+     *                the command for the menu item
+     * @throws IllegalArgumentException
+     */
+    public MenuBar.Item addItem(String caption, Resource icon,
+            MenuBar.Command command) {
+        if (caption == null) {
+            throw new IllegalArgumentException("caption cannot be null");
+        }
+        Item newItem = new Item(caption, icon, command);
+        menuItems.add(newItem);
+        requestRepaint();
+
+        return newItem;
+
+    }
+
+    /**
+     * Add an item before some item. If the given item does not exist the item
+     * is added at the end of the menu. Icon and command can be null, but a
+     * caption must be given.
+     * 
+     * @param caption
+     *                the text for the menu item
+     * @param icon
+     *                the icon for the menu item
+     * @param command
+     *                the command for the menu item
+     * @param itemToAddBefore
+     *                the item that will be after the new item
+     * @throws IllegalArgumentException
+     */
+    public MenuBar.Item addItemBefore(String caption, Resource icon,
+            MenuBar.Command command, MenuBar.Item itemToAddBefore) {
+        if (caption == null) {
+            throw new IllegalArgumentException("caption cannot be null");
+        }
+
+        Item newItem = new Item(caption, icon, command);
+        if (menuItems.contains(itemToAddBefore)) {
+            int index = menuItems.indexOf(itemToAddBefore);
+            menuItems.add(index, newItem);
+
+        } else {
+            menuItems.add(newItem);
+        }
+
+        requestRepaint();
+
+        return newItem;
+    }
+
+    /**
+     * Returns a list with all the MenuItem objects in the menubar
+     * 
+     * @return a list containing the MenuItem objects in the menubar
+     */
+    public java.util.List getItems() {
+        return menuItems;
+    }
+
+    /**
+     * Remove first occurrence the specified item from the main menu
+     * 
+     * @param item
+     *                The item to be removed
+     */
+    public void removeItem(MenuBar.Item item) {
+        if (item != null) {
+            menuItems.remove(item);
+        }
+        requestRepaint();
+    }
+
+    /**
+     * Empty the menubar
+     */
+    public void removeItems() {
+        menuItems.clear();
+        requestRepaint();
+    }
+
+    /**
+     * Returns the size of the menu.
+     * 
+     * @return The size of the menu
+     */
+    public int getSize() {
+        return menuItems.size();
+    }
+
+    /**
+     * Enable or disable animated menubar appearance. Animation is disabled by
+     * default.
+     * 
+     * @param hasAnimation
+     */
+    public void setAnimation(boolean animation) {
+        animationEnabled = animation;
+    }
+
+    /**
+     * Returns true if the animation is enabled. Animation of this class is
+     * disabled by default.
+     * 
+     * @return true if the animation is enabled
+     * 
+     */
+    public boolean hasAnimation() {
+        return animationEnabled;
+    }
+
+    /**
+     * This interface contains the layer for menu commands of the MenuBar class .
+     * It's method will fire when the user clicks on the containing MenuItem.
+     * The selected item is given as an argument.
+     */
+    public interface Command {
+        public void menuSelected(MenuBar.Item selectedItem);
+    }
+
+    /**
+     * A composite class for menu items and submenus. You can set commands to be
+     * fired on user click by implementing the MenuBar.Command interface.
+     * 
+     */
+    public class Item {
+
+        /** Private members * */
+        private int itsId;
+        private Command itsCommand;
+        private String itsText;
+        private List itsChildren;
+        private Resource itsIcon;
+        private Item itsParent;
+
+        /**
+         * Constructs a new menu item that can optionally have an icon and a
+         * command associated with it. Icon and command can be null, but a
+         * caption must be given.
+         * 
+         * @param text
+         *                The text associated with the command
+         * @param command
+         *                The command to be fired
+         * @throws IllegalArgumentException
+         */
+        public Item(String caption, Resource icon, MenuBar.Command command) {
+            if (caption == null) {
+                throw new IllegalArgumentException("caption cannot be null");
+            }
+            itsId = ++numberOfItems;
+            itsText = caption;
+            itsIcon = icon;
+            itsCommand = command;
+        }
+
+        /**
+         * Checks if the item has children (if it is a submenu).
+         * 
+         * @return True if this item has children
+         */
+        public boolean hasChildren() {
+            return itsChildren != null;
+        }
+
+        /**
+         * Add a new item inside this item, thus creating a submenu. Icon and
+         * command can be null, but a caption must be given.
+         * 
+         * @param caption
+         *                the text for the menu item
+         * @param icon
+         *                the icon for the menu item
+         * @param command
+         *                the command for the menu item
+         */
+        public MenuBar.Item addItem(String caption, Resource icon,
+                MenuBar.Command command) {
+            if (caption == null) {
+                throw new IllegalArgumentException("caption cannot be null");
+            }
+
+            if (itsChildren == null) {
+                itsChildren = new ArrayList();
+            }
+
+            Item newItem = new Item(caption, icon, command);
+
+            // The only place where the parent is set
+            newItem.setParent(this);
+            itsChildren.add(newItem);
+
+            requestRepaint();
+
+            return newItem;
+        }
+
+        /**
+         * Add an item before some item. If the given item does not exist the
+         * item is added at the end of the menu. Icon and command can be null,
+         * but a caption must be given.
+         * 
+         * @param caption
+         *                the text for the menu item
+         * @param icon
+         *                the icon for the menu item
+         * @param command
+         *                the command for the menu item
+         * @param itemToAddBefore
+         *                the item that will be after the new item
+         * 
+         */
+        public MenuBar.Item addItemBefore(String caption, Resource icon,
+                MenuBar.Command command, MenuBar.Item itemToAddBefore) {
+
+            Item newItem = null;
+
+            if (hasChildren() && itsChildren.contains(itemToAddBefore)) {
+                int index = itsChildren.indexOf(itemToAddBefore);
+                newItem = new Item(caption, icon, command);
+                newItem.setParent(this);
+                itsChildren.add(index, newItem);
+
+            } else {
+                newItem = addItem(caption, icon, command);
+            }
+
+            requestRepaint();
+
+            return newItem;
+        }
+
+        /**
+         * For the associated command.
+         * 
+         * @return The associated command, or null if there is none
+         */
+        public Command getCommand() {
+            return itsCommand;
+        }
+
+        /**
+         * Gets the objects icon.
+         * 
+         * @return The icon of the item, null if the item doesn't have an icon
+         */
+        public Resource getIcon() {
+            return itsIcon;
+        }
+
+        /**
+         * For the containing item. This will return null if the item is in the
+         * top-level menubar.
+         * 
+         * @return The containing MenuBar.MenuItem, or null if there is none
+         */
+        public MenuBar.Item getParent() {
+            return itsParent;
+        }
+
+        /**
+         * This will return the children of this item or null if there are none.
+         * 
+         * @return List of children items, or null if there are none
+         */
+        public java.util.List getChildren() {
+            return itsChildren;
+        }
+
+        /**
+         * Gets the objects text
+         * 
+         * @return The text
+         */
+        public java.lang.String getText() {
+            return itsText;
+        }
+
+        /**
+         * Returns the number of children.
+         * 
+         * @return The number of child items
+         */
+        public int getSize() {
+            return itsChildren.size();
+        }
+
+        /**
+         * Get the unique identifier for this item.
+         * 
+         * @return The id of this item
+         */
+        public int getId() {
+            return itsId;
+        }
+
+        /**
+         * Set the command for this item. Set null to remove.
+         * 
+         * @param command
+         *                The MenuCommand of this item
+         */
+        public void setCommand(MenuBar.Command command) {
+            itsCommand = command;
+        }
+
+        /**
+         * Sets the icon. Set null to remove.
+         * 
+         * @param icon
+         *                The icon for this item
+         */
+        public void setIcon(Resource icon) {
+            itsIcon = icon;
+            requestRepaint();
+        }
+
+        /**
+         * Set the text of this object.
+         * 
+         * @param text
+         *                Text for this object
+         */
+        public void setText(java.lang.String text) {
+            if (text != null) {
+                itsText = text;
+            }
+            requestRepaint();
+        }
+
+        /**
+         * Remove the first occurrence of the item.
+         * 
+         * @param item
+         *                The item to be removed
+         */
+        public void removeChild(MenuBar.Item item) {
+            if (item != null && itsChildren != null) {
+                itsChildren.remove(item);
+                if (itsChildren.isEmpty()) {
+                    itsChildren = null;
+                }
+            }
+            requestRepaint();
+        }
+
+        /**
+         * Empty the list of children items.
+         */
+        public void removeChildren() {
+            if (itsChildren != null) {
+                itsChildren.clear();
+                itsChildren = null;
+            }
+            requestRepaint();
+        }
+
+        /**
+         * Set the parent of this item. This is called by the addItem method.
+         * 
+         * @param parent
+         *                The parent item
+         */
+        protected void setParent(MenuBar.Item parent) {
+            itsParent = parent;
+        }
+
+    }// class MenuItem
+
+}// class MenuBar