epubjs
Version:
Render ePub documents in the browser, across many devices
350 lines (336 loc) • 45.4 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>HelloJava3: The Button Strikes!</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="HelloJava3: The Button Strikes!"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-2-SECT-4"/>HelloJava3: The Button Strikes!</h1></div></div></div><p>Now we can move on to some fun stuff. <code class="literal">HelloJava3</code> brings us a new graphical interface
component: <code class="literal">JButton</code>.<sup>[<a id="learnjava3-CHP-2-FNOTE-3" href="#ftn.learnjava3-CHP-2-FNOTE-3" class="footnote">4</a>]</sup> In this example, we add a <code class="literal">JButton</code> component to our application that
changes the color of our text each time the button is pressed. The
draggable-message capability is still there, too. Our new code looks like
this:</p><a id="I_2_tt48"/><pre class="programlisting"> <code class="c1">//file: HelloJava3.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">HelloJava3</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">"HelloJava3"</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="k">new</code> <code class="n">HelloComponent3</code><code class="o">(</code><code class="s">"Hello, Java!"</code><code class="o">)</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">300</code><code class="o">,</code> <code class="mi">300</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="kd">class</code> <code class="nc">HelloComponent3</code> <code class="kd">extends</code> <code class="n">JComponent</code>
<code class="kd">implements</code> <code class="n">MouseMotionListener</code><code class="o">,</code> <code class="n">ActionListener</code>
<code class="o">{</code>
<code class="n">String</code> <code class="n">theMessage</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">messageX</code> <code class="o">=</code> <code class="mi">125</code><code class="o">,</code> <code class="n">messageY</code> <code class="o">=</code> <code class="mi">95</code><code class="o">;</code> <code class="c1">// Coordinates of the message</code>
<code class="n">JButton</code> <code class="n">theButton</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">colorIndex</code><code class="o">;</code> <code class="c1">// Current index into someColors</code>
<code class="kd">static</code> <code class="n">Color</code><code class="o">[]</code> <code class="n">someColors</code> <code class="o">=</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="n">Color</code><code class="o">.</code><code class="na">red</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">Color</code><code class="o">.</code><code class="na">blue</code><code class="o">,</code> <code class="n">Color</code><code class="o">.</code><code class="na">magenta</code> <code class="o">};</code>
<code class="kd">public</code> <code class="nf">HelloComponent3</code><code class="o">(</code> <code class="n">String</code> <code class="n">message</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">theMessage</code> <code class="o">=</code> <code class="n">message</code><code class="o">;</code>
<code class="n">theButton</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JButton</code><code class="o">(</code><code class="s">"Change Color"</code><code class="o">);</code>
<code class="n">setLayout</code><code class="o">(</code> <code class="k">new</code> <code class="n">FlowLayout</code><code class="o">()</code> <code class="o">);</code>
<code class="n">add</code><code class="o">(</code> <code class="n">theButton</code> <code class="o">);</code>
<code class="n">theButton</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code> <code class="k">this</code> <code class="o">);</code>
<code class="n">addMouseMotionListener</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">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">g</code><code class="o">.</code><code class="na">drawString</code><code class="o">(</code> <code class="n">theMessage</code><code class="o">,</code> <code class="n">messageX</code><code class="o">,</code> <code class="n">messageY</code> <code class="o">);</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">mouseDragged</code><code class="o">(</code> <code class="n">MouseEvent</code> <code class="n">e</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">messageX</code> <code class="o">=</code> <code class="n">e</code><code class="o">.</code><code class="na">getX</code><code class="o">();</code>
<code class="n">messageY</code> <code class="o">=</code> <code class="n">e</code><code class="o">.</code><code class="na">getY</code><code class="o">();</code>
<code class="n">repaint</code><code class="o">();</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">mouseMoved</code><code class="o">(</code> <code class="n">MouseEvent</code> <code class="n">e</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="c1">// Did somebody push our button?</code>
<code class="k">if</code> <code class="o">(</code><code class="n">e</code><code class="o">.</code><code class="na">getSource</code><code class="o">()</code> <code class="o">==</code> <code class="n">theButton</code><code class="o">)</code>
<code class="n">changeColor</code><code class="o">();</code>
<code class="o">}</code>
<code class="kd">synchronized</code> <code class="kd">private</code> <code class="kt">void</code> <code class="nf">changeColor</code><code class="o">()</code> <code class="o">{</code>
<code class="c1">// Change the index to the next color, awkwardly.</code>
<code class="k">if</code> <code class="o">(++</code><code class="n">colorIndex</code> <code class="o">==</code> <code class="n">someColors</code><code class="o">.</code><code class="na">length</code><code class="o">)</code>
<code class="n">colorIndex</code> <code class="o">=</code> <code class="mi">0</code><code class="o">;</code>
<code class="n">setForeground</code><code class="o">(</code> <code class="n">currentColor</code><code class="o">()</code> <code class="o">);</code> <code class="c1">// Use the new color.</code>
<code class="n">repaint</code><code class="o">();</code>
<code class="o">}</code>
<code class="kd">synchronized</code> <code class="kd">private</code> <code class="n">Color</code> <code class="nf">currentColor</code><code class="o">()</code> <code class="o">{</code>
<code class="k">return</code> <code class="n">someColors</code><code class="o">[</code><code class="n">colorIndex</code><code class="o">];</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>Compile <code class="literal">HelloJava3</code> in the same
way as the other applications. Run the example, and you should see the
display shown in <a class="xref" href="ch02s05.html#learnjava3-CHP-2-FIG-5" title="Figure 2-9. The HelloJava3 application">Figure 2-9</a>. Drag the text.
Each time you press the button, the color should change. Call your
friends! Test yourself for color blindness!</p><div class="figure"><a id="learnjava3-CHP-2-FIG-5"/><div class="figure-contents"><div class="mediaobject"><a id="I_2_tt49"/><img src="httpatomoreillycomsourceoreillyimages1707607.png" alt="The HelloJava3 application"/></div></div><p class="title">Figure 2-9. The HelloJava3 application</p></div><p>What have we added this time? Well, for starters, we have a new
variable:</p><a id="I_2_tt50"/><pre class="programlisting"> <code class="n">JButton</code> <code class="n">theButton</code><code class="o">;</code></pre><p>The <code class="literal">theButton</code> variable is of type
<code class="literal">JButton</code> and is going to hold an
instance of the <a id="I_indexterm2_id640818" class="indexterm"/><code class="literal">javax.swing.JButton</code>
class. The <code class="literal">JButton</code> class, as you might
expect, represents a graphical button, like other buttons in your
windowing system.</p><p>Three additional lines in the constructor create the button and
display it:</p><a id="I_2_tt51"/><pre class="programlisting"> <code class="n">theButton</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JButton</code><code class="o">(</code><code class="s">"Change Color"</code><code class="o">);</code>
<code class="n">setLayout</code><code class="o">(</code> <code class="k">new</code> <code class="n">FlowLayout</code><code class="o">()</code> <code class="o">);</code>
<code class="n">add</code><code class="o">(</code> <code class="n">theButton</code> <code class="o">);</code></pre><p>In the first line, the <a id="I_indexterm2_id640849" class="indexterm"/><code class="literal">new</code> keyword creates an
instance of the <code class="literal">JButton</code> class. The next
line affects the way our component will be used as a container to hold the
button. It tells <code class="literal">HelloComponent3</code> how it
should arrange components that are added to it for display—in this case,
to use a scheme called a <code class="literal">FlowLayout</code>
(more on that coming up). Finally, it adds the button to our component,
just like we added <code class="literal">HelloComponent3</code> to
the content pane of the <code class="literal">JFrame</code> in the
<code class="literal">main()</code> method.</p><div class="sect2" title="Method Overloading"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.1"/>Method Overloading</h2></div></div></div><p><a id="idx10081" class="indexterm"/> <a id="idx10100" class="indexterm"/> <a id="idx10103" class="indexterm"/> <code class="literal">JButton</code> has more than
one constructor. A class can have multiple constructors, each taking
different parameters and presumably using them to do different kinds of
setup. When a class has multiple constructors, Java chooses the correct
one based on the types of arguments used with them. We call the <code class="literal">JButton</code> constructor with a <code class="literal">String</code> argument, so Java locates the
constructor method of the <code class="literal">JButton</code>
class that takes a single <code class="literal">String</code>
argument and uses it to set up the object. This is called
<span class="emphasis"><em>method overloading</em></span>. All methods in Java (not just
constructors) can be overloaded; this is another aspect of the
object-oriented programming principle of <a id="I_indexterm2_id640983" class="indexterm"/><span class="emphasis"><em>polymorphism</em></span>.</p><p>Overloaded constructors generally provide a convenient way to
initialize a new object. The <code class="literal">JButton</code>
constructor we’ve used sets the text of the button as it is
created:</p><a id="I_2_tt52"/><pre class="programlisting"> <code class="n">theButton</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JButton</code><code class="o">(</code><code class="s">"Change Color"</code><code class="o">);</code></pre><p>This is shorthand for creating the button and setting its label,
like this:<a id="I_indexterm2_id641013" class="indexterm"/><a id="I_indexterm2_id641020" class="indexterm"/><a id="I_indexterm2_id641027" class="indexterm"/></p><a id="I_2_tt53"/><pre class="programlisting"> <code class="n">theButton</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JButton</code><code class="o">();</code>
<code class="n">theButton</code><code class="o">.</code><code class="na">setText</code><code class="o">(</code><code class="s">"Change Color"</code><code class="o">);</code></pre></div><div class="sect2" title="Components"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.2"/>Components</h2></div></div></div><p><a id="I_indexterm2_id641050" class="indexterm"/> <a id="I_indexterm2_id641061" class="indexterm"/>We have used the terms <a id="I_indexterm2_id641070" class="indexterm"/><span class="emphasis"><em>component</em></span> and <a id="I_indexterm2_id641080" class="indexterm"/><span class="emphasis"><em>container</em></span> somewhat loosely to
describe graphical elements of Java applications, but these terms are
used in the names of actual classes in the <code class="literal">java.awt</code> package.</p><p><code class="literal">Component</code> is a base class from
which all of Java’s GUI components are derived. It contains variables
that represent the location, shape, general appearance, and status of
the object as well as methods for basic painting and event handling.
<a id="I_indexterm2_id641108" class="indexterm"/><code class="literal">javax.swing.JComponent</code>
extends the base <code class="literal">Component</code> class and
refines it for the Swing toolkit. The <code class="literal">paintComponent()</code> method we have been using in
our example is inherited from the <code class="literal">JComponent</code> class. <code class="literal">HelloComponent</code> is a kind of <code class="literal">JComponent</code> and inherits all its public
members, just as other GUI components do.</p><p>The <code class="literal">JButton</code> class is also
derived from <code class="literal">JComponent</code> and therefore
shares this functionality. This means that the developer of the <code class="literal">JButton</code> class had methods such as <code class="literal">paintComponent()</code> available with which to
implement the behavior of the <code class="literal">JButton</code>
object, just as we did when creating our example. What’s exciting is
that we are perfectly free to further subclass components such as
<code class="literal">JButton</code> and override their behavior
to create our own special types of user-interface components. <code class="literal">JButton</code> and <code class="literal">HelloComponent3</code> are, in this respect,
equivalent types of things.</p></div><div class="sect2" title="Containers"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.3"/>Containers</h2></div></div></div><p><a id="idx10057" class="indexterm"/> <a id="idx10070" class="indexterm"/>The <code class="literal">Container</code> class is
an extended type of <code class="literal">Component</code> that
maintains a list of child components and helps to group them. The
<code class="literal">Container</code> causes its children to be
displayed and arranges them on the screen according to a particular
layout strategy.</p><p>Because a <code class="literal">Container</code> is also a
<code class="literal">Component</code>, it can be placed alongside
other <code class="literal">Component</code> objects in other
<code class="literal">Container</code>s in a hierarchical fashion,
as shown in <a class="xref" href="ch02s05.html#learnjava3-CHP-2-FIG-6" title="Figure 2-10. Layout of Java containers (in bold) and components (in italics)">Figure 2-10</a>. Our <code class="literal">HelloComponent3</code> class is a kind of <code class="literal">Container</code> (by virtue of the <code class="literal">JComponent</code> class) and can therefore hold and
manage other Java components and containers, such as buttons, sliders,
text fields, and panels.</p><div class="figure"><a id="learnjava3-CHP-2-FIG-6"/><div class="figure-contents"><div class="mediaobject"><a id="I_2_tt54"/><img src="httpatomoreillycomsourceoreillyimages1707608.png" alt="Layout of Java containers (in bold) and components (in italics)"/></div></div><p class="title">Figure 2-10. Layout of Java containers (in bold) and components (in
italics)</p></div><p>In <a class="xref" href="ch02s05.html#learnjava3-CHP-2-FIG-6" title="Figure 2-10. Layout of Java containers (in bold) and components (in italics)">Figure 2-10</a>, the italicized items
are <code class="literal">Component</code>s, and the bold items
are <code class="literal">Container</code>s. The keypad is
implemented as a container object that manages a number of keys. The
keypad itself is contained in the <code class="literal">GizmoTool</code> container object.</p><p>Since <code class="literal">JComponent</code> descends from
<code class="literal">Container</code>, it can be both a component
and a container. In fact, we’ve already used it in this capacity in the
<code class="literal">HelloComponent3</code> example. It does its
own drawing and handles events, just like a component, but it also
contains a button, just like a container.<a id="I_indexterm2_id641362" class="indexterm"/><a id="I_indexterm2_id641370" class="indexterm"/></p></div><div class="sect2" title="Layout"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.4"/>Layout</h2></div></div></div><p><a id="idx10078" class="indexterm"/> <a id="idx10096" class="indexterm"/>Having created a <code class="literal">JButton</code> object, we need to place it in the
container, but where? An object called a <a id="I_indexterm2_id641413" class="indexterm"/><code class="literal">LayoutManager</code>
determines the location within the <code class="literal">HelloComponent3</code> container at which to display
the <code class="literal">JButton</code>. A <code class="literal">LayoutManager</code> object embodies a particular
scheme for arranging components on the screen and adjusting their sizes.
There are several standard layout managers to choose from, and we can,
of course, create new ones. In our case, we specify one of the standard
managers, a <a id="I_indexterm2_id641443" class="indexterm"/><code class="literal">FlowLayout</code> . The net
result is that the button is centered at the top of the <code class="literal">HelloComponent3</code> container. Our <code class="literal">JFrame</code> has another kind of layout, called
<a id="I_indexterm2_id641465" class="indexterm"/><code class="literal">BorderLayout</code>. You’ll
learn more about layout managers in <a class="xref" href="ch19.html" title="Chapter 19. Layout Managers">Chapter 19</a>.</p><p>To add the button to the layout, we invoke the <code class="literal">add()</code> method that <code class="literal">HelloComponent3</code> inherits from <code class="literal">Container</code>, passing the <code class="literal">JButton</code> object as a parameter:</p><a id="I_2_tt55"/><pre class="programlisting"> <code class="n">add</code><code class="o">(</code> <code class="n">theButton</code> <code class="o">);</code></pre><p><code class="literal">add()</code> is a method inherited by
our class from the <code class="literal">Container</code> class.
It appends our <code class="literal">JButton</code> to the list of
components that the <code class="literal">HelloComponent3</code>
container manages. Thereafter, <code class="literal">HelloComponent3</code> is responsible for the
<code class="literal">JButton</code>: it causes the button to be
displayed and it determines where in its window the button should be
placed.<a id="I_indexterm2_id641549" class="indexterm"/></p></div><div class="sect2" title="Subclassing and Subtypes"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.5"/>Subclassing and Subtypes</h2></div></div></div><p><a id="I_indexterm2_id641563" class="indexterm"/> <a id="I_indexterm2_id641572" class="indexterm"/>If you look up the <code class="literal">add()</code> method of the <code class="literal">Container</code> class, you’ll see that it takes a
<code class="literal">Component</code> object as an argument. In
our example, we’ve given it a <code class="literal">JButton</code>
object. What’s going on?</p><p>As we’ve said, <code class="literal">JButton</code> is a
subclass of the <code class="literal">Component</code> class.
Because a subclass is a kind of its superclass and has, at minimum, the
same public methods and variables, Java allows us to use an instance of
a subclass anywhere we could use an instance of its superclass. <code class="literal">JButton</code> is a kind of <code class="literal">Component</code>, so any method that expects a
<code class="literal">Component</code> as an argument will accept
a <code class="literal">JButton</code>. The converse, however, is
not true. A method signature expecting a particular class will not
accept its superclass as a parameter.</p></div><div class="sect2" title="More Events and Interfaces"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.6"/>More Events and Interfaces</h2></div></div></div><p><a id="idx10061" class="indexterm"/> <a id="idx10072" class="indexterm"/> <a id="idx10077" class="indexterm"/> <a id="idx10093" class="indexterm"/>Now that we have a <code class="literal">JButton</code>, we need some way to communicate with
it—that is, to get the events it generates. We could just listen for
mouse clicks within the button and act accordingly, but that would
require customization, via subclassing of the <code class="literal">JButton</code>, and we would be giving up the
advantages of using a pre-fab component. Instead, we have the <code class="literal">HelloComponent3</code> object listen for higher-level
events, corresponding to button presses. A <code class="literal">JButton</code> generates a special kind of event
called an <code class="literal">ActionEvent</code> when someone
clicks on it with the mouse. To receive these events, we have added
another method to the <code class="literal">HelloComponent3</code>
class:</p><a id="I_2_tt56"/><pre class="programlisting"> <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="k">if</code> <code class="o">(</code> <code class="n">e</code><code class="o">.</code><code class="na">getSource</code><code class="o">()</code> <code class="o">==</code> <code class="n">theButton</code> <code class="o">)</code>
<code class="n">changeColor</code><code class="o">();</code>
<code class="o">}</code></pre><p>If you followed the previous example, you shouldn’t be surprised
to see that <code class="literal">HelloComponent3</code> now
declares that it implements the <a id="I_indexterm2_id641757" class="indexterm"/><code class="literal">ActionListener</code>
interface in addition to <a id="I_indexterm2_id641768" class="indexterm"/><code class="literal">MouseMotionListener</code>.
<code class="literal">ActionListener</code> requires us to
implement an <a id="I_indexterm2_id641785" class="indexterm"/><code class="literal">actionPerformed()</code>
method that is called whenever an <code class="literal">ActionEvent</code> occurs. You also shouldn’t be
surprised to see that we added a line to the <code class="literal">HelloComponent3</code> constructor, registering
itself (<code class="literal">this</code>) as a listener for the
button’s action events:</p><a id="I_2_tt57"/><pre class="programlisting"> <code class="n">theButton</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code> <code class="k">this</code> <code class="o">);</code></pre><p>Note that this time, we’re registering our component as a listener
with a different object—the
button—whereas previously we were asking for our own events.</p><p>The <code class="literal">actionPerformed()</code> method
takes care of any action events that arise. First, it checks to make
sure that the event’s source (the component generating the event) is
what we think it should be: <code class="literal">theButton</code>. This may seem superfluous; after
all, there is only one button. What else could possibly generate an
action event? In this application, nothing, but it’s a good idea to
check because another application may have many buttons, and you may
need to figure out which one has been clicked. Or you may add a second
button to this application later, and you don’t want it to break
something when you do. To check this, we call the <a id="I_indexterm2_id641859" class="indexterm"/><code class="literal">getSource()</code> method of
the <code class="literal">ActionEvent</code> object, <code class="literal">e</code>. We then use the <a id="I_indexterm2_id641880" class="indexterm"/><code class="literal">==</code> operator to make
sure the event source matches <code class="literal">theButton</code>.</p><div class="tip" title="Tip"><h3 class="title"><a id="learnjava3-CHP-2-NOTE-4"/>Tip</h3><p>In Java, <code class="literal">==</code> is a test for
<a id="I_indexterm2_id641909" class="indexterm"/><span class="emphasis"><em>identity</em></span>, not equality; it is
<a id="I_indexterm2_id641918" class="indexterm"/><code class="literal">true</code> if the event
source and <code class="literal">theButton</code> are the same
object. The distinction between equality and identity is important. We
would consider two <code class="literal">String</code> objects
to be equal if they have the same characters in the same sequence.
However, they might not be the same object. In <a class="xref" href="ch07.html" title="Chapter 7. Working with Objects and Classes">Chapter 7</a>, we’ll look at the <a id="I_indexterm2_id641947" class="indexterm"/><code class="literal">equals()</code> method,
which tests for equality.</p></div><p>Once we establish that event <code class="literal">e</code>
comes from the right button, we call our <code class="literal">changeColor()</code> method, and we’re
finished.</p><p>You may wonder why we don’t have to change <code class="literal">mouseDragged()</code> now that we have a <code class="literal">JButton</code> in our application. The rationale is
that the coordinates of the event are all that matter for this method.
We are not particularly concerned if the event falls within an area of
the screen occupied by another component. This means you can drag the
text right through the <code class="literal">JButton</code>: try
it and see! In this case, the arrangement of containers means that the
button is on top of our component, so the text is dragged beneath
it.<a id="I_indexterm2_id641995" class="indexterm"/><a id="I_indexterm2_id642002" class="indexterm"/><a id="I_indexterm2_id642009" class="indexterm"/><a id="I_indexterm2_id642016" class="indexterm"/></p></div><div class="sect2" title="Color Commentary"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.7"/>Color Commentary</h2></div></div></div><p><a id="idx10054" class="indexterm"/> <a id="idx10067" class="indexterm"/>To support <code class="literal">HelloJava3</code>’s
colorful side, we have added a couple of new variables and two helpful
methods. We create and initialize an array of <code class="literal">Color</code> objects representing the colors through
which we cycle when the button is pressed. We also declare an integer
variable that serves as an index into this array, specifying the
position of the current color:</p><a id="I_2_tt58"/><pre class="programlisting"> <code class="kt">int</code> <code class="n">colorIndex</code><code class="o">;</code>
<code class="kd">static</code> <code class="n">Color</code><code class="o">[]</code> <code class="n">someColors</code> <code class="o">=</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="n">Color</code><code class="o">.</code><code class="na">red</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">Color</code><code class="o">.</code><code class="na">blue</code><code class="o">,</code> <code class="n">Color</code><code class="o">.</code><code class="na">magenta</code> <code class="o">};</code></pre><p>A number of things are going on here. First, let’s look at the
<code class="literal">Color</code> objects we are putting into the
array. Instances of the <a id="I_indexterm2_id642086" class="indexterm"/><code class="literal">java.awt.Color</code> class
represent colors; they are used by all classes in the <code class="literal">java.awt</code> package that deal with basic color
graphics. Notice that we are referencing variables such as <code class="literal">Color.black</code> and <code class="literal">Color.red</code>. These look like examples of an
object’s instance variables, but <code class="literal">Color</code> is not an object, it’s a class. What is
the meaning of this? We’ll discuss that next.<a id="I_indexterm2_id642122" class="indexterm"/></p></div><div class="sect2" title="Static Members"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.8"/>Static Members</h2></div></div></div><p><a id="I_indexterm2_id642136" class="indexterm"/> <a id="I_indexterm2_id642144" class="indexterm"/> <a id="I_indexterm2_id642153" class="indexterm"/> <a id="I_indexterm2_id642159" class="indexterm"/> <a id="I_indexterm2_id642165" class="indexterm"/> <a id="I_indexterm2_id642172" class="indexterm"/>A class can contain variables and methods that are shared
among all instances of the class. These shared members are called
<span class="emphasis"><em>static variables</em></span> and <span class="emphasis"><em>static
methods</em></span>. The most common use of static variables in a class
is to hold predefined constants or unchanging objects that all the
instances can use.</p><p>This approach has two advantages. One advantage is that static
values are shared by all instances of the class; the same value can be
seen by all instances. More importantly, static members can be accessed
even if no instances of the class exist. In this example, we use the
static variable <code class="literal">Color.red</code> without
having to create an instance of the <code class="literal">Color</code> class.</p><p>An instance of the <code class="literal">Color</code> class
represents a visible color. For convenience, the <code class="literal">Color</code> class contains some static, predefined
objects with friendly names such as <a id="I_indexterm2_id642220" class="indexterm"/><code class="literal">GREEN</code>, <a id="I_indexterm2_id642230" class="indexterm"/><code class="literal">RED</code>, and (the happy
color) <a id="I_indexterm2_id642241" class="indexterm"/><code class="literal">MAGENTA</code>. The variable
<code class="literal">GREEN</code>, for example, is a static
member in the <code class="literal">Color</code> class. The data
type of the variable <code class="literal">GREEN</code> is
<code class="literal">Color</code>. Internally, in Java-land, it
is initialized like this:</p><a id="I_2_tt59"/><pre class="programlisting"> <code class="kd">public</code> <code class="kd">final</code> <code class="kd">static</code> <code class="n">Color</code> <code class="n">GREEN</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Color</code><code class="o">(</code><code class="mi">0</code><code class="o">,</code> <code class="mi">255</code><code class="o">,</code> <code class="mi">0</code><code class="o">);</code></pre><p>The <code class="literal">GREEN</code> variable and the
other static members of <code class="literal">Color</code> cannot
be modified (after they’ve been initialized) so that they are
effectively constants and can be optimized as such by the Java VM. The
alternative to using these predefined colors is to create a color
manually by specifying its red, green, and blue (RGB) components using a
<code class="literal">Color</code> class constructor.</p></div><div class="sect2" title="Arrays"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.9"/>Arrays</h2></div></div></div><p><a id="idx10050" class="indexterm"/> <a id="idx10064" class="indexterm"/>Next, we turn our attention to the array. We have declared
a variable called <code class="literal">someColors</code>, which
is an array of <code class="literal">Color</code> objects. In
Java, arrays are <a id="I_indexterm2_id642353" class="indexterm"/><span class="emphasis"><em>first-class</em></span> objects. This means that
an array itself is a type of object—one that knows how to hold an
indexed list of some other type of object. An array is indexed by
integers; when you index an array, the resulting value is an object
reference—that is, a reference to the object that is located in the
array’s specified slot. Our code uses the <code class="literal">colorIndex</code> variable to index <code class="literal">someColors</code>. It’s also possible to have an
array of simple primitive types, such as <code class="literal">float</code>s, rather than objects.</p><p><a id="I_indexterm2_id642387" class="indexterm"/> <a id="I_indexterm2_id642393" class="indexterm"/>When we declare an array, we can initialize it using the
curly brace construct. Specifying a comma-separated list of elements
inside curly braces is a convenience that instructs the compiler to
create an instance of the array with those elements and assign it to our
variable. Alternatively, we could have just declared our <code class="literal">someColors</code> variable and, later, allocated an
array object for it and assigned individual elements to that array’s
slots. See <a class="xref" href="ch05.html" title="Chapter 5. Objects in Java">Chapter 5</a> for a complete discussion
of arrays.<a id="I_indexterm2_id642415" class="indexterm"/><a id="I_indexterm2_id642422" class="indexterm"/></p></div><div class="sect2" title="Our Color Methods"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-4.10"/>Our Color Methods</h2></div></div></div><p><a id="idx10068" class="indexterm"/> <a id="idx10079" class="indexterm"/> <a id="idx10098" class="indexterm"/>Now we have an array of <code class="literal">Color</code> objects and a variable with which to
index the array. Two private methods do the actual work for us. The
<a id="I_indexterm2_id642487" class="indexterm"/><code class="literal">private</code> modifier on
these methods specifies that they can be called only by other methods in
the same instance of the class. They cannot be accessed outside the
object that contains them. We declare members to be <code class="literal">private</code> to hide the detailed inner workings of
a class from the outside world. This is called <a id="I_indexterm2_id642506" class="indexterm"/><span class="emphasis"><em>encapsulation</em></span> and is another tenet of
object-oriented design as well as good programming practice. Private
methods are created as helper functions for use solely in the class
implementation.</p><p>The first method, <code class="literal">currentColor()</code>, is simply a convenience
routine that returns the <code class="literal">Color</code> object
representing the current text color. It returns the <code class="literal">Color</code> object in the <code class="literal">someColors</code> array at the index specified by our
<code class="literal">colorIndex</code> variable:</p><a id="I_2_tt60"/><pre class="programlisting"> <code class="kd">synchronized</code> <code class="kd">private</code> <code class="n">Color</code> <code class="nf">currentColor</code><code class="o">()</code> <code class="o">{</code>
<code class="k">return</code> <code class="n">someColors</code><code class="o">[</code><code class="n">colorIndex</code><code class="o">];</code>
<code class="o">}</code></pre><p>We could just as readily have used the expression <code class="literal">someColors[colorIndex]</code> everywhere we use
<code class="literal">currentColor()</code>; however, creating
methods to wrap common tasks is another way of shielding ourselves from
the details of our class. In an alternative implementation, we might
have shuffled off details of all color-related code into a separate
class. We could have created a class that takes an array of colors in
its constructor and then provides two methods: one to ask for the
current color and one to cycle to the next color (just some food for
thought).</p><p>The second method, <code class="literal">changeColor()</code>, is responsible for incrementing
the <code class="literal">colorIndex</code> variable to point to
the next <code class="literal">Color</code> in the array. <code class="literal">changeColor()</code> is called from our <a id="I_indexterm2_id642598" class="indexterm"/><code class="literal">actionPerformed()</code>
method whenever the button is pressed:</p><a id="I_2_tt61"/><pre class="programlisting"> <code class="kd">synchronized</code> <code class="kd">private</code> <code class="kt">void</code> <code class="nf">changeColor</code><code class="o">()</code> <code class="o">{</code>
<code class="c1">// Change the index to the next color, awkwardly.</code>
<code class="k">if</code> <code class="o">(</code> <code class="o">++</code><code class="n">colorIndex</code> <code class="o">==</code> <code class="n">someColors</code><code class="o">.</code><code class="na">length</code> <code class="o">)</code>
<code class="n">colorIndex</code> <code class="o">=</code> <code class="mi">0</code><code class="o">;</code>
<code class="n">setForeground</code><code class="o">(</code> <code class="n">currentColor</code><code class="o">()</code> <code class="o">);</code> <code class="c1">// Use the new color.</code>
<code class="n">repaint</code><code class="o">();</code>
<code class="o">}</code></pre><p>Here we increment <code class="literal">colorIndex</code>
and compare it to the length of the <code class="literal">someColors</code> array. All array objects have a
variable called <code class="literal">length</code> that specifies
the number of elements in the array. If we have reached the end of the
array, we wrap around to the beginning by resetting the index to
<code class="literal">0</code>. We’ve flagged this with a comment
to indicate that we’re doing something fishy here. But we’ll come back
to that in a moment. After changing the currently selected color, we do
two things. First, we call the component’s <a id="I_indexterm2_id642650" class="indexterm"/><code class="literal">setForeground()</code> method,
which changes the color used to draw text in our component. Then we call
<code class="literal">repaint()</code> to cause the component to
be redrawn with the new color for the draggable message.</p><p>What is the <a id="I_indexterm2_id642670" class="indexterm"/><code class="literal">synchronized</code> keyword
that appears in front of our <code class="literal">currentColor()</code> and <code class="literal">changeColor()</code> methods? Synchronization has to
do with threads, which we’ll examine in the next section. For now, all
you need to know is that the <code class="literal">synchronized</code> keyword indicates that these two
methods can never be running at the same time. They must always run in a
mutually exclusive way.</p><p>The reason for this is related to the fishy way we increment our
index. Notice that in <code class="literal">changeColor()</code>,
we increment <code class="literal">colorIndex</code> before
testing its value. Strictly speaking, this means that for some brief
period of time while Java is running through our code, <code class="literal">colorIndex</code> can have a value that is past the
end of our array. If our <code class="literal">currentColor()</code> method happened to run at that
same moment, we would see a runtime “array out of bounds” error. Now, it
would be easy for us to fix the problem in this case with some simple
arithmetic before changing the value, but this simple example is
representative of more general synchronization issues that we need to
address. We’ll use it to illustrate the use of the <code class="literal">synchronized</code> keyword. In the next section,
you’ll see that Java makes dealing with these problems relatively easy
through language-level synchronization support.<a id="I_indexterm2_id642741" class="indexterm"/><a id="I_indexterm2_id642748" class="indexterm"/><a id="I_indexterm2_id642755" class="indexterm"/><a id="I_indexterm2_id642762" class="indexterm"/></p></div><div class="footnotes"><br/><hr/><div class="footnote"><p><sup>[<a id="ftn.learnjava3-CHP-2-FNOTE-3" href="#learnjava3-CHP-2-FNOTE-3" class="para">4</a>] </sup>Why isn’t it just called a <code class="literal">Button</code>? <a id="I_indexterm2_id640672" class="indexterm"/><code class="literal">Button</code> is the name
that was used in Java’s original GUI toolkit, AWT. AWT had some
significant shortcomings, so it was extended and essentially replaced
by Swing in Java 1.2. Since AWT already took the reasonable names,
such as <code class="literal">Button</code> and <a id="I_indexterm2_id640692" class="indexterm"/><a id="I_indexterm2_id640697" class="indexterm"/><code class="literal">MenuBar</code>, and mixing
them in code could be confusing, Swing user interface component names
start with J, such as <code class="literal">JButton</code> and
<a id="I_indexterm2_id640716" class="indexterm"/><code class="literal">JMenuBar</code>.</p></div></div></div></body></html>