http://zetcode.com/tutorials/javaswingtutorial/menusandtoolbars/

在 Java Swing 教程的这一部分中,我们将使用菜单和工具栏。 在示例中,我们将创建常规菜单,子菜单,复选框菜单项,单选按钮菜单项,弹出菜单和工具栏。

Tweet

菜单是位于菜单栏中的一组命令。 工具栏上的按钮带有应用中的一些常用命令。

我们将使用以下组件:

  • JMenuBar - 实现菜单栏。
  • JMenu — 实现一个菜单,一个包含JMenuItems的弹出窗口,当用户在JMenuBar上选择一个项目时显示。
  • JMenuItem - 在菜单中实现一个项目。 用户选择它来执行操作。
  • JSeparator - 提供用于实现分隔线的通用组件。
  • JCheckBoxMenuItem ­- 实现可以选择或取消选择的菜单。
  • JRadioButtonMenuItem ­- 实现单选按钮菜单项,用于相互排斥的选择。
  • ButtonGroup ­- 为一组按钮创建一个多重排除范围。
  • JPopupMenu ­- 实现一个弹出菜单,一个弹出的小窗口并显示一系列选项。
  • JToolBar- 实现工具栏,该工具栏对于显示常用的Actions或控件很有用。

Swing JMenuBar

我们从一个简单的菜单栏示例开始。

com/zetcode/SimpleMenuEx.java

  1. package com.zetcode;
  2. import java.awt.EventQueue;
  3. import java.awt.event.KeyEvent;
  4. import javax.swing.ImageIcon;
  5. import javax.swing.JFrame;
  6. import javax.swing.JMenu;
  7. import javax.swing.JMenuBar;
  8. import javax.swing.JMenuItem;
  9. public class SimpleMenuEx extends JFrame {
  10. public SimpleMenuEx() {
  11. initUI();
  12. }
  13. private void initUI() {
  14. createMenuBar();
  15. setTitle("Simple menu");
  16. setSize(350, 250);
  17. setLocationRelativeTo(null);
  18. setDefaultCloseOperation(EXIT_ON_CLOSE);
  19. }
  20. private void createMenuBar() {
  21. var menuBar = new JMenuBar();
  22. var exitIcon = new ImageIcon("src/resources/exit.png");
  23. var fileMenu = new JMenu("File");
  24. fileMenu.setMnemonic(KeyEvent.VK_F);
  25. var eMenuItem = new JMenuItem("Exit", exitIcon);
  26. eMenuItem.setMnemonic(KeyEvent.VK_E);
  27. eMenuItem.setToolTipText("Exit application");
  28. eMenuItem.addActionListener((event) -> System.exit(0));
  29. fileMenu.add(eMenuItem);
  30. menuBar.add(fileMenu);
  31. setJMenuBar(menuBar);
  32. }
  33. public static void main(String[] args) {
  34. EventQueue.invokeLater(() -> {
  35. var ex = new SimpleMenuEx();
  36. ex.setVisible(true);
  37. });
  38. }
  39. }

我们的示例将显示一个菜单项。 选择退出菜单项,我们关闭应用。

  1. var menuBar = new JMenuBar();

使用JMenuBar创建菜单栏。

  1. var exitIcon = new ImageIcon("src/resources/exit.png");

菜单中显示退出图标。

  1. var fileMenu = new JMenu("File");
  2. fileMenu.setMnemonic(KeyEvent.VK_F);

使用JMenu类创建菜单对象。 也可以通过键盘访问菜单。 要将菜单绑定到特定键,我们使用setMnemonic()方法。 在我们的情况下,可以使用 Alt + F 快捷方式打开菜单。

  1. var eMenuItem = new JMenuItem("Exit", exitIcon);
  2. eMenuItem.setMnemonic(KeyEvent.VK_E);

菜单对象由菜单项组成。 使用JMenuItem类创建一个菜单项。 菜单项具有其自己的助记符。 可以使用 Alt + F + E 组合键激活。

  1. eMenuItem.setToolTipText("Exit application");

此代码行为菜单项创建工具提示。

  1. eMenuItem.addActionListener((event) -> System.exit(0));

JMenuItem是一种特殊的按钮组件。 我们向它添加了一个动作监听器,它终止了应用。

  1. fileMenu.add(eMenuItem);
  2. menuBar.add(fileMenu);

菜单项被添加到菜单对象,菜单对象被插入菜单栏。

  1. setJMenuBar(menuBar);

