Menu.java :  » Apache-Harmony-Java-SE » java-package » java » awt » Java Open Source

Java Open Source » Apache Harmony Java SE » java package 
java package » java » awt » Menu.java
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package java.awt;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashSet;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import org.apache.harmony.awt.gl.MultiRectArea;
import org.apache.harmony.awt.internal.nls.Messages;
import org.apache.harmony.awt.state.MenuState;

public class Menu extends MenuItem implements MenuContainer, Accessible {
    private static final long serialVersionUID = -8809584163345499784L;

    final static int LAST_ELEMENT = Integer.MAX_VALUE;

    private final ArrayList<MenuItem> menuItems = new ArrayList<MenuItem>();

    private final Point location = new Point();

    private final Dimension size = new Dimension();

    private final boolean tearOff;

    final MenuPopupBox popupBox = new MenuPopupBox();

    protected class AccessibleAWTMenu extends AccessibleAWTMenuItem {
        private static final long serialVersionUID = 5228160894980069094L;

        @Override
        public AccessibleRole getAccessibleRole() {
            return AccessibleRole.MENU;
        }
    }

    /**
     * The internal menu's state utilized by the visual theme
     */
    final class State extends MenuComponent.State implements MenuState {
        @Override
        public int getWidth() {
            return Menu.this.getWidth();
        }

        @Override
        public int getHeight() {
            return Menu.this.getHeight();
        }

        @Override
        public Font getFont() {
            return Menu.this.getFont();
        }

        @Override
        public int getItemCount() {
            return Menu.this.getItemCount();
        }

        @Override
        public int getSelectedItemIndex() {
            return Menu.this.getSelectedItemIndex();
        }

        @Override
        public boolean isFontSet() {
            return Menu.this.isFontSet();
        }

        @SuppressWarnings("deprecation")
        @Override
        public FontMetrics getFontMetrics(Font f) {
            return Menu.this.toolkit.getFontMetrics(f);
        }

        @Override
        public Point getLocation() {
            return Menu.this.location;
        }
    }

    final State menuState = new State();

    public Menu(String label) throws HeadlessException {
        this(label, false);
        toolkit.lockAWT();
        try {
        } finally {
            toolkit.unlockAWT();
        }
    }

    public Menu(String label, boolean tearOff) throws HeadlessException {
        super(label);
        toolkit.lockAWT();
        try {
            this.tearOff = tearOff;
        } finally {
            toolkit.unlockAWT();
        }
    }

    public Menu() throws HeadlessException {
        this("", false); //$NON-NLS-1$
        toolkit.lockAWT();
        try {
        } finally {
            toolkit.unlockAWT();
        }
    }

    public void add(String label) {
        toolkit.lockAWT();
        try {
            add(new MenuItem(label));
        } finally {
            toolkit.unlockAWT();
        }
    }

    public MenuItem add(MenuItem item) {
        toolkit.lockAWT();
        try {
            insertImpl(item, LAST_ELEMENT);
            return item;
        } finally {
            toolkit.unlockAWT();
        }
    }

    public void remove(int index) {
        toolkit.lockAWT();
        try {
            removeImpl(index);
        } finally {
            toolkit.unlockAWT();
        }
    }

    public void remove(MenuComponent item) {
        if (item == null) {
            return;
        }
        toolkit.lockAWT();
        try {
            int index = menuItems.indexOf(item);
            removeImpl(index);
        } finally {
            toolkit.unlockAWT();
        }
    }

    void removeImpl(int index) {
        MenuComponent item = menuItems.remove(index);
        item.setParent(null);
    }

    public void removeAll() {
        toolkit.lockAWT();
        try {
            while (!menuItems.isEmpty()) {
                removeImpl(menuItems.size() - 1);
            }
        } finally {
            toolkit.unlockAWT();
        }
    }

    public void insert(String label, int index) {
        toolkit.lockAWT();
        try {
            insertImpl(new MenuItem(label), index);
        } finally {
            toolkit.unlockAWT();
        }
    }

