The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
A menu provides a space-saving way to let the user choose one of several options. 菜单提供了一种节省空间的方式,让用户选择几个选项之一。Other components with which the user can make a one-of-many choice include combo boxes, lists, radio buttons, spinners, and tool bars. 用户可以选择的其他组件包括组合框、列表、单选按钮、微调器和工具栏。If any of your menu items performs an action that is duplicated by another menu item or by a tool-bar button, then in addition to this section you should read How to Use Actions.如果任何菜单项执行的操作被另一个菜单项或工具栏按钮复制,则除本节外,您还应阅读如何使用操作。
Menus are unique in that, by convention, they aren't placed with the other components in the UI. 菜单的独特之处在于,按照惯例,它们不会与UI中的其他组件一起放置。Instead, a menu usually appears either in a menu bar or as a popup menu. 相反,菜单通常显示在菜单栏或弹出菜单中。A menu bar contains one or more menus and has a customary, platform-dependent location usually along the top of a window. 菜单栏包含一个或多个菜单,并具有常规的、依赖于平台的位置;通常沿着窗户的顶部。A popup menu is a menu that is invisible until the user makes a platform-specific mouse action, such as pressing the right mouse button, over a popup-enabled component. 弹出菜单是一个不可见的菜单,直到用户在启用弹出菜单的组件上进行特定于平台的鼠标操作,如按下鼠标右键。The popup menu then appears under the cursor.然后,弹出菜单出现在光标下方。
The following figure shows many menu-related components: a menu bar, menus, menu items, radio button menu items, check box menu items, and separators. 下图显示了许多与菜单相关的组件:菜单栏、菜单、菜单项、单选按钮菜单项、复选框菜单项和分隔符。As you can see, a menu item can have either an image or text, or both. You can also specify other properties, such as font and color.如您所见,菜单项可以包含图像或文本,也可以同时包含图像和文本。您还可以指定其他属性,如字体和颜色。
The rest of this section teaches you about the menu components and tells you how to use various menu features:本节的其余部分将向您介绍菜单组件,并告诉您如何使用各种菜单功能:
Here is a picture of the inheritance hierarchy for the menu-related classes:以下是菜单相关类的继承层次结构图:
As the figure shows, menu items (including menus) are simply buttons. 如图所示,菜单项(包括菜单)只是按钮。You might be wondering how a menu, if it's only a button, shows its menu items. 您可能想知道,如果菜单只是一个按钮,它是如何显示菜单项的。The answer is that when a menu is activated, it automatically brings up a popup menu that displays the menu items.答案是,当菜单被激活时,它会自动弹出菜单,显示菜单项。
The following code creates the menus shown near the beginning of this menu section. 下面的代码创建了显示在此菜单部分开头附近的菜单。The bold lines of code create and connect the menu objects; the other code sets up or customizes the menu objects. 粗体代码行创建并连接菜单对象;其他代码设置或自定义菜单对象。You can find the entire program in 您可以在MenuLookDemo.java
. MenuLookDemo.java
中找到整个程序。Other required files are listed in the example index. 示例索引中列出了其他所需文件。
Because this code has no event handling, the menus do nothing useful except to look as they should. 因为这段代码没有事件处理,所以菜单除了看起来应该的样子之外没有任何用处。If you run the example, you'll notice that despite the lack of custom event handling, menus and submenus appear when they should, and the check boxes and radio buttons respond appropriately when the user chooses them.如果运行该示例,您会注意到,尽管缺少自定义事件处理,但菜单和子菜单在应该出现的时候出现,并且当用户选择它们时,复选框和单选按钮会相应响应。
//Where the GUI is created: JMenuBar menuBar; JMenu menu, submenu; JMenuItem menuItem; JRadioButtonMenuItem rbMenuItem; JCheckBoxMenuItem cbMenuItem; //Create the menu bar. menuBar = new JMenuBar(); //Build the first menu. menu = new JMenu("A Menu"); menu.setMnemonic(KeyEvent.VK_A); menu.getAccessibleContext().setAccessibleDescription( "The only menu in this program that has menu items"); menuBar.add(menu); //a group of JMenuItems menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_1, ActionEvent.ALT_MASK)); menuItem.getAccessibleContext().setAccessibleDescription( "This doesn't really do anything"); menu.add(menuItem); menuItem = new JMenuItem("Both text and icon", new ImageIcon("images/middle.gif")); menuItem.setMnemonic(KeyEvent.VK_B); menu.add(menuItem); menuItem = new JMenuItem(new ImageIcon("images/middle.gif")); menuItem.setMnemonic(KeyEvent.VK_D); menu.add(menuItem); //a group of radio button menu items menu.addSeparator(); ButtonGroup group = new ButtonGroup(); rbMenuItem = new JRadioButtonMenuItem("A radio button menu item"); rbMenuItem.setSelected(true); rbMenuItem.setMnemonic(KeyEvent.VK_R); group.add(rbMenuItem); menu.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem("Another one"); rbMenuItem.setMnemonic(KeyEvent.VK_O); group.add(rbMenuItem); menu.add(rbMenuItem); //a group of check box menu items menu.addSeparator(); cbMenuItem = new JCheckBoxMenuItem("A check box menu item"); cbMenuItem.setMnemonic(KeyEvent.VK_C); menu.add(cbMenuItem); cbMenuItem = new JCheckBoxMenuItem("Another one"); cbMenuItem.setMnemonic(KeyEvent.VK_H); menu.add(cbMenuItem); //a submenu menu.addSeparator(); submenu = new JMenu("A submenu"); submenu.setMnemonic(KeyEvent.VK_S); menuItem = new JMenuItem("An item in the submenu"); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_2, ActionEvent.ALT_MASK)); submenu.add(menuItem); menuItem = new JMenuItem("Another item"); submenu.add(menuItem); menu.add(submenu); //Build second menu in the menu bar. menu = new JMenu("Another Menu"); menu.setMnemonic(KeyEvent.VK_N); menu.getAccessibleContext().setAccessibleDescription( "This menu does nothing"); menuBar.add(menu); ... frame.setJMenuBar(theJMenuBar);
As the code shows, to set the menu bar for a 如代码所示,要设JFrame
, you use the setJMenuBar
method. 置JFrame
的菜单栏,可以使用setJMenuBar
方法。To add a 要将JMenu
to a JMenuBar
, you use the add(JMenu)
method. JMenu
添加到JMenuBar
,可以使用add(JMenu)
方法。To add menu items and submenus to a 要将菜单项和子菜单添加到JMenu
, you use the add(JMenuItem)
method.JMenu
,可以使用add(JMenuItem)
方法。
Menu items, like other components, can be in at most one container. 与其他组件一样,菜单项最多只能在一个容器中。If you try to add a menu item to a second menu, the menu item will be removed from the first menu before being added to the second. 如果您尝试将菜单项添加到第二个菜单,则该菜单项将在添加到第三个菜单之前从第一个菜单中删除。For a way of implementing multiple components that do the same thing, see How to Use Actions.有关实现多个组件执行相同操作的方法,请参阅如何使用操作。
Other methods in the preceding code include 前面代码中的其他方法包括setAccelerator
and setMnemonic
, which are discussed a little later in Enabling Keyboard Operation. setAccelerator
和setMnemonic
,稍后将在启用键盘操作中讨论。The 如何支持辅助技术中讨论了setAccessibleDescription
method is discussed in How to Support Assistive Technologies.setAccessibleDescription
方法。
To detect when the user chooses a 为了检测用户何时选择JMenuItem
, you can listen for action events (just as you would for a JButton
). JMenuItem
,您可以监听动作事件(就像监听JButton
一样)。To detect when the user chooses a 要检测用户何时选择JRadioButtonMenuItem
, you can listen for either action events or item events, as described in How to Use Radio Buttons. JRadioButtonMenuItem
,您可以监听操作事件或项事件,如如何使用单选按钮中所述。For 对于JCheckBoxMenuItem
s, you generally listen for item events, as described in How to Use Check Boxes.JCheckBoxMenuItems
,您通常会侦听项事件,如如何使用复选框中所述。
Here is the code that implements the event handling:以下是实现事件处理的代码:
public class MenuDemo ... implements ActionListener, ItemListener { ... public MenuDemo() { //...for each JMenuItem instance: menuItem.addActionListener(this); ... //for each JRadioButtonMenuItem: rbMenuItem.addActionListener(this); ... //for each JCheckBoxMenuItem: cbMenuItem.addItemListener(this); ... } public void actionPerformed(ActionEvent e) { //...Get information from the action event... //...Display it in the text area... } public void itemStateChanged(ItemEvent e) { //...Get information from the item event... //...Display it in the text area... }
For examples of handling action and item events, see the button, radio button, and check box sections, as well as the list of examples at the end of this section.有关处理操作和项目事件的示例,请参阅按钮、单选按钮和复选框部分,以及本部分末尾的示例列表。
Menus support two kinds of keyboard alternatives: mnemonics and accelerators. 菜单支持两种键盘选择:助记符和加速器。Mnemonics助记符 offer a way to use the keyboard to navigate the menu hierarchy, increasing the accessibility of programs. 提供一种使用键盘导航菜单层次结构的方法,增加程序的可访问性。Accelerators, on the other hand, offer keyboard shortcuts to bypass navigating the menu hierarchy. 另一方面,加速器提供键盘快捷键以绕过菜单层次结构的导航。Mnemonics are for all users; accelerators are for power users.助记符适用于所有用户;加速器是为超级用户设计的。
A mnemonic is a key that makes an already visible menu item be chosen. 助记符是一个键,用于选择已经可见的菜单项。For example, in 例如,在MenuDemo
the first menu has the mnemonic A, and its second menu item has the mnemonic B. MenuDemo
中,第一个菜单具有助记符号A,第二个菜单项具有助记字母B。This means that, when you run 这意味着,当您使用Java外观运行MenuDemo
with the Java look and feel, pressing the Alt and A keys makes the first menu appear. MenuDemo
时,按下Alt和A键将显示第一个菜单。While the first menu is visible, pressing the B key (with or without Alt) makes the second menu item be chosen. 当第一个菜单可见时,按B键(带或不带Alt)可选择第二个菜单项。A menu item generally displays its mnemonic by underlining the first occurrence of the mnemonic character in the menu item's text, as the following snapshot shows.菜单项通常通过在菜单项文本中第一次出现的助记符字符下下划线来显示其助记符,如下快照所示。
An accelerator is a key combination that causes a menu item to be chosen, whether or not it's visible. 加速键是一种组合键,可使菜单项被选择,无论其是否可见。For example, pressing the Alt and 2 keys in 例如,在MenuDemo
makes the first item in the first menu's submenu be chosen, without bringing up any menus. MenuDemo
中按Alt键和2键可选择第一个菜单子菜单中的第一个项目,而不显示任何菜单。Only leaf menu items menus that don't bring up other menus can have accelerators. 仅叶菜单项不显示其他菜单的菜单;它可以有加速器。The following snapshot shows how the Java look and feel displays a menu item that has an accelerator.下面的快照显示了Java外观如何显示具有加速器的菜单项。
You can specify a mnemonic either when constructing the menu item or with the 您可以在构造菜单项时或使用setMnemonic
method. setMnemonic
方法指定助记符。To specify an accelerator, use the 要指定加速器,请使用setAccelerator
method. setAccelerator
方法。Here are examples of setting mnemonics and accelerators:以下是设置助记符和加速器的示例:
//Setting the mnemonic when constructing a menu item: menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T); //Setting the mnemonic after creation time: menuItem.setMnemonic(KeyEvent.VK_T); //Setting the accelerator: menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_T, ActionEvent.ALT_MASK));
As you can see, you set a mnemonic by specifying the 如您所见,您可以通过指定与用户应按下的键对应的KeyEvent
constant corresponding to the key the user should press. KeyEvent
常量来设置助记符。To specify an accelerator you must use a 要指定加速器,必须使用KeyStroke
object, which combines a key (specified by a KeyEvent
constant) and a modifier-key mask (specified by an ActionEvent
constant).KeyStroke
对象,该对象组合键(由KeyEvent
常量指定)和修改器键掩码(由ActionEvent
常量规定)。
Because popup menus, unlike regular menus, aren't always contained by a component, accelerators in popup menu items don't work unless the popup menu is visible.因为与常规菜单不同,弹出菜单并不总是包含在组件中,所以除非弹出菜单可见,否则弹出菜单项中的加速器不起作用。
To bring up a popup menu ( 要打开弹出菜单(JPopupMenu
), you must register a mouse listener on each component that the popup menu should be associated with. JPopupMenu
),必须在弹出菜单应关联的每个组件上注册鼠标侦听器。The mouse listener must detect user requests that the popup menu be brought up.鼠标监听器必须检测用户请求弹出菜单。
The exact gesture that should bring up a popup menu varies by look and feel. 打开弹出菜单的确切姿势因外观和感觉而异。In Microsoft Windows, the user by convention brings up a popup menu by releasing the right mouse button while the cursor is over a component that is popup-enabled. 在Microsoft Windows中,根据惯例,当光标位于启用弹出功能的组件上时,用户通过释放鼠标右键打开弹出菜单。In the Java look and feel, the customary trigger is either pressing the right mouse button (for a popup that goes away when the button is released) or clicking it (for a popup that stays up). 在Java外观中,通常的触发是按下鼠标右键(对于释放按钮时消失的弹出窗口)或单击它(对于保持不变的弹出窗口)。
//...where instance variables are declared: JPopupMenu popup; //...where the GUI is constructed: //Create the popup menu. popup = new JPopupMenu(); menuItem = new JMenuItem("A popup menu item"); menuItem.addActionListener(this); popup.add(menuItem); menuItem = new JMenuItem("Another popup menu item"); menuItem.addActionListener(this); popup.add(menuItem); //Add listener to components that can bring up popup menus. MouseListener popupListener = new PopupListener(); output.addMouseListener(popupListener); menuBar.addMouseListener(popupListener); ... class PopupListener extends MouseAdapter { public void mousePressed(MouseEvent e) { maybeShowPopup(e); } public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { popup.show(e.getComponent(), e.getX(), e.getY()); } } }
Popup menus have a few interesting implementation details. 弹出菜单有一些有趣的实现细节。One is that every menu has an associated popup menu. When the menu is activated, it uses its associated popup menu to show its menu items.一个是每个菜单都有一个关联的弹出菜单。当菜单被激活时,它使用其关联的弹出菜单显示其菜单项。
Another detail is that a popup menu itself uses another component to implement the window containing the menu items. 另一个细节是弹出菜单本身使用另一个组件来实现包含菜单项的窗口。Depending on the circumstances under which the popup menu is displayed, the popup menu might implement its "window" using a lightweight component (such as a 根据弹出菜单的显示环境,弹出菜单可能使用轻量级组件(如JPanel
), a "mediumweight" component (such as a Panel
), or a heavyweight window (something that inherits from Window
).JPanel
)、中等权重组件(如Panel
)或重量级窗口(从Window
继承的东西)实现其“窗口”。
Lightweight popup windows are more efficient than heavyweight windows but, prior to the Java SE Platform 6 Update 12 release, they didn't work well if you had any heavyweight components inside your GUI. 轻量级弹出窗口比重量级窗口更高效,但在JavaSE平台6更新12发布之前,如果GUI中有任何重量级组件,它们就不能很好地工作。Specifically, when the lightweight popup's display area intersects the heavyweight component's display area, the heavyweight component is drawn on top. 具体而言,当轻量级弹出窗口的显示区域与重量级组件的显示区域相交时,重量级组件将绘制在顶部。This is one of the reasons that, prior to the 6u12 release, we recommended against mixing heavyweight and lightweight components. 这是在6u12发布之前,我们建议不要混合重量级和轻型组件的原因之一。If you are using an older release and absolutely need to use a heavyweight component in your GUI, then you can invoke 如果您使用的是较旧版本,并且绝对需要在GUI中使用重量级组件,则可以调用JPopupMenu.setLightWeightPopupEnabled(false)
to disable lightweight popup windows. JPopupMenu.setLightWeightPopupEnabled(false)
来禁用轻量级弹出窗口。For information on mixing components in the 6u12 release and later, please see Mixing Heavyweight and Lightweight Components.有关6u12版本及更高版本中混合组件的信息,请参阅混合重量级和轻型组件。
Because menus are made up of ordinary Swing components, you can easily customize them. 因为菜单是由普通的Swing组件组成的,所以您可以轻松地自定义它们。For example, you can add any lightweight component to a 例如,您可以将任何轻量级组件添加到JMenu
or JMenuBar
. JMenu
或JMenuBar
。And because 由于JMenuBar
uses BoxLayout
, you can customize a menu bar's layout just by adding invisible components to it. JMenuBar
使用BoxLayout
,您可以通过向菜单栏添加不可见的组件来定制菜单栏的布局。Here is an example of adding a glue component to a menu bar, so that the last menu is at the right edge of the menu bar:以下是向菜单栏添加粘合组件的示例,以便最后一个菜单位于菜单栏的右边缘:
//...create and add some menus... menuBar.add(Box.createHorizontalGlue()); //...create the rightmost menu... menuBar.add(rightMenu);
Here's the modified menu layout that MenuGlueDemo displays:以下是MenuGlueDemo显示的修改菜单布局:
Another way of changing the look of menus is to change the layout managers used to control them. 更改菜单外观的另一种方法是更改用于控制菜单的布局管理器。For example, you can change a menu bar's layout manager from the default left-to-right 例如,可以将菜单栏的布局管理器从默认的从左到右的BoxLayout
to something such as GridLayout
. BoxLayout
更改为GridLayout
。
Here's a picture of the menu layout that 以下是MenuLayoutDemo
creates:MenuLayoutDemo
创建的菜单布局的图片:
The following tables list the commonly used menu constructors and methods. 下表列出了常用的菜单构造函数和方法。The API for using menus falls into these categories:使用菜单的API分为以下几类:
JMenuBar() |
|
JMenu add(JMenu) |
|
void setJMenuBar(JMenuBar) JMenuBar getJMenuBar() (in JApplet , JDialog , JFrame , JInternalFrame , JRootPane ) |
JMenu() JMenu(String) JMenu(Action) |
Action specifies the text and other properties of the menu (see How to Use Actions).Action 指定菜单的文本和其他属性(请参见如何使用操作)。 |
JMenuItem add(JMenuItem) JMenuItem add(String) |
JMenuItem object that displays the specified text. |
void addSeparator() |
|
JMenuItem insert(JMenuItem, int) void insert(String, int) void insertSeparator(int) |
JMenuItem and String arguments are treated the same as in the corresponding add methods.JMenuItem 和String 参数的处理方式与相应的add 方法相同。 |
void remove(JMenuItem) void remove(int) void removeAll() |
JPopupMenu() JPopupMenu(String) |
|
JMenuItem add(JMenuItem) JMenuItem add(String) |
JMenuItem object that displays the specified text.JMenuItem 对象。 |
void addSeparator() |
|
void insert(Component, int) |
Component argument specifies the menu item to add.Component 参数指定要添加的菜单项。 |
void remove(int) void removeAll() |
|
static void setLightWeightPopupEnabled(boolean) |
JPopupMenu.setLightWeightPopupEnabled(false) .JPopupMenu.setLightWeightPopupEnabled(false) 。 |
void show(Component, int, int) |
JMenuItem() JMenuItem(String) JMenuItem(Icon) JMenuItem(String, Icon) JMenuItem(String, int) JMenuItem(Action) |
KeyEvent.VK_A . KeyEvent.VK_A 。
|
JCheckBoxMenuItem() JCheckBoxMenuItem(String) JCheckBoxMenuItem(Icon) JCheckBoxMenuItem(String, Icon) JCheckBoxMenuItem(String, boolean) JCheckBoxMenuItem(String, Icon, boolean) |
true for the boolean argument, then the menu item is initially selected (checked). true ,则最初选择(选中)菜单项。 |
JRadioButtonMenuItem() JRadioButtonMenuItem(String) JRadioButtonMenuItem(Icon) JRadioButtonMenuItem(String, Icon) JRadioButtonMenuItem(String, boolean) JRadioButtonMenuItem(Icon, boolean) JRadioButtonMenuItem(String, Icon, boolean) |
true for the boolean argument, then the menu item is initially selected. true ,则最初选择菜单项。 |
void setState(boolean) boolean getState() (in JCheckBoxMenuItem ) |
|
void setEnabled(boolean) |
true ,则启用菜单项。 |
void setMnemonic(int) |
KeyEvent class.KeyEvent 类中定义的VK常量之一。 |
void setAccelerator(KeyStroke) |
|
void setActionCommand(String) |
|
void addActionListener(ActionListener) void addItemListener(ItemListener) |
|
void setAction(Action) |
Action associated with the menu item. Action 。 |
AbstractButton . AbstractButton 。AbstractButton provides.AbstractButton 提供的其他有用方法的信息,请参阅按钮API。 |
Menus are used in a few of our examples.在一些示例中使用了菜单。
MenuLookDemo |
||
MenuDemo |
MenuLookDemo .MenuLookDemo 。 | |
PopupMenuDemo |
MenuDemo .MenuDemo 。 | |
MenuGlueDemo |
||
MenuLayoutDemo |
||
MenuSelectionManagerDemo |
| MenuDemo 。MenuSelectionManager , which tracks the state of the menu hierarchy.MenuSelectionManager ,它跟踪菜单层次结构的状态。 |
ActionDemo |
Action objects to implement menu items that duplicate functionality provided by tool bar buttons.Action 对象实现复制工具栏按钮提供的功能的菜单项。 | |
Framework |
| |
InternalFrameDemo |
See the Using JavaFX UI Controls: Menu tutorial to learn how to create menus in JavaFX.