setJMenuBar()方法设置JFrame容器的菜单栏。

Java Swing 中的菜单和工具栏 - 图1

图:简单菜单

Swing 子菜单

每个菜单也可以有一个子菜单。 这样,我们可以将类似的命令分组。 例如,我们可以将用于隐藏和显示各种工具栏(例如个人栏,地址栏,状态栏或导航栏)的命令放在称为工具栏的子菜单中。 在菜单中,我们可以使用分隔符来分隔命令。 分隔符是一条简单的线。 通常的做法是使用单个分隔符将“新建”,“打开”,“保存”等命令与“打印”,“打印预览”等命令分开。 除助记符外,还可通过加速器启动菜单命令。

com/zetcode/SubmenuEx.java

  1. package com.zetcode;
  2. import javax.swing.ImageIcon;
  3. import javax.swing.JFrame;
  4. import javax.swing.JMenu;
  5. import javax.swing.JMenuBar;
  6. import javax.swing.JMenuItem;
  7. import java.awt.EventQueue;
  8. public class SubmenuEx extends JFrame {
  9. public SubmenuEx() {
  10. initUI();
  11. }
  12. private void initUI() {
  13. createMenuBar();
  14. setTitle("Submenu");
  15. setSize(360, 250);
  16. setLocationRelativeTo(null);
  17. setDefaultCloseOperation(EXIT_ON_CLOSE);
  18. }
  19. private void createMenuBar() {
  20. var menuBar = new JMenuBar();
  21. var iconNew = new ImageIcon("src/resources/new.png");
  22. var iconOpen = new ImageIcon("src/resources/open.png");
  23. var iconSave = new ImageIcon("src/resources/save.png");
  24. var iconExit = new ImageIcon("src/resources/exit.png");
  25. var fileMenu = new JMenu("File");
  26. var impMenu = new JMenu("Import");
  27. var newsMenuItem = new JMenuItem("Import newsfeed list...");
  28. var bookmarksMenuItem = new JMenuItem("Import bookmarks...");
  29. var importMailMenuItem = new JMenuItem("Import mail...");
  30. impMenu.add(newsMenuItem);
  31. impMenu.add(bookmarksMenuItem);
  32. impMenu.add(importMailMenuItem);
  33. var newMenuItem = new JMenuItem("New", iconNew);
  34. var openMenuItem = new JMenuItem("Open", iconOpen);
  35. var saveMenuItem = new JMenuItem("Save", iconSave);
  36. var exitMenuItem = new JMenuItem("Exit", iconExit);
  37. exitMenuItem.setToolTipText("Exit application");
  38. exitMenuItem.addActionListener((event) -> System.exit(0));
  39. fileMenu.add(newMenuItem);
  40. fileMenu.add(openMenuItem);
  41. fileMenu.add(saveMenuItem);
  42. fileMenu.addSeparator();
  43. fileMenu.add(impMenu);
  44. fileMenu.addSeparator();
  45. fileMenu.add(exitMenuItem);
  46. menuBar.add(fileMenu);
  47. setJMenuBar(menuBar);
  48. }
  49. public static void main(String[] args) {
  50. EventQueue.invokeLater(() -> {
  51. var ex = new SubmenuEx();
  52. ex.setVisible(true);
  53. });
  54. }
  55. }

本示例创建一个子菜单,并使用菜单分隔符分隔菜单项组。

  1. var impMenu = new JMenu("Import");
  2. ...
  3. fileMenu.add(impMenu);

子菜单与其他任何普通菜单一样。 它是用相同的方式创建的。 我们只需将菜单添加到现有菜单即可。

  1. exitMenuItem.setToolTipText("Exit application");

使用setToolTipText()方法将工具提示设置为“退出”菜单项。

  1. var newMenuItem = new JMenuItem("New", iconNew);

JMenuItem构造器创建带有标签和图标的菜单项。

  1. fileMenu.addSeparator();

分隔符是一条水平线,可以在视觉上分隔菜单项。 这样,我们可以将项目分组到一些合理的位置。 使用addSeparator()方法创建分隔符。

Java Swing 中的菜单和工具栏 - 图2

图:子菜单

Swing 助记符和加速器

助记符和加速键是使您能够通过键盘执行命令的快捷键。 助记符导航菜单层次结构以选择特定的菜单项,而加速器则跳过菜单层次结构并直接激活菜单项。

下面的示例利用操作,这些操作是可以由需要相同功能的不同组件共享的对象。

