Java Swing Menu Item addMenuItem(final Action action, final C topLevelMenu, final String... path)

Here you can find the source of addMenuItem(final Action action, final C topLevelMenu, final String... path)

Description

add Menu Item

License

Open Source License

Declaration

static public <C extends JComponent & MenuElement> JMenuItem addMenuItem(final Action action,
            final C topLevelMenu, final String... path) throws IllegalArgumentException 

Method Source Code


//package com.java2s;
/*/*  w w  w . j  a  v a2  s.c  o m*/
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */

import java.awt.Component;
import java.awt.Container;
import java.util.Arrays;
import java.util.List;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import javax.swing.MenuElement;

public class Main {
    private static final String GROUPNAME_PROPNAME = "GROUPNAME";
    private static final String DEFAULT_GROUPNAME = "defaultGroupName";

    static public <C extends JComponent & MenuElement> JMenuItem addMenuItem(final Action action,
            final C topLevelMenu) throws IllegalArgumentException {
        return addMenuItem(action, topLevelMenu, (String) null);
    }

    static public <C extends JComponent & MenuElement> JMenuItem addMenuItem(final Action action,
            final C topLevelMenu, final String... path) throws IllegalArgumentException {
        return addMenuItem(action, topLevelMenu, Arrays.asList(path));
    }

    /**
     * Adds a menu item to the passed menu. The path should be an alternation of group and menu
     * within that menu. All items within the same group will be grouped together inside separators.
     * Menus will be created as needed and groups' names can be <code>null</code>. NOTE: items added
     * with this method (even with null groups) will always be separated from items added directly.
     * 
     * @param action the action to perform.
     * @param topLevelMenu where to add the menu item.
     * @param path where to add the menu item.
     * @return the newly created item.
     * @throws IllegalArgumentException if path length is not odd.
     */
    static public <C extends JComponent & MenuElement> JMenuItem addMenuItem(final Action action,
            final C topLevelMenu, final List<String> path) throws IllegalArgumentException {
        return addMenuItem(new JMenuItem(action), topLevelMenu, path);
    }

    static public <C extends JComponent & MenuElement> JMenuItem addMenuItem(final JMenuItem mi,
            final C topLevelMenu, final List<String> path) throws IllegalArgumentException {
        if (path.size() == 0 || path.size() % 2 == 0)
            throw new IllegalArgumentException("Path should be of the form group/menu/group/... : " + path);
        JComponent menu = topLevelMenu;
        for (int i = 0; i < path.size() - 1; i += 2) {
            final String groupName = path.get(i);
            final String menuName = path.get(i + 1);
            menu = addChild(menu, groupName, new JMenu(menuName), JMenu.class, false);
        }
        final String actionGroupName = path.get(path.size() - 1);
        return addChild(menu, actionGroupName, mi, JMenuItem.class, true);
    }

    static private <T extends JMenuItem> T addChild(final Container c, String groupName, final T created,
            final Class<T> clazz, final boolean alwaysAdd) {
        if (groupName == null)
            groupName = DEFAULT_GROUPNAME;
        final Component[] children = getChildren(c);
        final int[] groupRange = getRange(children, groupName);
        final T res;
        if (groupRange == null) {
            if (children.length > 0) {
                if (c instanceof JMenu) {
                    ((JMenu) c).addSeparator();
                } else {
                    c.add(new JSeparator());
                }
            }
            res = created;
            c.add(res);
        } else {
            final T existingChild = alwaysAdd ? null : findChild(children, groupRange, created.getText(), clazz);
            if (existingChild != null) {
                res = existingChild;
            } else {
                res = created;
                // add after the last of the group (groupRange[1] is exclusive)
                // from Container.addImpl() index can be equal to count() to add at the end
                c.add(res, groupRange[1]);
            }
        }
        res.putClientProperty(GROUPNAME_PROPNAME, groupName);
        return res;
    }

    static private Component[] getChildren(final Container c) {
        return c instanceof JMenu ? ((JMenu) c).getMenuComponents() : c.getComponents();
    }

    static private int[] getRange(final Component[] children, String groupName) {
        int min = -1;
        int max = -1;
        for (int i = 0; i < children.length; i++) {
            if (groupName.equals(((JComponent) children[i]).getClientProperty(GROUPNAME_PROPNAME))) {
                if (min < 0)
                    min = i;
                if (max < i)
                    max = i;
            }
        }
        // inclusive, exclusive
        return min == -1 ? null : new int[] { min, max + 1 };
    }

    /**
     * Find a child with the passed class and text.
     * 
     * @param <T> type of child
     * @param c the parent.
     * @param name the text of the child.
     * @param clazz the class of the child.
     * @return the child found or <code>null</code>.
     */
    static public <T extends JMenuItem> T findChild(final Container c, final String name, Class<T> clazz) {
        return findChild(getChildren(c), null, name, clazz);
    }

    static private <T extends JMenuItem> T findChild(final Component[] children, int[] range, final String name,
            Class<T> clazz) {
        if (range == null)
            range = new int[] { 0, children.length };
        for (int groupIndex = range[0]; groupIndex < range[1]; groupIndex++) {
            final Component child = children[groupIndex];
            if (clazz == child.getClass()) {
                final T casted = clazz.cast(child);
                if (name.equals(casted.getText())) {
                    return casted;
                }
            }
        }
        return null;
    }
}

Related

  1. addMenuItem(Container menu, String text, ActionListener listener)
  2. appendMenuItem(Component menuItem, StringBuilder builder, String indent)
  3. createMenu(String menu, String[] menuItemNames)
  4. createMenuItem(Action a)
  5. createMenuItem(Action action, Icon icon)