    public void insert(MenuItem item, int index) {
        toolkit.lockAWT();
        try {
            insertImpl(item, index);
        } finally {
            toolkit.unlockAWT();
        }
    }

    void insertImpl(MenuItem item, int index) {
        if (index < 0) {
            // awt.6F=Index less than zero
            throw new IllegalArgumentException(Messages.getString("awt.6F")); //$NON-NLS-1$
        }
        if (item == null) {
            // awt.70=MenuItem is null
            throw new NullPointerException(Messages.getString("awt.70")); //$NON-NLS-1$
        }
        MenuContainer oldParent = item.getParent();
        if (oldParent != null) {
            oldParent.remove(item);
        }
        item.setParent(this);
        if (index >= menuItems.size()) {
            menuItems.add(item);
        } else {
            menuItems.add(index, item);
        }
    }

    @Override
    public String paramString() {
        toolkit.lockAWT();
        try {
            return super.paramString() + (tearOff ? ",tearOff" : ""); //$NON-NLS-1$ //$NON-NLS-2$
        } finally {
            toolkit.unlockAWT();
        }
    }

    @Override
    public MenuItem getItem(int index) {
        toolkit.lockAWT();
        try {
            return menuItems.get(index);
        } finally {
            toolkit.unlockAWT();
        }
    }

    @Override
    public void addNotify() {
        toolkit.lockAWT();
        try {
            popupBox.addNotify();
            super.addNotify();
        } finally {
            toolkit.unlockAWT();
        }
    }

    @Override
    public AccessibleContext getAccessibleContext() {
        toolkit.lockAWT();
        try {
            return super.getAccessibleContext();
        } finally {
            toolkit.unlockAWT();
        }
    }

    @Override
    public void removeNotify() {
        toolkit.lockAWT();
        try {
            for (int i = 0; i < getItemCount(); i++) {
                getItem(i).removeNotify();
            }
            super.removeNotify();
        } finally {
            toolkit.unlockAWT();
        }
    }

    /**
     * @deprecated
     */
    @Deprecated
    public int countItems() {
        toolkit.lockAWT();
        try {
            return getItemCount();
        } finally {
            toolkit.unlockAWT();
        }
    }

    @Override
    public int getItemCount() {
        toolkit.lockAWT();
        try {
            return menuItems.size();
        } finally {
            toolkit.unlockAWT();
        }
    }

    public void addSeparator() {
        toolkit.lockAWT();
        try {
            add(new MenuItem("-")); //$NON-NLS-1$
        } finally {
            toolkit.unlockAWT();
        }
    }

    public void insertSeparator(int index) {
        toolkit.lockAWT();
        try {
            insert(new MenuItem("-"), index); //$NON-NLS-1$
        } finally {
            toolkit.unlockAWT();
        }
    }

    public boolean isTearOff() {
        return tearOff;
    }

    @Override
    Point getLocation() {
        return location;
    }

    Dimension getSize() {
        return size;
    }

    @Override
    int getWidth() {
        return size.width;
    }

    @Override
    int getHeight() {
        return size.height;
    }

    @Override
    void paint(Graphics gr) {
        toolkit.theme.drawMenu(menuState, gr);
    }

    /**
     * Show menu on the screen
     * @param x - screen X coordinate
     * @param y - screen Y coordinate
     */
    void show(int x, int y, boolean modal) {
        if (parent == null) {
            // awt.71=Parent is null
            throw new NullPointerException(Messages.getString("awt.71")); //$NON-NLS-1$
        }
        location.x = x;
        location.y = y;
        selectItem(-1, true);
        PopupBox parentBox = null;
        if (parent instanceof MenuComponent) {
            parentBox = ((MenuComponent) parent).getPopupBox();
        }
        size.setSize(toolkit.theme.calculateMenuSize(menuState));
        popupBox.setParent(parentBox);
        popupBox.setModal(modal);
        popupBox.show(location, size, getOwnerWindow());
    }