com/zetcode/ShortcutsEx.java

  1. package com.zetcode;
  2. import javax.swing.AbstractAction;
  3. import javax.swing.ImageIcon;
  4. import javax.swing.JFrame;
  5. import javax.swing.JMenu;
  6. import javax.swing.JMenuBar;
  7. import javax.swing.JMenuItem;
  8. import javax.swing.KeyStroke;
  9. import java.awt.EventQueue;
  10. import java.awt.event.ActionEvent;
  11. import java.awt.event.InputEvent;
  12. import java.awt.event.KeyEvent;
  13. public class ShortcutsEx extends JFrame {
  14. public ShortcutsEx() {
  15. initUI();
  16. }
  17. private void initUI() {
  18. createMenuBar();
  19. setTitle("Mnemonics and accelerators");
  20. setSize(360, 250);
  21. setLocationRelativeTo(null);
  22. setDefaultCloseOperation(EXIT_ON_CLOSE);
  23. }
  24. private void createMenuBar() {
  25. var menuBar = new JMenuBar();
  26. var iconNew = new ImageIcon("src/resources/new.png");
  27. var iconOpen = new ImageIcon("src/resources/open.png");
  28. var iconSave = new ImageIcon("src/resources/save.png");
  29. var iconExit = new ImageIcon("src/resources/exit.png");
  30. var fileMenu = new JMenu("File");
  31. fileMenu.setMnemonic(KeyEvent.VK_F);
  32. var newMenuItem = new JMenuItem(new MenuItemAction("New", iconNew,
  33. KeyEvent.VK_N));
  34. var openMenuItem = new JMenuItem(new MenuItemAction("Open", iconOpen,
  35. KeyEvent.VK_O));
  36. var saveMenuItem = new JMenuItem(new MenuItemAction("Save", iconSave,
  37. KeyEvent.VK_S));
  38. var exitMenuItem = new JMenuItem("Exit", iconExit);
  39. exitMenuItem.setMnemonic(KeyEvent.VK_E);
  40. exitMenuItem.setToolTipText("Exit application");
  41. exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,
  42. InputEvent.CTRL_DOWN_MASK));
  43. exitMenuItem.addActionListener((event) -> System.exit(0));
  44. fileMenu.add(newMenuItem);
  45. fileMenu.add(openMenuItem);
  46. fileMenu.add(saveMenuItem);
  47. fileMenu.addSeparator();
  48. fileMenu.add(exitMenuItem);
  49. menuBar.add(fileMenu);
  50. setJMenuBar(menuBar);
  51. }
  52. private class MenuItemAction extends AbstractAction {
  53. public MenuItemAction(String text, ImageIcon icon,
  54. Integer mnemonic) {
  55. super(text);
  56. putValue(SMALL_ICON, icon);
  57. putValue(MNEMONIC_KEY, mnemonic);
  58. }
  59. @Override
  60. public void actionPerformed(ActionEvent e) {
  61. System.out.println(e.getActionCommand());
  62. }
  63. }
  64. public static void main(String[] args) {
  65. EventQueue.invokeLater(() -> {
  66. var ex = new ShortcutsEx();
  67. ex.setVisible(true);
  68. });
  69. }
  70. }

该示例包含多个助记符和一个加速器。 三个菜单项共享一个动作对象。 选择这三个菜单项会使它们的操作命令打印到控制台。

  1. var fileMenu = new JMenu("File");
  2. fileMenu.setMnemonic(KeyEvent.VK_F);

助记符设置为“文件”菜单。 现在可以使用 Alt + F 快捷键激活菜单。

  1. var newMenuItem = new JMenuItem(new MenuItemAction("New", iconNew,
  2. KeyEvent.VK_N));

“新建”菜单项将操作对象作为参数。 其构造器将文本标签,图标和助记键作为参数。

  1. exitMenuItem.setMnemonic(KeyEvent.VK_E);

“退出”菜单项不使用操作对象。 其功能是单独构建的。 我们调用setMnemonic()方法来设置助记键。 要使用助记符,该组件必须在屏幕上可见。 因此,我们必须首先激活菜单对象,使“退出”菜单项可见,然后才能激活此菜单项。 这意味着此菜单项通过 Alt + F + E 组合键激活。

  1. exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,
  2. ActionEvent.CTRL_MASK));

