epubjs
Version:
Render ePub documents in the browser, across many devices
140 lines (132 loc) • 22.3 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Menus</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Menus"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-17-SECT-7"/>Menus</h1></div></div></div><p><a id="idx10985" class="indexterm"/> <a id="idx11000" class="indexterm"/> A <a id="I_indexterm17_id796226" class="indexterm"/><code class="literal">JMenu</code> is a standard
pull-down menu with a fixed name. Menus can hold other menus as submenu
items, enabling you to implement complex menu structures. In Swing, menus
are first-class components, just like everything else. You can place them
any place a component would go. Another class, <a id="I_indexterm17_id796239" class="indexterm"/><code class="literal">JMenuBar</code>, holds menus in
the conventional horizontal bar. Menu bars are real components, too, so
you can place them any place you want in a container: top, bottom, or
middle. But in the middle of a container, it usually makes more sense to
use a <code class="literal">JComboBox</code> rather than some kind
of menu.</p><p>Menu items may have associated images and shortcut keys; there are
even menu items that look like checkboxes and radio buttons. Menu items
are really a kind of button. Like buttons, menu items fire action events
when they are selected. You can respond to menu items by registering
action listeners with them.</p><p>There are two ways to use the keyboard with menus. The first is
called <a id="I_indexterm17_id796265" class="indexterm"/><span class="emphasis"><em>mnemonics</em></span>. A mnemonic is one character
in the menu name. If you hold down the Alt key and type a menu’s mnemonic,
the menu drops down, just as if you had clicked on it with the mouse. Menu
items may also have mnemonics. Once a menu is dropped down, you can select
individual items in the same way.</p><p>Menu items may also have accelerators. An <a id="I_indexterm17_id796282" class="indexterm"/><span class="emphasis"><em>accelerator</em></span> is a key combination that
selects the menu item, whether or not the menu that contains it is
showing. A common example is the accelerator Ctrl-C, which is frequently
used as a shortcut for the Copy item in the Edit menu.</p><p>The next example demonstrates several different features of menus.
It creates a menu bar with three different menus. The first, Utensils,
contains several menu items, a submenu, a separator, and a Quit item that
includes both a mnemonic and an accelerator. The second menu, Spices,
contains menu items that look and act like checkboxes. Finally, the Cheese
menu demonstrates radio button menu items.</p><p>The application is shown in <a class="xref" href="ch17s06.html#learnjava3-CHP-17-FIG-7" title="Figure 17-7. The DinnerMenu application">Figure 17-7</a> with one of its menus dropped down.
Choosing Quit from the Utensils menu (or pressing Ctrl-Q) removes the
window.</p><a id="I_17_tt1023"/><pre class="programlisting"> <code class="c1">//file: DinnerMenu.java</code>
<code class="kn">import</code> <code class="nn">java.awt.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">java.awt.event.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">javax.swing.*</code><code class="o">;</code>
<code class="kd">public</code> <code class="kd">class</code> <code class="nc">DinnerMenu</code>
<code class="o">{</code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code><code class="n">String</code><code class="o">[]</code> <code class="n">args</code><code class="o">)</code> <code class="o">{</code>
<code class="n">JFrame</code> <code class="n">frame</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JFrame</code><code class="o">(</code><code class="s">"Dinner Menu"</code><code class="o">);</code>
<code class="c1">// create the Utensils menu</code>
<code class="n">JMenu</code> <code class="n">utensils</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JMenu</code><code class="o">(</code><code class="s">"Utensils"</code><code class="o">);</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">setMnemonic</code><code class="o">(</code><code class="n">KeyEvent</code><code class="o">.</code><code class="na">VK_U</code><code class="o">);</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Fork"</code><code class="o">));</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Knife"</code><code class="o">));</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Spoon"</code><code class="o">));</code>
<code class="n">JMenu</code> <code class="n">hybrid</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JMenu</code><code class="o">(</code><code class="s">"Hybrid"</code><code class="o">);</code>
<code class="n">hybrid</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Spork"</code><code class="o">));</code>
<code class="n">hybrid</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Spife"</code><code class="o">));</code>
<code class="n">hybrid</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Knork"</code><code class="o">));</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">hybrid</code><code class="o">);</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">addSeparator</code><code class="o">();</code>
<code class="c1">// do some fancy stuff with the Quit item</code>
<code class="n">JMenuItem</code> <code class="n">quitItem</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Quit"</code><code class="o">);</code>
<code class="n">quitItem</code><code class="o">.</code><code class="na">setMnemonic</code><code class="o">(</code><code class="n">KeyEvent</code><code class="o">.</code><code class="na">VK_Q</code><code class="o">);</code>
<code class="n">quitItem</code><code class="o">.</code><code class="na">setAccelerator</code><code class="o">(</code>
<code class="n">KeyStroke</code><code class="o">.</code><code class="na">getKeyStroke</code><code class="o">(</code><code class="n">KeyEvent</code><code class="o">.</code><code class="na">VK_Q</code><code class="o">,</code> <code class="n">Event</code><code class="o">.</code><code class="na">CTRL_MASK</code><code class="o">));</code>
<code class="n">quitItem</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code><code class="k">new</code> <code class="n">ActionListener</code><code class="o">()</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">actionPerformed</code><code class="o">(</code><code class="n">ActionEvent</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code> <code class="n">System</code><code class="o">.</code><code class="na">exit</code><code class="o">(</code><code class="mi">0</code><code class="o">);</code> <code class="o">}</code>
<code class="o">});</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">quitItem</code><code class="o">);</code>
<code class="c1">// create the Spices menu</code>
<code class="n">JMenu</code> <code class="n">spices</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JMenu</code><code class="o">(</code><code class="s">"Spices"</code><code class="o">);</code>
<code class="n">spices</code><code class="o">.</code><code class="na">setMnemonic</code><code class="o">(</code><code class="n">KeyEvent</code><code class="o">.</code><code class="na">VK_S</code><code class="o">);</code>
<code class="n">spices</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JCheckBoxMenuItem</code><code class="o">(</code><code class="s">"Thyme"</code><code class="o">));</code>
<code class="n">spices</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JCheckBoxMenuItem</code><code class="o">(</code><code class="s">"Rosemary"</code><code class="o">));</code>
<code class="n">spices</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JCheckBoxMenuItem</code><code class="o">(</code><code class="s">"Oregano"</code><code class="o">,</code> <code class="kc">true</code><code class="o">));</code>
<code class="n">spices</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JCheckBoxMenuItem</code><code class="o">(</code><code class="s">"Fennel"</code><code class="o">));</code>
<code class="c1">// create the Cheese menu</code>
<code class="n">JMenu</code> <code class="n">cheese</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JMenu</code><code class="o">(</code><code class="s">"Cheese"</code><code class="o">);</code>
<code class="n">cheese</code><code class="o">.</code><code class="na">setMnemonic</code><code class="o">(</code><code class="n">KeyEvent</code><code class="o">.</code><code class="na">VK_C</code><code class="o">);</code>
<code class="n">ButtonGroup</code> <code class="n">group</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ButtonGroup</code><code class="o">();</code>
<code class="n">JRadioButtonMenuItem</code> <code class="n">rbmi</code><code class="o">;</code>
<code class="n">rbmi</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JRadioButtonMenuItem</code><code class="o">(</code><code class="s">"Regular"</code><code class="o">,</code> <code class="kc">true</code><code class="o">);</code>
<code class="n">group</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">rbmi</code><code class="o">);</code>
<code class="n">cheese</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">rbmi</code><code class="o">);</code>
<code class="n">rbmi</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JRadioButtonMenuItem</code><code class="o">(</code><code class="s">"Extra"</code><code class="o">);</code>
<code class="n">group</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">rbmi</code><code class="o">);</code>
<code class="n">cheese</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">rbmi</code><code class="o">);</code>
<code class="n">rbmi</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JRadioButtonMenuItem</code><code class="o">(</code><code class="s">"Blue"</code><code class="o">);</code>
<code class="n">group</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">rbmi</code><code class="o">);</code>
<code class="n">cheese</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">rbmi</code><code class="o">);</code>
<code class="c1">// create a menu bar and use it in this JFrame</code>
<code class="n">JMenuBar</code> <code class="n">menuBar</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JMenuBar</code><code class="o">();</code>
<code class="n">menuBar</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">utensils</code><code class="o">);</code>
<code class="n">menuBar</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">spices</code><code class="o">);</code>
<code class="n">menuBar</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">cheese</code><code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setJMenuBar</code><code class="o">(</code><code class="n">menuBar</code><code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setDefaultCloseOperation</code><code class="o">(</code> <code class="n">JFrame</code><code class="o">.</code><code class="na">EXIT_ON_CLOSE</code> <code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setSize</code><code class="o">(</code><code class="mi">200</code><code class="o">,</code><code class="mi">200</code><code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setVisible</code><code class="o">(</code><code class="kc">true</code><code class="o">);</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>Yes, we know. Quit doesn’t belong in the Utensils menu. If it’s
driving you crazy, you can go back and add a File menu as an exercise when
we’re through.</p><p>Creating menus is pretty simple work. You create a <code class="literal">JMenu</code> object, specifying the menu’s title. Like
the text of <code class="literal">JButton</code>s and <code class="literal">JLabel</code>s, menu labels can contain simple HTML.
Then you just add <a id="I_indexterm17_id796359" class="indexterm"/><code class="literal">JMenuItem</code>s to the
<code class="literal">JMenu</code>. You can also add <code class="literal">JMenu</code>s to a <code class="literal">JMenu</code>; they show up as submenus. This is shown
in the creation of the Utensils menu:</p><a id="I_17_tt1025"/><pre class="programlisting"> <code class="n">JMenu</code> <code class="n">utensils</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JMenu</code><code class="o">(</code><code class="s">"Utensils"</code><code class="o">);</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">setMnemonic</code><code class="o">(</code><code class="n">KeyEvent</code><code class="o">.</code><code class="na">VK_U</code><code class="o">);</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Fork"</code><code class="o">));</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Knife"</code><code class="o">));</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Spoon"</code><code class="o">));</code>
<code class="n">JMenu</code> <code class="n">hybrid</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JMenu</code><code class="o">(</code><code class="s">"Hybrid"</code><code class="o">);</code>
<code class="n">hybrid</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Spork"</code><code class="o">));</code>
<code class="n">hybrid</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Spife"</code><code class="o">));</code>
<code class="n">hybrid</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Knork"</code><code class="o">));</code>
<code class="n">utensils</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">hybrid</code><code class="o">);</code></pre><div class="figure"><a id="learnjava3-CHP-17-FIG-7"/><div class="figure-contents"><div class="mediaobject"><a id="I_17_tt1024"/><img src="httpatomoreillycomsourceoreillyimages1707659.png.jpg" alt="The DinnerMenu application"/></div></div><p class="title">Figure 17-7. The DinnerMenu application</p></div><p>In the second line, we set the mnemonic for this menu using a
constant defined in the <code class="literal">KeyEvent</code> class,
which has static identifiers for all keys on the keyboard.</p><p>You can add those pretty separator lines with a single call:</p><a id="I_17_tt1026"/><pre class="programlisting"> <code class="n">utensils</code><code class="o">.</code><code class="na">addSeparator</code><code class="o">();</code></pre><p>The Quit menu item has some bells and whistles we should explain.
First, we create the menu item and set its mnemonic, just as we did before
for the Utensils menu:</p><a id="I_17_tt1027"/><pre class="programlisting"> <code class="n">JMenuItem</code> <code class="n">quitItem</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JMenuItem</code><code class="o">(</code><code class="s">"Quit"</code><code class="o">);</code>
<code class="n">quitItem</code><code class="o">.</code><code class="na">setMnemonic</code><code class="o">(</code><code class="n">KeyEvent</code><code class="o">.</code><code class="na">VK_Q</code><code class="o">);</code></pre><p>Now we want to create an accelerator for the menu item. We do this
with the help of a class called <a id="I_indexterm17_id796453" class="indexterm"/><code class="literal">KeyStroke</code> :</p><a id="I_17_tt1028"/><pre class="programlisting"> <code class="n">quitItem</code><code class="o">.</code><code class="na">setAccelerator</code><code class="o">(</code>
<code class="n">KeyStroke</code><code class="o">.</code><code class="na">getKeyStroke</code><code class="o">(</code><code class="n">KeyEvent</code><code class="o">.</code><code class="na">VK_Q</code><code class="o">,</code> <code class="n">Event</code><code class="o">.</code><code class="na">CTRL_MASK</code><code class="o">));</code></pre><p>Finally, to actually do something in response to the menu item, we
register an action listener:</p><a id="I_17_tt1029"/><pre class="programlisting"> <code class="n">quitItem</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code><code class="k">new</code> <code class="n">ActionListener</code><code class="o">()</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">actionPerformed</code><code class="o">(</code><code class="n">ActionEvent</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code> <code class="n">System</code><code class="o">.</code><code class="na">exit</code><code class="o">(</code><code class="mi">0</code><code class="o">);</code> <code class="o">}</code>
<code class="o">});</code></pre><p>Our action listener exits the application when the Quit item is
selected.</p><p>Creating the Spices menu is just as easy, except that we use
<code class="literal">JCheckBoxMenuItem</code>s instead of regular
<code class="literal">JMenuItem</code>s. The result is a menu full
of items that behave like checkboxes.</p><p>The next menu, Cheese, is a little more tricky. We want the items to
be radio buttons, but we need to place them in a <code class="literal">ButtonGroup</code> to ensure they are mutually
exclusive. Each item, then, is created, added to the button group, and
added to the menu itself.</p><p>The final step is to place the menus we’ve just created in a
<code class="literal">JMenuBar</code>. This is simply a component
that lays out menus in a horizontal bar. We have two options for adding it
to our <code class="literal">JFrame</code>. Because the <code class="literal">JMenuBar</code> is a real component, we could add it to
the content pane of the <code class="literal">JFrame</code>.
Instead, we use a convenience method called <a id="I_indexterm17_id796539" class="indexterm"/><code class="literal">setJMenuBar()</code>, which
automatically places the <code class="literal">JMenuBar</code> at
the top of the frame’s content pane. This saves us the trouble of altering
the layout or size of the content pane; it is adjusted to coexist
peacefully with the menu bar.<a id="I_indexterm17_id796558" class="indexterm"/><a id="I_indexterm17_id796566" class="indexterm"/></p></div></body></html>