    Window getOwnerWindow() {
        for (MenuContainer cont = getParent(); cont != null;) {
            if (cont instanceof Component) {
                return ((Component) cont).getWindowAncestor();
            }
            if (cont instanceof Menu) {
                cont = ((Menu) cont).parent;
                continue;
            }
            if (cont instanceof MenuBar) {
                return (Window) ((MenuBar) cont).parent;
            }
        }
        return null;
    }

    @Override
    void hide() {
        super.hide();
        for (int i = 0; i < getItemCount(); i++) {
            getItem(i).hide();
        }
        popupBox.hide();
    }

    @Override
    boolean isVisible() {
        return popupBox.isVisible();
    }

    @Override
    PopupBox getPopupBox() {
        return popupBox;
    }

    @Override
    void onMouseEvent(int eventId, Point where, int mouseButton, long when, int modifiers) {
        if (eventId == MouseEvent.MOUSE_PRESSED || eventId == MouseEvent.MOUSE_MOVED
                || eventId == MouseEvent.MOUSE_DRAGGED) {
            int index = toolkit.theme.getMenuItemIndex(menuState, where);
            if (index >= 0 || getSelectedSubmenu() == null) {
                selectItem(index);
            }
        } else if (eventId == MouseEvent.MOUSE_RELEASED) {
            int index = toolkit.theme.getMenuItemIndex(menuState, where);
            selectItem(index);
            if (index >= 0) {
                fireItemAction(index, when, modifiers);
            }
        } else if (eventId == MouseEvent.MOUSE_EXITED) {
            if (getSelectedSubmenu() == null) {
                selectItem(-1);
            }
        }
    }

    @Override
    void onKeyEvent(int eventId, int vKey, long when, int modifiers) {
        if (eventId != KeyEvent.KEY_PRESSED) {
            return;
        }
        int selected = getSelectedItemIndex();
        MenuBar menuBar;
        switch (vKey) {
            case KeyEvent.VK_ESCAPE:
                hide();
                break;
            case KeyEvent.VK_RIGHT:
                Menu subMenu = getSelectedSubmenu();
                if (subMenu != null) {
                    showSubMenu(selected);
                    subMenu.selectNextItem(true, false);
                } else {
                    menuBar = getMenuBar();
                    if (menuBar != null) {
                        menuBar.onKeyEvent(eventId, vKey, when, modifiers);
                    }
                }
                break;
            case KeyEvent.VK_LEFT:
                if (parent instanceof Menu) {
                    hide();
                } else {
                    menuBar = getMenuBar();
                    if (menuBar != null) {
                        menuBar.onKeyEvent(eventId, vKey, when, modifiers);
                    }
                }
                break;
            case KeyEvent.VK_UP:
            case KeyEvent.VK_DOWN:
                selectNextItem(vKey == KeyEvent.VK_DOWN, false);
                break;
            case KeyEvent.VK_ENTER:
                if (selected >= 0) {
                    fireItemAction(selected, when, modifiers);
                } else {
                    hide();
                }
        }
    }

    @Override
    void itemSelected(long when, int modifiers) {
        // do nothing
    }

    @Override
    Rectangle getItemRect(int index) {
        return menuState.getItem(index).getItemBounds();
    }

    @Override
    Point getSubmenuLocation(int index) {
        return toolkit.theme.getMenuItemLocation(menuState, index);
    }

    @Override
    Graphics getGraphics(MultiRectArea clip) {
        return popupBox.getGraphics(clip);
    }

    @Override
    AccessibleContext createAccessibleContext() {
        return new AccessibleAWTMenu();
    }

    void collectShortcuts(HashSet<MenuShortcut> shortcuts) {
        for (int i = 0; i < menuItems.size(); i++) {
            MenuItem item = menuItems.get(i);
            if (item instanceof Menu) {
                ((Menu) item).collectShortcuts(shortcuts);
            } else {
                MenuShortcut ms = item.getShortcut();
                if (ms != null) {
                    shortcuts.add(ms);
                }
            }
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.