加速器是直接启动菜单项的快捷键。 在我们的情况下,通过按 Ctrl + W 关闭我们的应用。 通过setAccelerator()方法设置加速器。

  1. private class MenuItemAction extends AbstractAction {
  2. public MenuItemAction(String text, ImageIcon icon,
  3. Integer mnemonic) {
  4. super(text);
  5. putValue(SMALL_ICON, icon);
  6. putValue(MNEMONIC_KEY, mnemonic);
  7. }
  8. @Override
  9. public void actionPerformed(ActionEvent e) {
  10. System.out.println(e.getActionCommand());
  11. }
  12. }

此动作类的一个实例由三个菜单项共享。 动作使用各种键来定义其功能。 putValue()方法将字符串值与指定的键关联。

Java Swing 中的菜单和工具栏 - 图3

图:助记符和加速器

带下划线的字符在视觉上提示助记符,加速器的快捷键显示在菜单项标签的旁边。

JCheckBoxMenuItem

JCheckBoxMenuItem是可以选择或取消选择的菜单项。 如果选中该菜单项,通常会在其旁边带有对勾标记。 如果未选择或取消选择,菜单项将显示而没有选中标记。 与常规菜单项一样,复选框菜单项可以具有与之关联的文本或图形图标,或两者都有。

com/zetcode/CheckBoxMenuItemEx.java

  1. package com.zetcode;
  2. import java.awt.BorderLayout;
  3. import java.awt.EventQueue;
  4. import java.awt.event.ItemEvent;
  5. import java.awt.event.KeyEvent;
  6. import javax.swing.BorderFactory;
  7. import javax.swing.JCheckBoxMenuItem;
  8. import javax.swing.JFrame;
  9. import javax.swing.JLabel;
  10. import javax.swing.JMenu;
  11. import javax.swing.JMenuBar;
  12. public class CheckBoxMenuItemEx extends JFrame {
  13. private JLabel statusBar;
  14. public CheckBoxMenuItemEx() {
  15. initUI();
  16. }
  17. private void initUI() {
  18. createMenuBar();
  19. statusBar = new JLabel("Ready");
  20. statusBar.setBorder(BorderFactory.createEtchedBorder());
  21. add(statusBar, BorderLayout.SOUTH);
  22. setTitle("JCheckBoxMenuItem");
  23. setSize(360, 250);
  24. setLocationRelativeTo(null);
  25. setDefaultCloseOperation(EXIT_ON_CLOSE);
  26. }
  27. private void createMenuBar() {
  28. var menuBar = new JMenuBar();
  29. var fileMenu = new JMenu("File");
  30. fileMenu.setMnemonic(KeyEvent.VK_F);
  31. var viewMenu = new JMenu("View");
  32. viewMenu.setMnemonic(KeyEvent.VK_V);
  33. var showStatusBarMenuItem = new JCheckBoxMenuItem("Show statubar");
  34. showStatusBarMenuItem.setMnemonic(KeyEvent.VK_S);
  35. showStatusBarMenuItem.setDisplayedMnemonicIndex(5);
  36. showStatusBarMenuItem.setSelected(true);
  37. showStatusBarMenuItem.addItemListener((e) -> {
  38. if (e.getStateChange() == ItemEvent.SELECTED) {
  39. statusBar.setVisible(true);
  40. } else {
  41. statusBar.setVisible(false);
  42. }
  43. });
  44. viewMenu.add(showStatusBarMenuItem);
  45. menuBar.add(fileMenu);
  46. menuBar.add(viewMenu);
  47. setJMenuBar(menuBar);
  48. }
  49. public static void main(String[] args) {
  50. EventQueue.invokeLater(() -> {
  51. var ex = new CheckBoxMenuItemEx();
  52. ex.setVisible(true);
  53. });
  54. }
  55. }

本示例使用JCheckBoxMenuItem来切换状态栏的可见性。

  1. statusBar = new JLabel("Ready");
  2. statusBar.setBorder(BorderFactory.createEtchedBorder());
  3. add(statusBar, BorderLayout.SOUTH);

状态栏是一个简单的JLabel组件。 我们在标签周围放置了凸起的EtchedBorder,以使其可见。

  1. var showStatusBarMenuItem = new JCheckBoxMenuItem("Show statubar");
  2. showStatusBarMenuItem.setMnemonic(KeyEvent.VK_S);
  3. showStatusBarMenuItem.setDisplayedMnemonicIndex(5);

JCheckBoxMenuItem创建一个复选框菜单项。 标签上有两个字母; 因此,我们使用setDisplayedMnemonicIndex()方法来选择要强调的内容。 我们选择了第二个。

  1. showStatusBarMenuItem.setSelected(true);

