/* class JPopupMenu * * Copyright (C) 2001-2003 R M Pitman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package charvax.swing; import java.util.Vector; import charva.awt.Component; import charva.awt.Toolkit; import charva.awt.event.ActionEvent; import charva.awt.event.KeyEvent; /** * An implementation of a popup menu - a small window that pops up and * displays a number of choices. */ public class JPopupMenu extends JFrame { /** Constructs a JPopupMenu that contains the specified items. * Each element in the Vector must be a JMenuItem or JSeparator. */ public JPopupMenu(Vector<Component> items_) { super(); for (Component item : items_) { add(item); } setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); pack(); } /** * Sets the "invoker" of this popup menu; must be a JMenuBar * or another JPopupMenu. */ public void setInvoker(Component invoker_) { _invoker = invoker_; setForeground(invoker_.getForeground()); setBackground(invoker_.getBackground()); } /** Returns the component that invoked this popup menu. */ public Component getInvoker() { return _invoker; } /** Returns the menu item at the specified index. If the item * is a JSeparator, it returns null. */ public JMenuItem getMenuItem(int index_) { Object o = super._components.elementAt(index_); if (o instanceof JMenuItem) return (JMenuItem) o; else return null; } public int getComponentIndex(Component c) { return super._components.indexOf(c); } public void processKeyEvent(KeyEvent e) { _wasCancelled = false; _leftWasPressed = false; _rightWasPressed = false; if ( ! _visible) return; // the popup has already been dismissed. int key = e.getKeyCode(); Toolkit term = Toolkit.getDefaultToolkit(); if (key == KeyEvent.VK_UP) { super.previousFocus(); } else if (key == KeyEvent.VK_DOWN) { super.nextFocus(); } else if (key == KeyEvent.VK_LEFT) { /* Pressing the LEFT cursor key has the effect of cancelling * the selected menu and invoking the next menu on the left. */ _leftWasPressed = true; hide(); } else if (key == KeyEvent.VK_RIGHT) { /* Pressing the RIGHT cursor key has the effect of cancelling * the selected menu and invoking the next menu on the right. */ _rightWasPressed = true; hide(); } else if (key == KeyEvent.VK_ENTER) { /* Pressing ENTER sends an ActionEvent. The source of the * event is the menu item, not the menu; this means that the * client program has to add an ActionListener to each menu * item. This is inconvenient, but it's the way that the Java * Swing menus do it. */ JMenuItem item = (JMenuItem) super.getCurrentFocus(); _activate(item); e.consume(); } else if (key == KeyEvent.VK_BACK_SPACE || key == 0x1b) { // Backspace or ESC was pressed _wasCancelled = true; hide(); } else { /* Check if one of the mnemonic keys was pressed. * Note that the user can press a lowercase or an uppercase * key. */ char keyLower = Character.toLowerCase((char) key); for (int i=0; i < super._components.size(); i++) { JMenuItem item = getMenuItem(i); if (item != null) { if (item.getMnemonic() == -1) continue; // this item doesn't have a mnemonic char mnemonicLower = Character.toLowerCase((char) item.getMnemonic()); if (keyLower == mnemonicLower) { _activate(item); return; } } } term.beep(); } } // end of processKeyEvent() public boolean wasCancelled() { return _wasCancelled; } boolean leftWasPressed() { return _leftWasPressed; } boolean rightWasPressed() { return _rightWasPressed; } /** Private helper method for activating a menu item (either a * JMenuItem or a JMenu). */ private void _activate(JMenuItem item_) { if (item_ instanceof JMenu) { JMenu menu = (JMenu) item_; menu.setPopupMenuVisible(true); // The popup menu has hidden itself if (menu.getPopupMenu().leftWasPressed()) { Toolkit.getDefaultToolkit().fireKeystroke(KeyEvent.VK_LEFT); } else if (menu.getPopupMenu().rightWasPressed()) { Toolkit.getDefaultToolkit().fireKeystroke(KeyEvent.VK_RIGHT); } else if (menu.getPopupMenu().wasCancelled() == false) hide(); } else { ActionEvent evt = new ActionEvent(item_, item_.getActionCommand()); Toolkit term = Toolkit.getDefaultToolkit(); term.getSystemEventQueue().postEvent(evt); hide(); } } public String toString() { String str = "JPopupMenu: ["; for (int i=0; i<getComponentCount(); i++) { str += getMenuItem(i); str += " "; } return str + "]"; } protected boolean _wasCancelled; protected boolean _leftWasPressed; protected boolean _rightWasPressed; private Component _invoker; }