/* class JMenuBar
*
* 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 charva.awt.Component;
import charva.awt.Container;
import charva.awt.Dimension;
import charva.awt.IllegalComponentStateException;
import charva.awt.Point;
import charva.awt.Toolkit;
import charva.awt.event.KeyEvent;
/**
* An implementation of a menubar.
*/
public class JMenuBar extends Container {
/**
* Create a new menu bar
*/
public JMenuBar() {
/*
* The menubar is always offset from the origin of its parent JFrame by
* (1, 1).
*/
super._origin = new Point(1, 1);
}
/**
* Appends the specified menu to the end of the JMenuBar.
*
* @param menu_
* the menu to be added.
* @return the menu that was added.
*/
public JMenu add(JMenu menu_) {
JMenu jmenu = menu_;
super.add(jmenu);
return jmenu;
}
/**
* Returns the number of menus in the menubar.
*/
public int getMenuCount() {
return super.getComponentCount();
}
/**
* Returns the menu at the specified index.
*/
public JMenu getMenu(int index_) {
return (JMenu) super.getComponent(index_);
}
/**
* Returns the menu that has the specified text label.
*/
public JMenu getMenu(String text_) {
for (int i = 0; i < getMenuCount(); i++) {
JMenu menu = getMenu(i);
if (menu.getText().equals(text_)) { return menu; }
}
throw new IllegalArgumentException("menubar does not contain menu \""
+ text_ + "\"");
}
/**
* Draw this menubar.
* @param toolkit
*/
public void draw(Toolkit toolkit) {
/*
* Get the absolute origin of this component.
*/
Point origin = getLocationOnScreen();
int colorpair = getCursesColor();
/*
* Build a horizontal line of spaces extending across the top of the
* frame.
*/
StringBuffer buf = new StringBuffer();
for (int i = 0; i < getSize().width; i++) {
buf.append(' ');
}
toolkit.setCursor(origin);
toolkit.addString(buf.toString(), Toolkit.A_REVERSE, colorpair);
Component[] menus = super.getComponents();
int x = 0;
for (int i = 0; i < menus.length; i++) {
menus[ i].setLocation(x, 0);
menus[ i].draw(toolkit);
x += menus[ i].getWidth();
}
}
/**
* Processes key events occurring on this object by dispatching them to any
* registered KeyListener objects.
*/
public void processKeyEvent(KeyEvent ke_) {
//Toolkit term = Toolkit.getDefaultToolkit();
int key = ke_.getKeyCode();
if (key == '\t') {
getParent().nextFocus();
ke_.consume();
return;
} else if (key == KeyEvent.VK_BACK_TAB) {
getParent().previousFocus();
ke_.consume();
return;
} else if (key == KeyEvent.VK_RIGHT) {
Component currentFocus = super.getCurrentFocus();
int menuCount = getMenuCount();
int i = 0;
for (i = 0; i < menuCount; i++) {
if (currentFocus == super.getComponent(i)) break;
}
if (i == menuCount - 1)
i = 0;
else
i++;
getMenu(i).requestFocus();
ke_.consume();
} else if (key == KeyEvent.VK_LEFT) {
Component currentFocus = super.getCurrentFocus();
int menuCount = getMenuCount();
int i = 0;
for (i = 0; i < menuCount; i++) {
if (currentFocus == super.getComponent(i)) break;
}
if (i == 0)
i = menuCount - 1;
else
i--;
getMenu(i).requestFocus();
ke_.consume();
} 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++) {
JMenu menu = getMenu(i);
if (menu != null) {
if (menu.getMnemonic() == -1) continue; // this menu
// doesn't have a
// mnemonic
char mnemonicLower = Character.toLowerCase((char) menu
.getMnemonic());
if (keyLower == mnemonicLower) {
menu.doClick();
ke_.consume();
return;
}
}
}
// Pass the KeyEvent on to the JMenu that originated it.
super.processKeyEvent(ke_);
}
}
public Dimension minimumSize() {
int width = 0;
for (int i = 0; i < getMenuCount(); i++) {
width += getMenu(i).getText().length() + 1;
}
return new Dimension(width, 1);
}
public Dimension getSize() {
return new Dimension(this.getWidth(), getHeight());
}
public int getWidth() {
// get the width of our parent JFrame.
Container parent = getParent();
if (parent == null) { throw new IllegalComponentStateException(
"can't get menubar size before "
+ "it has been added to a frame"); }
int parentwidth = parent.getWidth() - 2;
int minwidth = minimumSize().width;
int width = (parentwidth > minwidth) ? parentwidth : minwidth;
return width;
}
public int getHeight() {
return 1;
}
/**
* Output a text description of the menubar.
*/
public void debug(int level_) {
for (int i = 0; i < level_; i++)
System.err.print(" ");
System.err.println(this.toString());
}
public String toString() {
return "JMenuBar";
}
/**
* Returns the index of the menu containing the point at the specified
* screen coordinates, or -1 if no menu contains the point.
*/
/*private int getMenuAt(int x, int y) {
Point origin = getLocationOnScreen();
int index = origin.x;
for (int i = 0; i < getMenuCount(); i++) {
String menutext = getMenu(i).getText();
index += (menutext.length() + 1);
if (x < index) return i;
}
return -1;
}*/
//====================================================================
// PACKAGE-PRIVATE METHODS
/**
* Computes the absolute screen position for the specified JMenu. This is a
* Charva-specific package-private method called by the JMenu that wants to
* pop itself up. It is required because JMenuBar is not implemented as a
* subclass of Container. It is not intended to be called by application
* programmers.
*/
Point getPopupMenuLocation(JMenu menu_) {
/*
* Get the origin of this menubar
*/
Point origin = getLocationOnScreen();
int offset = 0;
for (int i = 0; i < getMenuCount(); i++) {
JMenu menu = getMenu(i);
if (menu == menu_) { return origin.addOffset(offset, 1); }
String menutext = menu.getText();
offset += menutext.length() + 1;
}
throw new IllegalArgumentException("specified menu not in menubar");
}
//====================================================================
// INSTANCE VARIABLES
}