因为状态栏最初是可见的,所以我们调用JCheckBoxMenuItemsetSelected()方法来选择它。

  1. showStatusBarMenuItem.addItemListener((e) -> {
  2. if (e.getStateChange() == ItemEvent.SELECTED) {
  3. statusbar.setVisible(true);
  4. } else {
  5. statusbar.setVisible(false);
  6. }
  7. });

JCheckBoxMenuItem是一种特殊的按钮组件。 它实现了ItemSelectable接口。 ItemListener可用于监听其状态变化。 根据其状态,我们显示或隐藏状态栏。

Java Swing 中的菜单和工具栏 - 图4

图:JCheckBoxMenuItem

JRadioButtonMenuItem

JRadioButtonMenuItem使您可以从互斥的选项列表中进行选择。 选择特定的JRadioButtonMenuItem会取消选择所有其他项目。 将JRadioButtonMenuItems放入ButtonGroup

com/zetcode/RadioMenuItemEx.java

  1. package com.zetcode;
  2. import javax.swing.BorderFactory;
  3. import javax.swing.ButtonGroup;
  4. import javax.swing.JFrame;
  5. import javax.swing.JLabel;
  6. import javax.swing.JMenu;
  7. import javax.swing.JMenuBar;
  8. import javax.swing.JRadioButtonMenuItem;
  9. import java.awt.BorderLayout;
  10. import java.awt.EventQueue;
  11. import java.awt.event.ItemEvent;
  12. import java.awt.event.KeyEvent;
  13. public class RadioMenuItemEx extends JFrame {
  14. private JLabel statusBar;
  15. public RadioMenuItemEx() {
  16. initUI();
  17. }
  18. private void initUI() {
  19. createMenuBar();
  20. statusBar = new JLabel("Easy");
  21. statusBar.setBorder(BorderFactory.createEtchedBorder());
  22. add(statusBar, BorderLayout.SOUTH);
  23. setTitle("JRadioButtonMenuItem");
  24. setSize(360, 250);
  25. setLocationRelativeTo(null);
  26. setDefaultCloseOperation(EXIT_ON_CLOSE);
  27. }
  28. private void createMenuBar() {
  29. var menuBar = new JMenuBar();
  30. var difMenu = new JMenu("Difficulty");
  31. difMenu.setMnemonic(KeyEvent.VK_F);
  32. var difGroup = new ButtonGroup();
  33. var easyRMenuItem = new JRadioButtonMenuItem("Easy");
  34. easyRMenuItem.setSelected(true);
  35. difMenu.add(easyRMenuItem);
  36. easyRMenuItem.addItemListener((e) -> {
  37. if (e.getStateChange() == ItemEvent.SELECTED) {
  38. statusBar.setText("Easy");
  39. }
  40. });
  41. var mediumRMenuItem = new JRadioButtonMenuItem("Medium");
  42. difMenu.add(mediumRMenuItem);
  43. mediumRMenuItem.addItemListener((e) -> {
  44. if (e.getStateChange() == ItemEvent.SELECTED) {
  45. statusBar.setText("Medium");
  46. }
  47. });
  48. var hardRMenuItem = new JRadioButtonMenuItem("Hard");
  49. difMenu.add(hardRMenuItem);
  50. hardRMenuItem.addItemListener((e) -> {
  51. if (e.getStateChange() == ItemEvent.SELECTED) {
  52. statusBar.setText("Hard");
  53. }
  54. });
  55. difGroup.add(easyRMenuItem);
  56. difGroup.add(mediumRMenuItem);
  57. difGroup.add(hardRMenuItem);
  58. menuBar.add(difMenu);
  59. setJMenuBar(menuBar);
  60. }
  61. public static void main(String[] args) {
  62. EventQueue.invokeLater(() -> {
  63. var ex = new RadioMenuItemEx();
  64. ex.setVisible(true);
  65. });
  66. }
  67. }

该示例创建一个包含三个JRadioButtonMenuItem组件的菜单。

  1. var difGroup = new ButtonGroup();

ButtonGroup用于为一组按钮创建一个多重排除范围。

  1. var easyRMenuItem = new JRadioButtonMenuItem("Easy");
  2. easyRMenuItem.setSelected(true);
  3. difMenu.add(easyRMenuItem);

创建一个新的JRadioButtonMenuItem。 用setSelected()方法选择它,并用add()方法放置在按钮组中。

  1. easyRMenuItem.addItemListener((e) -> {
  2. if (e.getStateChange() == ItemEvent.SELECTED) {
  3. statusbar.setText("Easy");
  4. }
  5. });

