UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

171 lines (147 loc) 24.2 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>The JTabbedPane Class</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="The JTabbedPane Class"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-17-SECT-12"/>The JTabbedPane Class</h1></div></div></div><p><a id="idx10982" class="indexterm"/> <a id="idx10997" class="indexterm"/> If you’ve ever right-clicked on the desktop to set your Display Properties in Windows, you already know what a <code class="literal">JTabbedPane</code> is. It’s a container with labeled tabs (e.g., Themes, Screen Saver, Appearance). When you click on a tab, a new set of controls is shown in the body of the <code class="literal">JTabbedPane</code>. In Swing, <code class="literal">JTabbedPane</code> is simply a specialized container.</p><p>Each tab has a name. To add a tab to the <code class="literal">JTabbedPane</code>, simply call <a id="I_indexterm17_id797575" class="indexterm"/><code class="literal">addTab()</code>. You’ll need to specify the name of the tab as well as a component that supplies the tab’s contents. Typically, it’s a container holding other components.</p><p>Even though the <code class="literal">JTabbedPane</code> only shows one set of components at a time, be aware that all the components on all the pages are alive and in memory at one time. If you have components that hog processor time or memory, try to put them into a “sleep” state when they are not showing.</p><p>The following example shows how to create a <code class="literal">JTabbedPane</code>. It adds standard Swing components to a tab named Controls. The second tab is filled with a scrollable image, which was presented in the previous examples.</p><a id="I_17_tt1037"/><pre class="programlisting"> <code class="c1">//file: TabbedPaneFrame.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="kn">import</code> <code class="nn">javax.swing.border.*</code><code class="o">;</code> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">TabbedPaneFrame</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">"TabbedPaneFrame"</code><code class="o">);</code> <code class="n">JTabbedPane</code> <code class="n">tabby</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JTabbedPane</code><code class="o">();</code> <code class="c1">// create the controls pane</code> <code class="n">JPanel</code> <code class="n">controls</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JPanel</code><code class="o">();</code> <code class="n">controls</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JLabel</code><code class="o">(</code><code class="s">"Service:"</code><code class="o">));</code> <code class="n">JList</code> <code class="n">list</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JList</code><code class="o">(</code> <code class="k">new</code> <code class="n">String</code><code class="o">[]</code> <code class="o">{</code> <code class="s">"Web server"</code><code class="o">,</code> <code class="s">"FTP server"</code> <code class="o">});</code> <code class="n">list</code><code class="o">.</code><code class="na">setBorder</code><code class="o">(</code><code class="n">BorderFactory</code><code class="o">.</code><code class="na">createEtchedBorder</code><code class="o">());</code> <code class="n">controls</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">list</code><code class="o">);</code> <code class="n">controls</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">JButton</code><code class="o">(</code><code class="s">"Start"</code><code class="o">));</code> <code class="c1">// create an image pane</code> <code class="n">String</code> <code class="n">filename</code> <code class="o">=</code> <code class="s">"Piazza di Spagna.jpg"</code><code class="o">;</code> <code class="n">JLabel</code> <code class="n">image</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JLabel</code><code class="o">(</code> <code class="k">new</code> <code class="n">ImageIcon</code><code class="o">(</code><code class="n">filename</code><code class="o">)</code> <code class="o">);</code> <code class="n">JComponent</code> <code class="n">picture</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JScrollPane</code><code class="o">(</code><code class="n">image</code><code class="o">);</code> <code class="n">tabby</code><code class="o">.</code><code class="na">addTab</code><code class="o">(</code><code class="s">"Controls"</code><code class="o">,</code> <code class="n">controls</code><code class="o">);</code> <code class="n">tabby</code><code class="o">.</code><code class="na">addTab</code><code class="o">(</code><code class="s">"Picture"</code><code class="o">,</code> <code class="n">picture</code><code class="o">);</code> <code class="n">frame</code><code class="o">.</code><code class="na">getContentPane</code><code class="o">().</code><code class="na">add</code><code class="o">(</code><code class="n">tabby</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">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">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>The code isn’t especially fancy, but the result is an impressive-looking user interface. The first tab is a <code class="literal">JPanel</code> that contains some other components, including a <code class="literal">JList</code> with an etched border. The second tab simply contains the <code class="literal">JLabel</code> with <code class="literal">ImageIcon</code> wrapped in a <code class="literal">JScrollPane</code>. The running example is shown in <a class="xref" href="ch17s10.html#learnjava3-CHP-17-FIG-11" title="Figure 17-11. Using a tabbed pane">Figure 17-11</a>.</p><p>Our example has only two tabs and they fit quite easily, but in a realistic application it is easy to run out of room. By default, when there are too many tabs to display in a single row, <code class="literal">JTabbedPane</code> automatically wraps them into additional rows. This behavior fits with the tab notion quite well, giving the appearance of a filing cabinet, but it also necessitates that when you select a tab from the back row, the tabs must be rearranged to bring the selected tab to the foreground. Many users find this confusing, and it violates a principal of user interface design that says that controls should remain in the same location. Alternatively, you can configure the tabbed pane to use a single, scrolling row of tabs by specifying a scrolling tab layout policy like this:</p><a id="I_17_tt1039"/><pre class="programlisting"> <code class="n">setTabLayoutPolicy</code><code class="o">(</code> <code class="n">JTabbedPane</code><code class="o">.</code><code class="na">SCROLL_TAB_LAYOUT</code> <code class="o">);</code></pre><div class="figure"><a id="learnjava3-CHP-17-FIG-11"/><div class="figure-contents"><div class="mediaobject"><a id="I_17_tt1038"/><img src="httpatomoreillycomsourceoreillyimages1707663.png.jpg" alt="Using a tabbed pane"/></div></div><p class="title">Figure 17-11. Using a tabbed pane</p></div><p>Java 6 introduced the ability to add custom components to tabs. The most common use of this capability is the addition of buttons on tabs for functions such as close, info, tear away, etc. The following example demonstrates how to use the new <code class="literal">setTabComponentAt(int index, Component component)</code> method to add a close button on each tab.<a id="I_indexterm17_id797717" class="indexterm"/><a id="I_indexterm17_id797724" class="indexterm"/></p><a id="I_programlisting17_id797731"/><pre class="programlisting"> <code class="c1">//file: ClosableTabs.java</code> <code class="kn">import</code> <code class="nn">javax.swing.*</code><code class="o">;</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="kd">public</code> <code class="kd">class</code> <code class="nc">ClosableTabs</code> <code class="kd">extends</code> <code class="n">JTabbedPane</code> <code class="o">{</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">addTab</code><code class="o">(</code><code class="n">String</code> <code class="n">title</code><code class="o">,</code> <code class="n">Color</code> <code class="n">color</code><code class="o">)</code> <code class="o">{</code> <code class="n">JPanel</code> <code class="n">pane</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JPanel</code><code class="o">();</code> <code class="n">pane</code><code class="o">.</code><code class="na">setBackground</code><code class="o">(</code><code class="n">color</code><code class="o">);</code> <code class="kt">int</code> <code class="n">loc</code> <code class="o">=</code> <code class="n">getTabCount</code><code class="o">();</code> <code class="n">insertTab</code><code class="o">(</code><code class="n">title</code><code class="o">,</code> <code class="kc">null</code><code class="o">,</code> <code class="n">pane</code><code class="o">,</code> <code class="kc">null</code><code class="o">,</code> <code class="n">loc</code><code class="o">);</code> <code class="n">setTabComponentAt</code><code class="o">(</code><code class="n">loc</code><code class="o">,</code> <code class="k">new</code> <code class="n">Tab</code><code class="o">(</code><code class="n">title</code><code class="o">));</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">SwingUtilities</code><code class="o">.</code><code class="na">invokeLater</code><code class="o">(</code><code class="k">new</code> <code class="n">Runnable</code><code class="o">(){</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">run</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">"Closable Tabs"</code><code class="o">);</code> <code class="n">ClosableTabs</code> <code class="n">tabs</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ClosableTabs</code><code class="o">();</code> <code class="n">tabs</code><code class="o">.</code><code class="na">addTab</code><code class="o">(</code><code class="s">"Blue"</code><code class="o">,</code> <code class="n">Color</code><code class="o">.</code><code class="na">BLUE</code><code class="o">);</code> <code class="n">tabs</code><code class="o">.</code><code class="na">addTab</code><code class="o">(</code><code class="s">"Green"</code><code class="o">,</code> <code class="n">Color</code><code class="o">.</code><code class="na">GREEN</code><code class="o">);</code> <code class="n">tabs</code><code class="o">.</code><code class="na">addTab</code><code class="o">(</code><code class="s">"Red"</code><code class="o">,</code> <code class="n">Color</code><code class="o">.</code><code class="na">RED</code><code class="o">);</code> <code class="n">frame</code><code class="o">.</code><code class="na">add</code><code class="o">(</code><code class="n">tabs</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="k">new</code> <code class="n">Dimension</code><code class="o">(</code><code class="mi">300</code><code class="o">,</code> <code class="mi">150</code><code class="o">));</code> <code class="n">frame</code><code class="o">.</code><code class="na">setLocationRelativeTo</code><code class="o">(</code><code class="kc">null</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> <code class="cm">/**</code> <code class="cm"> * The component used as a tab (i.e., the tab itself as opposed </code> <code class="cm"> * to the content)</code> <code class="cm"> */</code> <code class="kd">private</code> <code class="kd">class</code> <code class="nc">Tab</code> <code class="kd">extends</code> <code class="n">JPanel</code> <code class="o">{</code> <code class="kd">public</code> <code class="nf">Tab</code><code class="o">(</code><code class="n">String</code> <code class="n">title</code><code class="o">)</code> <code class="o">{</code> <code class="kd">super</code><code class="o">(</code><code class="k">new</code> <code class="n">FlowLayout</code><code class="o">(</code><code class="n">FlowLayout</code><code class="o">.</code><code class="na">LEFT</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="mi">0</code><code class="o">));</code> <code class="n">setOpaque</code><code class="o">(</code><code class="kc">false</code><code class="o">);</code> <code class="c1">// The tab's title</code> <code class="n">JLabel</code> <code class="n">label</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JLabel</code><code class="o">(</code><code class="n">title</code><code class="o">);</code> <code class="c1">// Creating a space to the right of the close button</code> <code class="n">label</code><code class="o">.</code><code class="na">setBorder</code><code class="o">(</code><code class="n">BorderFactory</code><code class="o">.</code><code class="na">createEmptyBorder</code><code class="o">(</code><code class="mi">0</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="mi">2</code><code class="o">));</code> <code class="n">add</code><code class="o">(</code><code class="n">label</code><code class="o">);</code> <code class="c1">// The tab's close button</code> <code class="n">JButton</code> <code class="n">button</code> <code class="o">=</code> <code class="k">new</code> <code class="n">CloseButton</code><code class="o">();</code> <code class="n">add</code><code class="o">(</code><code class="n">button</code><code class="o">);</code> <code class="c1">// This is necessary for vertical alignment of the </code> <code class="c1">// tab's content</code> <code class="n">setBorder</code><code class="o">(</code><code class="n">BorderFactory</code><code class="o">.</code><code class="na">createEmptyBorder</code><code class="o">(</code><code class="mi">2</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="mi">0</code><code class="o">));</code> <code class="o">}</code> <code class="kd">private</code> <code class="kd">class</code> <code class="nc">CloseButton</code> <code class="kd">extends</code> <code class="n">JButton</code> <code class="kd">implements</code> <code class="n">ActionListener</code> <code class="o">{</code> <code class="kd">public</code> <code class="nf">CloseButton</code><code class="o">()</code> <code class="o">{</code> <code class="n">setPreferredSize</code><code class="o">(</code><code class="k">new</code> <code class="n">Dimension</code><code class="o">(</code><code class="mi">17</code><code class="o">,</code> <code class="mi">17</code><code class="o">));</code> <code class="n">setOpaque</code><code class="o">(</code><code class="kc">false</code><code class="o">);</code> <code class="n">setContentAreaFilled</code><code class="o">(</code><code class="kc">false</code><code class="o">);</code> <code class="n">setBorderPainted</code><code class="o">(</code><code class="kc">false</code><code class="o">);</code> <code class="n">setRolloverEnabled</code><code class="o">(</code><code class="kc">true</code><code class="o">);</code> <code class="n">setFocusable</code><code class="o">(</code><code class="kc">false</code><code class="o">);</code> <code class="n">addActionListener</code><code class="o">(</code><code class="k">this</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="kt">int</code> <code class="n">i</code> <code class="o">=</code> <code class="n">ClosableTabs</code><code class="o">.</code><code class="na">this</code><code class="o">.</code><code class="na">indexOfTabComponent</code><code class="o">(</code> <code class="n">Tab</code><code class="o">.</code><code class="na">this</code><code class="o">);</code> <code class="k">if</code> <code class="o">(</code><code class="n">i</code> <code class="o">!=</code> <code class="o">-</code><code class="mi">1</code><code class="o">)</code> <code class="o">{</code> <code class="n">ClosableTabs</code><code class="o">.</code><code class="na">this</code><code class="o">.</code><code class="na">remove</code><code class="o">(</code><code class="n">i</code><code class="o">);</code> <code class="o">}</code> <code class="o">}</code> <code class="kd">protected</code> <code class="kt">void</code> <code class="nf">paintComponent</code><code class="o">(</code><code class="n">Graphics</code> <code class="n">g</code><code class="o">)</code> <code class="o">{</code> <code class="n">Graphics2D</code> <code class="n">g2</code> <code class="o">=</code> <code class="o">(</code><code class="n">Graphics2D</code><code class="o">)</code><code class="n">g</code><code class="o">;</code> <code class="n">g2</code><code class="o">.</code><code class="na">setStroke</code><code class="o">(</code><code class="k">new</code> <code class="n">BasicStroke</code><code class="o">(</code><code class="mi">2</code><code class="o">));</code> <code class="c1">// Show red on roll-over</code> <code class="n">g2</code><code class="o">.</code><code class="na">setColor</code><code class="o">(</code><code class="n">Color</code><code class="o">.</code><code class="na">BLACK</code><code class="o">);</code> <code class="k">if</code> <code class="o">(</code><code class="n">getModel</code><code class="o">().</code><code class="na">isRollover</code><code class="o">())</code> <code class="o">{</code> <code class="n">g2</code><code class="o">.</code><code class="na">setColor</code><code class="o">(</code><code class="n">Color</code><code class="o">.</code><code class="na">RED</code><code class="o">);</code> <code class="o">}</code> <code class="c1">// Paint the "X"</code> <code class="kt">int</code> <code class="n">offset</code> <code class="o">=</code> <code class="mi">5</code><code class="o">;</code> <code class="n">g2</code><code class="o">.</code><code class="na">drawLine</code><code class="o">(</code><code class="n">offset</code><code class="o">,</code> <code class="n">offset</code><code class="o">,</code> <code class="n">getWidth</code><code class="o">()</code> <code class="o">-</code> <code class="n">offset</code> <code class="o">-</code> <code class="mi">1</code><code class="o">,</code> <code class="n">getHeight</code><code class="o">()</code> <code class="o">-</code> <code class="n">offset</code> <code class="o">-</code> <code class="mi">1</code><code class="o">);</code> <code class="n">g2</code><code class="o">.</code><code class="na">drawLine</code><code class="o">(</code><code class="n">getWidth</code><code class="o">()</code> <code class="o">-</code> <code class="n">offset</code> <code class="o">-</code> <code class="mi">1</code><code class="o">,</code> <code class="n">offset</code><code class="o">,</code> <code class="n">offset</code><code class="o">,</code> <code class="n">getHeight</code><code class="o">()</code> <code class="o">-</code> <code class="n">offset</code> <code class="o">-</code> <code class="mi">1</code><code class="o">);</code> <code class="n">g2</code><code class="o">.</code><code class="na">dispose</code><code class="o">();</code> <code class="o">}</code> <code class="o">}</code> <code class="o">}</code> <code class="o">}</code></pre></div></body></html>