第10章 菜单和工具条
菜单和工具条是现代用户界面的重要组成部分。Swing提供了对这两者的完全支持。Swing提供菜单组件(即菜单条中的菜单和弹出式菜单中的菜单)和菜单项组件(包括复选框和单选按钮菜单项)。 Swing还提供一个工具条组件,根据工具条的方向,工具条组件包含一行按钮或一列按钮。工具条通常提供对普通特性的简单访问。通常,除键盘捷径键提供对相同功能的访问外,菜单栏和工具条不提供对相同功能集的访问。工具条还可以是悬浮的,这样,可以把工具条在窗口中任意拖动或拖到一个单独的窗口中。 Swing菜单和菜单项是按钮,因为JMenuItem扩展AbstractButton,JMenu扩展JMenuItem,如图10-1所示。因此,Swing菜单和菜单项继承了如下功能,即包含文本和(或)图标、显示光标进入时的图标和助记符等。 图10-1示出了JMenuItem和JMenu的父组件,它们最后都归于java.awt.Container,以强调菜单和菜单项都是容器。可以把任何类型的组件(从包含一个动画GIF的标签到JTree的一个实例)添加到一个菜单或菜单项中。 菜单和菜单项还实现MenuElement接口,以便参与菜单事件的处理。MenuElement接口在10.7节“菜单元素”中介绍。 工具条和弹出式菜单都扩展JComponent类,即任意组件都可以添加到一个工具条或弹出式菜单中。 本章将介绍下面的组件: ·JMenuItem ·JCheckBoxMenuItem ·JRadioButtonMenuItem ·JMenu ·JPopupMenu ·JMenuBar ·JToolBar
10.1 菜单、菜单栏和工具条
例10-1 JRootPane中的菜单栏和工具条
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { Icon dukeStanding = new ImageIcon("duke_standing.gif"), dukeWaving = new ImageIcon("duke_waving.gif"), dukeStandingSmall = new ImageIcon("duke_standing_small.gif"), dukeWavingSmall = new ImageIcon("duke_waving_small.gif");
public void init() { Container contentPane = getContentPane(); Action[] actions = { new NewAction(), new OpenAction(), new CutAction(), new CopyAction(), new PasteAction(), new ExitAction() }; JToolBar toolbar = new JToolBar(); JMenuBar menubar = new JMenuBar(); JMenu fileMenu = new JMenu("File");
JRadioButton menubarDuke = new JRadioButton(dukeStandingSmall), menuDuke = new JRadioButton(dukeStandingSmall), toolbarDuke = new JRadioButton(dukeStanding); menuDuke.setRolloverIcon(dukeWavingSmall); menubarDuke.setRolloverIcon(dukeWavingSmall); toolbarDuke.setRolloverIcon(dukeWaving);
menubar.add(menubarDuke); toolbar.add(toolbarDuke); fileMenu.add(menuDuke);
for(int i=0; i < actions.length; ++i) { fileMenu.add(actions[i]);
if(i != actions.length-1) toolbar.add(actions[i]);
if(i == 2 || i == actions.length-2){ toolbar.addSeparator(); fileMenu.addSeparator(); } } menubar.add(fileMenu);
contentPane.add(toolbar, BorderLayout.NORTH); getRootPane().setJMenuBar(menubar); System.out.println(contentPane.getClass().getName()); LayoutManager lm = contentPane.getLayout(); System.out.println(lm.getClass());
} class NewAction extends AbstractAction { public NewAction() { super("New ...", new ImageIcon("new.gif")); } public void actionPerformed(ActionEvent event) { showStatus("new"); } } class OpenAction extends AbstractAction { public OpenAction() { super("Open ...", new ImageIcon("open.gif")); } public void actionPerformed(ActionEvent event) { showStatus("open"); } } class CutAction extends AbstractAction { public CutAction() { super("Cut", new ImageIcon("cut.gif")); } public void actionPerformed(ActionEvent event) { showStatus("cut"); } } class CopyAction extends AbstractAction { public CopyAction() { super("Copy", new ImageIcon("copy.gif")); } public void actionPerformed(ActionEvent event) { showStatus("copy"); } } class PasteAction extends AbstractAction { public PasteAction() { super("Paste", new ImageIcon("paste.gif")); } public void actionPerformed(ActionEvent event) { showStatus("paste"); } } class ExitAction extends AbstractAction { public ExitAction() { super("Exit"); putValue(Action.SMALL_ICON, dukeWavingSmall); } public void actionPerformed(ActionEvent event) { System.exit(0); } } }
10.2 菜单和弹出式菜单
例10-2 一个简单的菜单举例
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { JMenuBar mb = new JMenuBar(); JMenu fileMenu = new JMenu("File"); JMenu pullRightMenu = new JMenu("pull right");
fileMenu.add("New ..."); fileMenu.add("Open ..."); fileMenu.add("Save"); fileMenu.add("Save As .."); fileMenu.addSeparator(); fileMenu.add(pullRightMenu); fileMenu.add("Exit");
pullRightMenu.add(new JCheckBoxMenuItem("Bush")); pullRightMenu.add(new JCheckBoxMenuItem("Tonic")); pullRightMenu.add(new JCheckBoxMenuItem("Radio Head")); pullRightMenu.add(new JCheckBoxMenuItem("Marcy Playground")); pullRightMenu.add(new JCheckBoxMenuItem("Silver Chair"));
mb.add(fileMenu); setJMenuBar(mb); } }
10.3 JMenuItem
例10-3 安装一些菜单项
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { Container contentPane = getContentPane(); Icon newIcon = new ImageIcon("new.gif", "Create a new document"); Icon openIcon = new ImageIcon("open.gif", "Open an existing document");
JMenuBar mb = new JMenuBar(); JMenu fileMenu = new JMenu("File");
JMenuItem newItem = new JMenuItem(newIcon); JMenuItem openItem = new JMenuItem("Open ...", openIcon); JMenuItem saveItem = new JMenuItem("Save"); JMenuItem saveAsItem = new JMenuItem("Save As ..."); JMenuItem exitItem = new JMenuItem("Exit", 'x');
fileMenu.add(newItem); fileMenu.add(openItem); fileMenu.add(saveItem); fileMenu.add(saveAsItem); fileMenu.addSeparator(); fileMenu.add(exitItem);
MenuItemListener listener = new MenuItemListener(this);
newItem.addActionListener(listener); openItem.addActionListener(listener); saveItem.addActionListener(listener); saveAsItem.addActionListener(listener);
exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } });
mb.add(fileMenu); setJMenuBar(mb); } } class MenuItemListener implements ActionListener { private JApplet applet;
public MenuItemListener(JApplet applet) { this.applet = applet; } public void actionPerformed(ActionEvent e) { JMenuItem item = (JMenuItem)e.getSource(); ImageIcon icon = (ImageIcon)item.getIcon();
if(icon != null) System.out.println(icon.getDescription()); else System.out.println(item.getText()); } }
10.3.1菜单项快捷键助记符键
例10-4 带助记符键和快捷键的菜单项
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JFrame { public Test() { Container contentPane = getContentPane();
JMenuBar mb = new JMenuBar(); JMenu fileMenu = new JMenu("File"); JMenuItem exitItem = new JMenuItem("Exit");
fileMenu.add("New ..."); fileMenu.add("Open ..."); fileMenu.add("Save"); fileMenu.add("Save As .."); fileMenu.addSeparator(); fileMenu.add(exitItem);
exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } });
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_X, Event.ALT_MASK); exitItem.setAccelerator(ks);
fileMenu.setMnemonic('F'); exitItem.setMnemonic(KeyEvent.VK_X);
mb.add(fileMenu); setJMenuBar(mb); } public static void main(String args[]) { GJApp.launch(new Test(), "Accelerators and Mnemonics",300,300,450,300); } } class GJApp extends WindowAdapter { static private JPanel statusArea = new JPanel(); static private JLabel status = new JLabel(" ");
public static void launch(final JFrame f, String title, final int x, final int y, final int w, int h) { f.setTitle(title); f.setBounds(x,y,w,h); f.setVisible(true);
statusArea.setBorder(BorderFactory.createEtchedBorder()); statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); statusArea.add(status); status.setHorizontalAlignment(JLabel.LEFT);
f.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE);
f.addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { System.exit(0); } }); } static public JPanel getStatusArea() { return statusArea; } static public void updateStatus(String s) { status.setText(s); } }
10.3.2 JMenuItem属性
10.3.3 JMenuItem事件
例10-5 监听菜单项动作和菜单项变化事件
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { JMenuBar mb = new JMenuBar(); JMenu fileMenu = new JMenu("File"); JMenuItem newItem = new JMenuItem("New ..."), openItem = new JMenuItem("Open ..."), saveItem = new JMenuItem("Save"), saveAsItem = new JMenuItem("Save As ..."), exitItem = new JMenuItem("Exit"); Listener listener = new Listener(this);
fileMenu.add(newItem); fileMenu.add(openItem); fileMenu.add(saveItem); fileMenu.add(saveAsItem); fileMenu.addSeparator(); fileMenu.add(exitItem);
newItem.setActionCommand("Create a New Document"); openItem.setActionCommand("Open an Existing Document"); saveItem.setActionCommand("Save Document"); saveAsItem.setActionCommand("Save Document As ..."); exitItem.setActionCommand("Exit the applet");
newItem.addChangeListener(listener); openItem.addChangeListener(listener); saveItem.addChangeListener(listener); saveAsItem.addChangeListener(listener); exitItem.addChangeListener(listener);
mb.add(fileMenu); setJMenuBar(mb);
exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); } } class Listener implements ChangeListener { private JApplet applet;
public Listener(JApplet applet) { this.applet = applet; } public void stateChanged(ChangeEvent e) { JMenuItem b = (JMenuItem)e.getSource();
if(b.isArmed()) applet.showStatus(b.getActionCommand()); } }
10.3.4 JMenuItem类总结
10.3.5 AWT兼容
10.4 JCheckBoxMenuItem
例10-6 实例化复选框菜单项
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { Container contentPane = getContentPane();
JMenuBar mb = new JMenuBar(); JMenu checkBoxMenu = new JMenu("Endangered Species");
ImageIcon crabIcon = new ImageIcon("crab.gif"); ImageIcon eagleIcon = new ImageIcon("eagle.gif");
JMenuItem crabItem = new JCheckBoxMenuItem(crabIcon), eagleItem = new JCheckBoxMenuItem("eagle", eagleIcon, true), ladybugItem = new JCheckBoxMenuItem("ladybug");
checkBoxMenu.add(crabItem); checkBoxMenu.add(eagleItem); checkBoxMenu.add(ladybugItem);
ladybugItem.setMnemonic('l');
mb.add(checkBoxMenu); setJMenuBar(mb); } }
10.4.1 JCheckBoxMenuItem属性
10.4.2 JCheckBoxMenuItem事件
例10-7 访问JCheckBoxMenuItem状态
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { private ImageIcon crabIcon = new ImageIcon("crab.gif"); private ImageIcon eagleIcon = new ImageIcon("eagle.gif");
private JCheckBoxMenuItem crabItem = new JCheckBoxMenuItem(crabIcon), eagleItem = new JCheckBoxMenuItem("eagle", eagleIcon), ladybugItem = new JCheckBoxMenuItem("ladybug");
public void init() { Container contentPane = getContentPane();
JMenuBar mb = new JMenuBar(); JMenu checkBoxMenu = new JMenu("Endangered Species"); Listener listener = new Listener();
checkBoxMenu.add(crabItem); checkBoxMenu.add(eagleItem); checkBoxMenu.add(ladybugItem);
crabItem.addActionListener(listener); eagleItem.addActionListener(listener); ladybugItem.addActionListener(listener);
mb.add(checkBoxMenu); setJMenuBar(mb); } class Listener implements ActionListener { public void actionPerformed(ActionEvent e) { showStatus("crab: " + crabItem.getState() + ", " + "eagle: " + eagleItem.getState() + ", " + "ladybug: " + ladybugItem.getState()); } } }
10.4.3 JCheckBoxMenuItem类总结
10.4.4 AWT兼容
10.5 JRadioButtonMenuItem
例10-8 实例化单选按钮菜单项
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { Container contentPane = getContentPane();
JMenuBar mb = new JMenuBar(); JMenu radioMenu = new JMenu("Favorite Animal");
ImageIcon crabIcon = new ImageIcon("crab.gif"); ImageIcon eagleIcon = new ImageIcon("eagle.gif");
final JMenuItem crabItem = new JRadioButtonMenuItem(crabIcon), eagleItem = new JRadioButtonMenuItem("eagle", eagleIcon), ladybugItem = new JRadioButtonMenuItem("ladybug");
radioMenu.add(crabItem); radioMenu.add(eagleItem); radioMenu.add(ladybugItem);
mb.add(radioMenu); setJMenuBar(mb); } }
10.5.1 JRadioButtonMenuItem属性
10.5.2 JRadioButtonMenuItem事件
例10-9 为JRadioButton的实例监视事件
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { private ImageIcon crabIcon = new ImageIcon("crab.gif", "Crab"); private ImageIcon eagleIcon = new ImageIcon("eagle.gif", "Eagle"); private JMenuItem crabItem = new JRadioButtonMenuItem(crabIcon), eagleItem = new JRadioButtonMenuItem("eagle", eagleIcon), ladybugItem = new JRadioButtonMenuItem("ladybug");
public void init() { Container contentPane = getContentPane();
JMenuBar mb = new JMenuBar(); JMenu radioMenu = new JMenu("Favorite Animal");
AnItemListener itemListener = new AnItemListener(); AnActionListener actionListener = new AnActionListener(); AChangeListener changeListener = new AChangeListener();
radioMenu.add(crabItem); radioMenu.add(eagleItem); radioMenu.add(ladybugItem);
ButtonGroup group = new ButtonGroup(); group.add(crabItem); group.add(eagleItem); group.add(ladybugItem);
mb.add(radioMenu); setJMenuBar(mb);
crabItem.addItemListener(itemListener); eagleItem.addItemListener(itemListener); ladybugItem.addItemListener(itemListener);
crabItem.addActionListener(actionListener); eagleItem.addActionListener(actionListener); ladybugItem.addActionListener(actionListener);
crabItem.addChangeListener(changeListener); eagleItem.addChangeListener(changeListener); ladybugItem.addChangeListener(changeListener); } private String getItemDescription(JMenuItem item) { String s; ImageIcon icon = (ImageIcon)item.getIcon();
if(icon != null) return icon.getDescription(); else return item.getText(); }
// Inner class event handlers follow ...
class AnActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { JMenuItem item = (JMenuItem) e.getSource(); String s = getItemDescription(item); showStatus(s + " activated");
System.out.println("action event fired"); } }; class AChangeListener implements ChangeListener { public void stateChanged(ChangeEvent e) { Object[] selectedObjs = ladybugItem.getSelectedObjects();
if(selectedObjs == null) System.out.println("selected objs is null"); else System.out.println(selectedObjs[0] + "selected");
JMenuItem item = (JMenuItem)e.getSource();
if(item.isArmed()) { String s = getItemDescription(item); showStatus(s + " armed"); } System.out.println("change event fired"); } }; class AnItemListener implements ItemListener { public void itemStateChanged(ItemEvent e) { JMenuItem item = (JMenuItem) e.getSource(); String s = getItemDescription(item);
if(e.getStateChange() == ItemEvent.SELECTED) s += " selected"; else s += " deselected";
showStatus(s); System.out.println("item event fired"); } }; }
10.5.3 JRadioButtonMenuItem类总结
10.5.4 AWT兼容
10.6 JMenu
例10-10 JMenu的一个简单例子
10.6.1动态修改菜单
例10-11 一个自修改菜单
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Vector;
public class Test extends JApplet { private SelfModifyingMenu selfModifyingMenu;
public void init() { JMenuBar menuBar = new JMenuBar(); createMenus(menuBar); setJMenuBar(menuBar); } public void createMenus(JMenuBar mbar) { mbar.add(createFileMenu()); mbar.add(selfModifyingMenu = new SelfModifyingMenu()); } private JMenu createFileMenu() { JMenu fileMenu = new JMenu("File"); JMenuItem quitItem = new JMenuItem("Quit");
fileMenu.add(quitItem);
quitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); return fileMenu; } } class SelfModifyingMenu extends JMenu { private Vector newItems = new Vector(); private Listener menuItemListener = new Listener(); private JMenuItem toggleItem, enablerItem, addItem, removeItem;
public SelfModifyingMenu() { super("Self Modifying Menu");
add(enablerItem = new JMenuItem("Disable Item Below")); add(toggleItem = new JMenuItem("Enable/Disable Me")); addSeparator();
add(addItem = new JMenuItem("Add a JMenuItem ...")); add(removeItem = new JMenuItem( "Remove last JMenuItem ...")); addItem.setFont(new Font("Helvetica", Font.BOLD, 18)); addSeparator();
enablerItem.addActionListener(menuItemListener); toggleItem.addActionListener(menuItemListener); addItem.addActionListener(menuItemListener); removeItem.addActionListener(menuItemListener); } public void addItem() { JMenuItem newItem = new JMenuItem("Extra Item #" + newItems.size()); add(newItem); newItems.addElement(newItem); } public void removeLastItem() { if(newItems.size() == 0) System.out.println("Nothing to remove!"); else { JMenuItem removeMe = (JMenuItem)newItems.lastElement();
remove(removeMe); newItems.removeElement(removeMe); } } public void toggleItem() { if(toggleItem.isEnabled()) toggleItem.setEnabled(false); else toggleItem.setEnabled(true); } class Listener implements ActionListener { public void actionPerformed(ActionEvent event) { JMenuItem item = (JMenuItem)event.getSource();
if(item == enablerItem) { toggleItem();
if(toggleItem.isEnabled()) enablerItem.setText("Disable Item Below"); else enablerItem.setText("Enable Item Below"); } else if(item == addItem) addItem(); else if(item == removeItem) removeLastItem(); } } }
10.6.2右拉式菜单
例10-12 右拉式菜单
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet {
public void init() { JMenuBar menuBar = new JMenuBar(); createMenus(menuBar); setJMenuBar(menuBar); } public void createMenus(JMenuBar mbar) { mbar.add(createFileMenu()); mbar.add(createCascadingMenu()); } private JMenu createFileMenu() { JMenu fileMenu = new JMenu("File"); JMenuItem quitItem = new JMenuItem("Quit");
fileMenu.add(quitItem);
quitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); return fileMenu; } private JMenu createCascadingMenu() { JMenu cascading = new JMenu("Cascading", true); JMenu submenu = new JMenu("pull right menu 1", true); JMenu subsubmenu = new JMenu("pull right menu 2", true);
submenu.add("submenu item 1"); submenu.add("submenu item 2"); submenu.add("submenu item 3"); submenu.add("submenu item 4"); submenu.add("submenu item 5");
subsubmenu.add("subsubmenu item 1"); subsubmenu.add("subsubmenu item 2"); subsubmenu.add("subsubmenu item 3"); subsubmenu.add("subsubmenu item 4"); subsubmenu.add("subsubmenu item 5");
submenu.add(subsubmenu); cascading.add(submenu);
return cascading; } }
10.6.3 JMenu属性
10.6.4 JMenu事件
例10-13 监听菜单事件
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { JMenuBar mb = new JMenuBar(); JMenu fileMenu = new JMenu("File");
fileMenu.add("New ..."); fileMenu.add("Open ..."); fileMenu.add("Save"); fileMenu.add("Save As .."); fileMenu.addSeparator(); fileMenu.add("Exit");
mb.add(fileMenu); setJMenuBar(mb);
fileMenu.addMenuListener(new MenuListener() { public void menuCanceled(MenuEvent e) { System.out.println("menu canceled"); } public void menuSelected(MenuEvent e) { System.out.println("menu selected"); } public void menuDeselected(MenuEvent e) { System.out.println("menu deselected"); } }); } }
10.6.5 JMenu类总结
例10-14 显示一个菜单条中菜单的信息
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { Container contentPane = getContentPane();
final JMenuBar mb = new JMenuBar(); final MenuBarPrinter printer = new MenuBarPrinter();
JMenu fileMenu = new JMenu("File"); JMenu editMenu = new JMenu("Edit"); JMenuItem exitItem = new JMenuItem("Exit");
fileMenu.setMnemonic('F'); editMenu.setMnemonic('F');
fileMenu.add("New ..."); fileMenu.add("Open ..."); fileMenu.add("Save"); fileMenu.add("Save As .."); fileMenu.addSeparator(); fileMenu.add(exitItem);
editMenu.add("Cut"); editMenu.add("Copy"); editMenu.add("Paste");
mb.add(fileMenu); mb.add(editMenu); setJMenuBar(mb);
JButton button = new JButton("show menu information"); contentPane.setLayout(new FlowLayout()); contentPane.add(button);
button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { printer.print(mb); } });
exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); } } class MenuBarPrinter { static public void print(JMenuBar menubar) { int numMenus = menubar.getMenuCount(); JMenu nextMenu; JMenuItem nextItem;
System.out.println(); System.out.println("MenuBar has " + menubar.getMenuCount() + " menus"); System.out.println();
for(int i=0; i < numMenus; ++i) { nextMenu = menubar.getMenu(i); System.out.println(nextMenu.getText() + " menu ..."); System.out.println(nextMenu);
int numItems = nextMenu.getItemCount();
for(int j=0; j < numItems; ++j) { nextItem = nextMenu.getItem(j); System.out.println(nextItem); } System.out.println(); } } }
10.6.6 AWT兼容
10.7 菜单元素
例10-15 实现定制菜单元素
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*;
public class Test extends JApplet { public void init() { Container contentPane = getContentPane(); JMenuBar menuBar = new JMenuBar(); JMenu fileMenu = new JMenu("File");
fileMenu.add(new UnderlineElement("item one")); fileMenu.add(new UnderlineElement("item two")); fileMenu.add(new UnderlineElement("item three"));
menuBar.add(fileMenu); setJMenuBar(menuBar); } } class UnderlineElement extends JButton implements MenuElement { private boolean drawUnderline = false;
public UnderlineElement(String s) { super(s); setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); } public Component getComponent() { return this; } public MenuElement[] getSubElements() { return new MenuElement[0]; } public void menuSelectionChanged(boolean b) { drawUnderline = b; repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g);
Insets insets = getInsets();
if(drawUnderline) { FontMetrics fm = g.getFontMetrics(); g.drawLine(insets.left, insets.top + fm.getHeight(), fm.stringWidth(getText()), insets.top + fm.getHeight()); } } public void processKeyEvent(KeyEvent me, MenuElement[] element, MenuSelectionManager msm) { } public void processMouseEvent(MouseEvent me) { super.processMouseEvent(me); MenuSelectionManager.defaultManager().processMouseEvent( me); } public void processMouseEvent(MouseEvent me, MenuElement[] element, MenuSelectionManager msm) { if(me.getID() == MouseEvent.MOUSE_CLICKED || me.getID() == MouseEvent.MOUSE_RELEASED) {
msm.setSelectedPath(null); doClick(); } else msm.setSelectedPath(getPath()); } public MenuElement[] getPath() { MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager(); MenuElement oldPath[] = defaultManager.getSelectedPath(); MenuElement newPath[]; int len = oldPath.length;
if(len > 0) { MenuElement lastElement = oldPath[len-1]; Component parent = getParent();
if (lastElement == parent) { newPath = new MenuElement[len+1];
System.arraycopy(oldPath, 0, newPath, 0, len); newPath[len] = this; } else { int j;
for (j = len-1; j >= 0; j--) { if (oldPath[j].getComponent() == parent) break; } newPath = new MenuElement[j+2]; System.arraycopy(oldPath, 0, newPath, 0, j+1); newPath[j+1] = this; } } else return new MenuElement[0];
return newPath; } }
10.8 JPopupMenu
例10-16 使用弹出式菜单
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { Container contentPane = getContentPane(); final JLabel label = new JLabel("Click here for popup"); final JPopupMenu popup = new JPopupMenu(); final JSlider slider = new JSlider();
popup.add(new JMenuItem("Copy", new ImageIcon(this.getClass().getResource("copy.gif")))); popup.add(new CutAction(new ImageIcon(this.getClass().getResource("cut.gif")))); popup.addSeparator(); popup.add(slider);
label.addMouseListener(new MouseAdapter() { public void mousePressed (MouseEvent e) { popup.show(label, e.getX(), e.getY()); } }); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if( ! slider.getValueIsAdjusting()) popup.setVisible(false); } });
label.setHorizontalAlignment(JLabel.CENTER); contentPane.add(label, BorderLayout.CENTER); } class CutAction extends AbstractAction { java.net.URL iconurl; public CutAction(Icon icon) { //super("Cut", new ImageIcon("cut.gif")); super("Cut",icon); } public void actionPerformed(ActionEvent e) { System.out.println("cut"); } } }
10.8.1弹出式菜单触发器
例10-17 显示一个弹出式菜单以响应弹出式菜单触发器
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { private JPopupMenu popup = new JPopupMenu();
public void init() { Container contentPane = getContentPane();
popup.add(new JMenuItem("item one")); popup.add(new JMenuItem("item two")); popup.add(new JMenuItem("item three")); popup.add(new JMenuItem("item four"));
contentPane.addMouseListener(new MouseAdapter() { public void mousePressed (MouseEvent e) { showPopup(e); } public void mouseClicked (MouseEvent e) { showPopup(e); } public void mouseReleased(MouseEvent e) { showPopup(e); } }); } void showPopup(MouseEvent e) { if(e.isPopupTrigger()) popup.show(this, e.getX(), e.getY()); } }
10.8.2轻量/中量/重量弹出式菜单
10.8.3弹出式菜单调用者
例10-18 相对于其调用者显示弹出式菜单
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { JComboBox combobox = new JComboBox(); JPopupMenu popup = new JPopupMenu(); ColoredCanvas popupRelativeToMe; ColoredCanvas blueCanvas, redCanvas, yellowCanvas;
public void init() { Container contentPane = getContentPane(); blueCanvas = new ColoredCanvas(Color.blue); redCanvas = new ColoredCanvas(Color.red); yellowCanvas = new ColoredCanvas(Color.yellow); popupRelativeToMe = blueCanvas;
popup.add(new JMenuItem("item one")); popup.add(new JMenuItem("item two")); popup.add(new JMenuItem("item three")); popup.add(new JMenuItem("item four"));
contentPane.setLayout(new FlowLayout()); contentPane.add(new JLabel("Popup Over:")); contentPane.add(combobox); contentPane.add(blueCanvas); contentPane.add(redCanvas); contentPane.add(yellowCanvas);
combobox.addItem("Blue Canvas"); combobox.addItem("Yellow Canvas"); combobox.addItem("Red Canvas");
combobox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent event) { if(event.getStateChange() == ItemEvent.SELECTED) { JComboBox c = (JComboBox)event.getSource(); String label = (String)c.getSelectedItem();
if(label.equals("Blue Canvas")) popupRelativeToMe = blueCanvas; else if(label.equals("Red Canvas")) popupRelativeToMe = redCanvas; else if(label.equals("Yellow Canvas")) popupRelativeToMe = yellowCanvas;
popup.show(popupRelativeToMe, 5, 5); } } }); } } class ColoredCanvas extends JPanel { private Color color;
public ColoredCanvas(Color color) { this.color = color; } public void paintComponent(Graphics g) { super.paintComponent(g);
Dimension size = getSize(); g.setColor (color); g.fill3DRect(0,0,size.width-1,size.height-1,true); } public Dimension getPreferredSize() { return new Dimension(100,100); } }
10.8.4 JPopupMenu属性
10.8.5 JPopupMenu事件
例10-19 弹出式菜单事件的清单
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.beans.*;
public class Test extends JApplet { public void init() { final Container contentPane = getContentPane(); final JPopupMenu popup = new JPopupMenu(); popup.add(new JMenuItem("item one")); popup.add(new JMenuItem("item two")); popup.add(new JMenuItem("item three")); popup.add(new JMenuItem("item four"));
popup.addPopupMenuListener(new PopupMenuListener() { public void popupMenuCanceled(PopupMenuEvent e) { showStatus("menu canceled"); } public void popupMenuWillBecomeVisible( PopupMenuEvent e) { showStatus("menu will become visible"); } public void popupMenuWillBecomeInvisible( PopupMenuEvent e) { showStatus("menu will become invisible"); } }); addMouseListener(new MouseAdapter() { public void mousePressed (MouseEvent e) { popup.show(contentPane, e.getX(), e.getY()); } }); } }
10.8.6 JPopupMenu类总结
例10-20 为弹出式菜单设置位置、边框和调用者
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { private JPopupMenu popup = new JPopupMenu();
public void init() { Container contentPane = getContentPane(); JLabel label = new JLabel("Click To Show Popup");
popup.add(new JMenuItem("item one")); popup.add(new JMenuItem("item two")); popup.add(new JMenuItem("item three")); popup.add(new JMenuItem("item four"));
label.setHorizontalAlignment(JLabel.CENTER); contentPane.add(label, BorderLayout.CENTER);
label.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { //if(e.isPopupTrigger()) { popup.setVisible(true); //} } }); } }
10.8.7 AWT兼容
10.9 JMenuBar
例10-21 一个简单的菜单栏
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*;
public class Test extends JFrame { public Test() { final JMenuBar mb = new JMenuBar(); final JMenu fileMenu = new JMenu("File"); JMenuItem exitItem = new JMenuItem("Exit");
fileMenu.add("New ..."); fileMenu.add("Open ..."); fileMenu.add("Save"); fileMenu.add("Save As .."); fileMenu.addSeparator(); fileMenu.add(exitItem);
mb.add(new JLabel( new ImageIcon("smiley_face_small.gif")));
mb.add(fileMenu);
// Either one of the following two lines will // attach the menu bar to the application //setJMenuBar(mb); getRootPane().setJMenuBar(mb);
exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); System.exit(0); } }); System.out.println("component count: " + mb.getComponentCount()); System.out.println("first component: " + (mb.getComponentAtIndex(0)).getClass().getName());
System.out.println("menu count: " + (mb.getMenuCount()));
JMenu menu = mb.getMenu(0); if(menu == null) System.out.println("null menu"); else System.out.println("got menu"); } public static void main(String args[]) { GJApp.launch(new Test(), "A Menu Bar",300,300,300,250); } } class GJApp extends WindowAdapter { static private JPanel statusArea = new JPanel(); static private JLabel status = new JLabel(" "); static private ResourceBundle resources;
public static void launch(final JFrame f, String title, final int x, final int y, final int w, int h) { launch(f,title,x,y,w,h,null); } public static void launch(final JFrame f, String title, final int x, final int y, final int w, int h, String propertiesFilename) { f.setTitle(title); f.setBounds(x,y,w,h); f.setVisible(true);
statusArea.setBorder(BorderFactory.createEtchedBorder()); statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); statusArea.add(status); status.setHorizontalAlignment(JLabel.LEFT);
f.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE);
if(propertiesFilename != null) { resources = ResourceBundle.getBundle( propertiesFilename, Locale.getDefault()); }
f.addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { System.exit(0); } }); } static public JPanel getStatusArea() { return statusArea; } static public void showStatus(String s) { status.setText(s); } static Object getResource(String key) { if(resources != null) { return resources.getString(key); } return null; } }
10.9.1菜单栏菜单和组件
例10-22 菜单栏中的菜单和组件
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { Container contentPane = getContentPane();
final JMenuBar mb = new JMenuBar(); JMenu fileMenu = new JMenu("File"); JMenu editMenu = new JMenu("Edit"); JMenuItem exitItem = new JMenuItem("Exit"); JButton compButton = new JButton( "show menubar components ..."); JButton menuButton = new JButton( "show menubar menus ...");
fileMenu.add("New ..."); fileMenu.add("Open ..."); fileMenu.add("Save"); fileMenu.add("Save As .."); fileMenu.addSeparator(); fileMenu.add(exitItem);
editMenu.add("Undo"); editMenu.addSeparator(); editMenu.add("Cut"); editMenu.add("Copy"); editMenu.add("Paste");
mb.setMargin(new Insets(30,20,10,5)); mb.add(new JLabel(new ImageIcon("smiley.gif"))); mb.add(fileMenu); mb.add(editMenu);
setJMenuBar(mb); contentPane.setLayout(new FlowLayout()); contentPane.add(compButton); contentPane.add(menuButton);
exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); menuButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Component c; int cnt = mb.getMenuCount();
for(int i=0; i < cnt; ++i) { c = mb.getMenu(i); System.out.println(c); System.out.println(); } } }); compButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Component c; int cnt = mb.getComponentCount();
for(int i=0; i < cnt; ++i) { c = mb.getComponentAtIndex(i); System.out.println(c); System.out.println(); } } }); } }
10.9.2 JMenuBar属性
10.9.3 JMenuBar事件
10.9.4JMenuBar类总结
10.9.5 AWT兼容
10.10 JToolBar
例10-23 把组件添加到一个菜单栏中
import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class Test extends JApplet { public Test() { Container contentPane = getContentPane(); JToolBar tb = new JToolBar(); JComboBox fontCombo = new JComboBox(), fontSizeCombo = new JComboBox();
JButton newButton = new JButton(new ImageIcon("new.gif")), openButton = new JButton(new ImageIcon("open.gif")), cutButton = new JButton(new ImageIcon("cut.gif")), copyButton = new JButton(new ImageIcon("copy.gif")), pasteButton = new JButton(new ImageIcon("paste.gif"));
fontCombo.addItem("Helvetica"); fontCombo.addItem("Palatino"); fontCombo.addItem("Courier"); fontCombo.addItem("Times"); fontCombo.addItem("Times-Roman");
fontSizeCombo.addItem("10"); fontSizeCombo.addItem("12"); fontSizeCombo.addItem("14"); fontSizeCombo.addItem("16"); fontSizeCombo.addItem("18");
tb.add(newButton); tb.add(openButton);
tb.addSeparator();
tb.add(cutButton); tb.add(copyButton); tb.add(pasteButton);
tb.addSeparator();
tb.add(fontCombo); tb.add(fontSizeCombo);
contentPane.setLayout(new BorderLayout()); contentPane.add(tb, BorderLayout.NORTH); } }
例10-24 把组件添加到一个工具条中(方法2)
import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class Test extends JApplet { public Test() { Container contentPane = getContentPane(); JToolBar tb = new JToolBar(); JComboBox fontCombo = new JComboBox(), fontSizeCombo = new JComboBox();
JButton newButton = new JButton(new ImageIcon("new.gif")), openButton = new JButton(new ImageIcon("open.gif")), cutButton = new JButton(new ImageIcon("cut.gif")), copyButton = new JButton(new ImageIcon("copy.gif")), pasteButton = new JButton(new ImageIcon("paste.gif"));
fontCombo.addItem("Helvetica"); fontCombo.addItem("Palatino"); fontCombo.addItem("Courier"); fontCombo.addItem("Times"); fontCombo.addItem("Times-Roman");
fontSizeCombo.addItem("10"); fontSizeCombo.addItem("12"); fontSizeCombo.addItem("14"); fontSizeCombo.addItem("16"); fontSizeCombo.addItem("18");
tb.add(newButton); tb.add(openButton);
tb.addSeparator();
tb.add(cutButton); tb.add(copyButton); tb.add(pasteButton);
tb.addSeparator();
tb.add(fontCombo); tb.add(fontSizeCombo);
newButton.setAlignmentY(0.5f); openButton.setAlignmentY(0.5f); cutButton.setAlignmentY(0.5f); copyButton.setAlignmentY(0.5f); pasteButton.setAlignmentY(0.5f);
newButton.setAlignmentX(0.5f); openButton.setAlignmentX(0.5f); cutButton.setAlignmentX(0.5f); copyButton.setAlignmentX(0.5f); pasteButton.setAlignmentX(0.5f);
fontCombo.setMaximumSize(fontCombo.getPreferredSize()); fontSizeCombo.setMaximumSize( fontSizeCombo.getPreferredSize());
contentPane.setLayout(new BorderLayout()); contentPane.add(tb, BorderLayout.NORTH); } }
10.10.1滚过式工具条
例10-25 JTooBar.isRollover属性
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { Container contentPane = getContentPane(); JToolBar toolbar = new JToolBar();
toolbar.add(new NewAction()); toolbar.add(new OpenAction()); toolbar.addSeparator(); toolbar.add(new CutAction()); toolbar.add(new CopyAction()); toolbar.add(new PasteAction());
toolbar.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
contentPane.add(toolbar, BorderLayout.NORTH); } class NewAction extends AbstractAction { public NewAction() { putValue(Action.SMALL_ICON, new ImageIcon("new.gif")); } public void actionPerformed(ActionEvent event) { showStatus("new"); } } class OpenAction extends AbstractAction { public OpenAction() { putValue(Action.SMALL_ICON, new ImageIcon("open.gif")); } public void actionPerformed(ActionEvent event) { showStatus("open"); } } class CutAction extends AbstractAction { public CutAction() { putValue(Action.SMALL_ICON, new ImageIcon("cut.gif")); } public void actionPerformed(ActionEvent event) { showStatus("cut"); } } class CopyAction extends AbstractAction { public CopyAction() { putValue(Action.SMALL_ICON, new ImageIcon("copy.gif")); } public void actionPerformed(ActionEvent event) { showStatus("copy"); } } class PasteAction extends AbstractAction { public PasteAction() { putValue(Action.SMALL_ICON, new ImageIcon("paste.gif")); } public void actionPerformed(ActionEvent event) { showStatus("paste"); } } }
10.10.2在工具条中使用动作
例10-26 把动作添加到一个工具条中
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class Test extends JApplet { public void init() { Container contentPane = getContentPane(); JToolBar toolbar = new JToolBar();
toolbar.add(new NewAction()); toolbar.add(new OpenAction()); toolbar.addSeparator(); toolbar.add(new CutAction()); toolbar.add(new CopyAction()); toolbar.add(new PasteAction());
contentPane.add(toolbar, BorderLayout.NORTH); } class NewAction extends AbstractAction { public NewAction() { super("new", new ImageIcon("new.gif")); } public void actionPerformed(ActionEvent event) { showStatus("new"); } } class OpenAction extends AbstractAction { public OpenAction() { putValue(Action.SMALL_ICON, new ImageIcon("open.gif")); } public void actionPerformed(ActionEvent event) { showStatus("open"); } } class CutAction extends AbstractAction { public CutAction() { super("cut", new ImageIcon("cut.gif")); putValue(Action.SMALL_ICON, new ImageIcon("cut.gif")); } public void actionPerformed(ActionEvent event) { showStatus("cut"); } } class CopyAction extends AbstractAction { public CopyAction() { putValue(Action.SMALL_ICON, new ImageIcon("copy.gif")); } public void actionPerformed(ActionEvent event) { showStatus("copy"); } } class PasteAction extends AbstractAction { public PasteAction() { putValue(Action.SMALL_ICON, new ImageIcon("paste.gif")); } public void actionPerformed(ActionEvent event) { showStatus("paste"); } } }
10.10.3浮动工具条
例10-27 固定位置的工具提示
import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class Test extends JApplet { public Test() { Container contentPane = getContentPane(); JToolBar toolbar = new JToolBar();
String[] tooltipTexts = { "new", "open", "cut", "copy", "paste" }; ImageIcon[] icons = { new ImageIcon("new.gif"), new ImageIcon("open.gif"), new ImageIcon("cut.gif"), new ImageIcon("copy.gif"), new ImageIcon("paste.gif") };
JButton[] buttons = { new ButtonWithFixedTooltip(icons[0],tooltipTexts[0]), new ButtonWithFixedTooltip(icons[1],tooltipTexts[1]), new ButtonWithFixedTooltip(icons[2],tooltipTexts[2]), new ButtonWithFixedTooltip(icons[3],tooltipTexts[3]), new ButtonWithFixedTooltip(icons[4],tooltipTexts[4]) };
for(int i=0; i < buttons.length; ++i) { toolbar.add(buttons[i]);
if(tooltipTexts[i].equals("open")) toolbar.addSeparator(); } contentPane.add(toolbar, BorderLayout.NORTH); } } class ButtonWithFixedTooltip extends JButton { public ButtonWithFixedTooltip(Icon icon, String tooltipText) { super(icon); setToolTipText(tooltipText); } public Point getToolTipLocation(MouseEvent e){ Dimension size = getSize(); return new Point(0, size.height); } }
10.10.4位置固定的工具提示
略
10.10.5 JToolBar属性
略
10.10.6 JMenuBar事件
略
10.10.7 JMenuBar类总结
略
10.10.8 AWT兼容
略