ItemListener用于监听JRadioButtonMenuItem的事件。 getStateChange()确定状态更改的类型。 如果更改为ItemEvent.SELECTED,我们将在状态栏上更改状态。 (另一个状态更改是ItemEvent.DESELECTED。)

Java Swing 中的菜单和工具栏 - 图5

图:JRadioButtonMenuItem

右侧菜单

某些应用在右侧显示菜单。 通常,它是一个“帮助”菜单。

com/zetcode/RightMenuEx.java

  1. package com.zetcode;
  2. import java.awt.EventQueue;
  3. import javax.swing.Box;
  4. import javax.swing.JFrame;
  5. import javax.swing.JMenu;
  6. import javax.swing.JMenuBar;
  7. public class RightMenuEx extends JFrame {
  8. public RightMenuEx() {
  9. initUI();
  10. }
  11. private void initUI() {
  12. createMenuBar();
  13. setTitle("Right menu");
  14. setSize(300, 200);
  15. setLocationRelativeTo(null);
  16. setDefaultCloseOperation(EXIT_ON_CLOSE);
  17. }
  18. private void createMenuBar() {
  19. var menuBar = new JMenuBar();
  20. var fileMenu = new JMenu("File");
  21. var viewMenu = new JMenu("View");
  22. var toolsMenu = new JMenu("Tools");
  23. var helpMenu = new JMenu("Help");
  24. menuBar.add(fileMenu);
  25. menuBar.add(viewMenu);
  26. menuBar.add(toolsMenu);
  27. menuBar.add(Box.createHorizontalGlue());
  28. menuBar.add(helpMenu);
  29. setJMenuBar(menuBar);
  30. }
  31. public static void main(String[] args) {
  32. EventQueue.invokeLater(() -> {
  33. var ex = new RightMenuEx();
  34. ex.setVisible(true);
  35. });
  36. }
  37. }

该示例在左侧显示三个菜单,在右侧显示一个菜单。

  1. var menubar = new JMenuBar();
  2. var fileMenu = new JMenu("File");
  3. var viewMenu = new JMenu("View");
  4. var toolsMenu = new JMenu("Tools");
  5. var helpMenu = new JMenu("Help");

将创建一个菜单栏和四个菜单对象。

  1. menuBar.add(fileMenu);
  2. menuBar.add(viewMenu);
  3. menuBar.add(toolsMenu);
  4. menuBar.add(Box.createHorizontalGlue());
  5. menuBar.add(helpMenu);

添加三个菜单后,我们使用Box.createHorizontalGlue()方法在菜单栏上添加水平胶水。 胶水会吸收所有可用的额外空间。 这会将“帮助”菜单推到菜单栏的右侧。

Java Swing 中的菜单和工具栏 - 图6

图:右侧的帮助菜单

弹出菜单

菜单的另一种类型是弹出菜单。 Java Swing 具有此功能的JPopupMenu类。 它也称为上下文菜单,通常在右键单击组件时显示。 想法是仅提供与当前上下文相关的命令。 说我们有一张图片。 通过右键单击图像,我们将弹出一个窗口,其中包含用于保存,缩放或移动图像的命令。

com/zetcode/PopupMenuEx.java

  1. package com.zetcode;
  2. import java.awt.EventQueue;
  3. import java.awt.event.MouseAdapter;
  4. import java.awt.event.MouseEvent;
  5. import javax.swing.JFrame;
  6. import javax.swing.JMenuItem;
  7. import javax.swing.JPopupMenu;
  8. public class PopupMenuEx extends JFrame {
  9. private JPopupMenu popupMenu;
  10. public PopupMenuEx() {
  11. initUI();
  12. }
  13. private void initUI() {
  14. createPopupMenu();
  15. setTitle("JPopupMenu");
  16. setSize(300, 250);
  17. setLocationRelativeTo(null);
  18. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  19. }
  20. private void createPopupMenu() {
  21. popupMenu = new JPopupMenu();
  22. var maximizeMenuItem = new JMenuItem("Maximize");
  23. maximizeMenuItem.addActionListener((e) -> {
  24. if (getExtendedState() != JFrame.MAXIMIZED_BOTH) {
  25. setExtendedState(JFrame.MAXIMIZED_BOTH);
  26. maximizeMenuItem.setEnabled(false);
  27. }
  28. });
  29. popupMenu.add(maximizeMenuItem);
  30. var quitMenuItem = new JMenuItem("Quit");
  31. quitMenuItem.addActionListener((e) -> System.exit(0));
  32. popupMenu.add(quitMenuItem);
  33. addMouseListener(new MouseAdapter() {
  34. @Override
  35. public void mouseReleased(MouseEvent e) {
  36. if (getExtendedState() != JFrame.MAXIMIZED_BOTH) {
  37. maximizeMenuItem.setEnabled(true);
  38. }
  39. if (e.getButton() == MouseEvent.BUTTON3) {
  40. popupMenu.show(e.getComponent(), e.getX(), e.getY());
  41. }
  42. }
  43. });
  44. }
  45. public static void main(String[] args) {
  46. EventQueue.invokeLater(() -> {
  47. var ex = new PopupMenuEx();
  48. ex.setVisible(true);
  49. });
  50. }
  51. }

该示例显示了带有两个命令的弹出菜单。 第一个命令最大化窗口,第二个命令退出应用。

  1. popupMenu = new JPopupMenu();

JPopupMenu创建一个弹出菜单。

  1. var maximizeMenuItem = new JMenuItem("Maximize");
  2. maximizeMenuItem.addActionListener((e) -> {
  3. if (getExtendedState() != JFrame.MAXIMIZED_BOTH) {
  4. setExtendedState(JFrame.MAXIMIZED_BOTH);
  5. maximizeMenuItem.setEnabled(false);
  6. }
  7. });

弹出菜单由JMenuItems组成。 此项目将最大化框架。 getExtendedState()方法确定帧的状态。 可用状态为:NORMALICONIFIEDMAXIMIZED_HORIZMAXIMIZED_VERTMAXIMIZED_BOTH。 最大化帧后,我们将使用setEnabled()方法禁用菜单项。

  1. popupMenu.add(quitMenuItem);

菜单项通过add()插入到弹出菜单中。

  1. addMouseListener(new MouseAdapter() {
  2. @Override
  3. public void mouseReleased(MouseEvent e) {
  4. if (getExtendedState() != JFrame.MAXIMIZED_BOTH) {
  5. maximizeMenuItem.setEnabled(true);
  6. }
  7. if (e.getButton() == MouseEvent.BUTTON3) {
  8. popupMenu.show(e.getComponent(), e.getX(), e.getY());
  9. }
  10. }
  11. });

弹出菜单显示在我们用鼠标按钮单击的位置。 getButton()方法返回哪些鼠标按钮已更改状态。 MouseEvent.BUTTON3仅在右键单击时启用弹出菜单。 一旦窗口未最大化,我们将启用最大化菜单项。

Java Swing 中的菜单和工具栏 - 图7

图:JPopupMenu

工具栏

菜单将我们可以在应用中使用的命令分组。 使用工具栏可以快速访问最常用的命令。 在 Java Swing 中,JToolBar类在应用中创建一个工具栏。

com/zetcode/ToolbarEx.java

  1. package com.zetcode;
  2. import javax.swing.ImageIcon;
  3. import javax.swing.JButton;
  4. import javax.swing.JFrame;
  5. import javax.swing.JMenu;
  6. import javax.swing.JMenuBar;
  7. import javax.swing.JToolBar;
  8. import java.awt.BorderLayout;
  9. import java.awt.EventQueue;
  10. public class ToolbarEx extends JFrame {
  11. public ToolbarEx() {
  12. initUI();
  13. }
  14. private void initUI() {
  15. createMenuBar();
  16. createToolBar();
  17. setTitle("Simple toolbar");
  18. setSize(300, 200);
  19. setLocationRelativeTo(null);
  20. setDefaultCloseOperation(EXIT_ON_CLOSE);
  21. }
  22. private void createMenuBar() {
  23. var menuBar = new JMenuBar();
  24. var fileMenu = new JMenu("File");
  25. menuBar.add(fileMenu);
  26. setJMenuBar(menuBar);
  27. }
  28. private void createToolBar() {
  29. var toolbar = new JToolBar();
  30. var icon = new ImageIcon("src/resources/exit2.png");
  31. var exitButton = new JButton(icon);
  32. toolbar.add(exitButton);
  33. exitButton.addActionListener((e) -> System.exit(0));
  34. add(toolbar, BorderLayout.NORTH);
  35. }
  36. public static void main(String[] args) {
  37. EventQueue.invokeLater(() -> {
  38. var ex = new ToolbarEx();
  39. ex.setVisible(true);
  40. });
  41. }
  42. }

该示例创建一个带有一个退出按钮的工具栏。

  1. var toolbar = new JToolBar();

使用JToolBar创建工具栏。

  1. var exitButton = new JButton(icon);
  2. toolbar.add(exitButton);

我们创建一个按钮并将其添加到工具栏。 插入工具栏中的按钮是常规JButton

  1. add(toolbar, BorderLayout.NORTH);

工具栏位于BorderLayout的北部区域。 (BorderLayoutJFrameJWindowJDialogJInternalFrameJApplet内容窗格的默认布局管理器。

Java Swing 中的菜单和工具栏 - 图8

图:JToolBar

Swing 工具栏

通常需要在窗口上显示多个工具栏。 以下示例显示了如何执行此操作。

com/zetcode/ToolbarsEx.java

  1. package com.zetcode;
  2. import javax.swing.GroupLayout;
  3. import javax.swing.ImageIcon;
  4. import javax.swing.JButton;
  5. import javax.swing.JComponent;
  6. import javax.swing.JFrame;
  7. import javax.swing.JToolBar;
  8. import java.awt.EventQueue;
  9. public class ToolbarsEx extends JFrame {
  10. public ToolbarsEx() {
  11. initUI();
  12. }
  13. private void initUI() {
  14. createToolBars();
  15. setTitle("Toolbars");
  16. setSize(360, 250);
  17. setLocationRelativeTo(null);
  18. setDefaultCloseOperation(EXIT_ON_CLOSE);
  19. }
  20. private void createToolBars() {
  21. var toolbar1 = new JToolBar();
  22. var toolbar2 = new JToolBar();
  23. var newIcon = new ImageIcon("src/resources/new2.png");
  24. var openIcon = new ImageIcon("src/resources/open2.png");
  25. var saveIcon = new ImageIcon("src/resources/save2.png");
  26. var exitIcon = new ImageIcon("src/resources/exit2.png");
  27. var newBtn = new JButton(newIcon);
  28. var openBtn = new JButton(openIcon);
  29. var saveBtn = new JButton(saveIcon);
  30. toolbar1.add(newBtn);
  31. toolbar1.add(openBtn);
  32. toolbar1.add(saveBtn);
  33. var exitBtn = new JButton(exitIcon);
  34. toolbar2.add(exitBtn);
  35. exitBtn.addActionListener((e) -> System.exit(0));
  36. createLayout(toolbar1, toolbar2);
  37. }
  38. private void createLayout(JComponent... arg) {
  39. var pane = getContentPane();
  40. var gl = new GroupLayout(pane);
  41. pane.setLayout(gl);
  42. gl.setHorizontalGroup(gl.createParallelGroup()
  43. .addComponent(arg[0], GroupLayout.DEFAULT_SIZE,
  44. GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
  45. .addComponent(arg[1], GroupLayout.DEFAULT_SIZE,
  46. GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
  47. );
  48. gl.setVerticalGroup(gl.createSequentialGroup()
  49. .addComponent(arg[0])
  50. .addComponent(arg[1])
  51. );
  52. }
  53. public static void main(String[] args) {
  54. EventQueue.invokeLater(() -> {
  55. var ex = new ToolbarsEx();
  56. ex.setVisible(true);
  57. });
  58. }
  59. }

窗口顶部显示两个工具栏。

  1. var toolbar1 = new JToolBar();
  2. var toolbar2 = new JToolBar();

使用JToolBar创建两个工具栏对象。

  1. private void createLayout(JComponent... arg) {
  2. var pane = getContentPane();
  3. var gl = new GroupLayout(pane);
  4. pane.setLayout(gl);
  5. gl.setHorizontalGroup(gl.createParallelGroup()
  6. .addComponent(arg[0], GroupLayout.DEFAULT_SIZE,
  7. GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
  8. .addComponent(arg[1], GroupLayout.DEFAULT_SIZE,
  9. GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
  10. );
  11. gl.setVerticalGroup(gl.createSequentialGroup()
  12. .addComponent(arg[0])
  13. .addComponent(arg[1])
  14. );
  15. }

GroupLayout管理器用于将工具栏放置在容器的顶部。

Java Swing 中的菜单和工具栏 - 图9

图:工具栏 s

在 Java Swing 教程的这一部分中,我们提到了菜单和工具栏。 我们使用了以下组件:JMenuBarJMenuJMenuItemJSeparatorJCheckBoxMenuItemJRadioButtonMenuItemButtonGroupJPopupMenuJToolBar