epubjs
Version:
Render ePub documents in the browser, across many devices
288 lines (280 loc) • 36.5 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>HelloJava2: The Sequel</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="HelloJava2: The Sequel"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-2-SECT-3"/>HelloJava2: The Sequel</h1></div></div></div><p>Now that we’ve got some basics down, let’s make our application a
little more interactive. The following minor upgrade allows us to drag the
message text around with the mouse.</p><p>We’ll call this example <code class="literal">HelloJava2</code> rather than cause confusion by
continuing to expand the old one, but the primary changes here and further
on lie in adding capabilities to the <code class="literal">HelloComponent</code> class and simply making the
corresponding changes to the names to keep them straight (e.g., <code class="literal">HelloComponent2</code>, <code class="literal">HelloComponent3</code>, and so on). Having just seen
inheritance at work, you might wonder why we aren’t creating a subclass of
<code class="literal">HelloComponent</code> and exploiting
inheritance to build upon our previous example and extend its
functionality. Well, in this case, that would not provide much advantage,
and for clarity we simply start over.</p><p>Here is <code class="literal">HelloJava2</code>:</p><a id="I_2_tt34"/><pre class="programlisting"> <code class="c1">//file: HelloJava2.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">HelloJava2</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">"HelloJava2"</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">HelloComponent2</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">HelloComponent2</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">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="kd">public</code> <code class="nf">HelloComponent2</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">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="c1">// Save the mouse coordinates and paint the message.</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="o">}</code>
<code class="o">}</code></pre><p>Two slashes in a row indicate that the rest of the line is a
comment. We’ve added a few comments to <code class="literal">HelloJava2</code> to help you keep track of
everything.</p><p>Place the text of this example in a file called
<span class="emphasis"><em>HelloJava2.java</em></span> and compile it as before. You should
get new class files, <span class="emphasis"><em>HelloJava2.class</em></span> and
<span class="emphasis"><em>HelloComponent2.class</em></span>, as a result.</p><p>Run the example using the following command:</p><a id="I_2_tt35"/><pre class="programlisting"> <code class="nl">C:</code><code class="err">\</code><code class="o">></code> <strong class="userinput"><code><code class="n">java</code> <code class="n">HelloJava2</code></code></strong></pre><p>Or, if you are following in Eclipse, click the Run button. Feel free
to substitute your own salacious comment for the “Hello, Java!” message
and enjoy many hours of fun, dragging the text around with your mouse.
Notice that now when you click the window’s close button, the application
exits; we’ll explain that later when we talk about events. Now let’s see
what’s changed.</p><div class="sect2" title="Instance Variables"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-3.1"/>Instance Variables</h2></div></div></div><p><a id="I_indexterm2_id639181" class="indexterm"/> <a id="idx10091" class="indexterm"/>We have added some variables to the <code class="literal">HelloComponent2</code> class in our example:</p><a id="I_2_tt36"/><pre class="programlisting"> <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="n">String</code> <code class="n">theMessage</code><code class="o">;</code></pre><p><code class="literal">messageX</code> and <code class="literal">messageY</code> are integers that hold the current
coordinates of our movable message. We have crudely initialized them to
default values that should place the message somewhere near the center
of the window. Java integers are 32-bit signed numbers, so they can
easily hold our coordinate values. The variable <code class="literal">theMessage</code> is of type <code class="literal">String</code> and can hold instances of the
<a id="I_indexterm2_id639245" class="indexterm"/><code class="literal">String</code> class.</p><p><a id="I_indexterm2_id639257" class="indexterm"/> <a id="I_indexterm2_id639263" class="indexterm"/>You should note that these three variables are declared
inside the braces of the class definition, but not inside any particular
method in that class. These variables are called <a id="I_indexterm2_id639271" class="indexterm"/><a id="I_indexterm2_id639279" class="indexterm"/><span class="emphasis"><em>instance</em></span> variables, and they belong
to the class as a whole. Specifically, copies of them appear in each
separate instance of the class. Instance variables are always visible to
(and usable by) all the methods inside their class. Depending on their
modifiers, they may also be accessible from outside the class.</p><p>Unless otherwise initialized, instance variables are set to a
default value of <code class="literal">0</code>, <a id="I_indexterm2_id639300" class="indexterm"/><code class="literal">false</code>, or <a id="I_indexterm2_id639311" class="indexterm"/><code class="literal">null</code>, depending on
their type. Numeric types are set to <code class="literal">0</code>, Boolean variables are set to <code class="literal">false</code>, and class type variables always have
their value set to <code class="literal">null</code>, which means
“no value.” Attempting to use an object with a <code class="literal">null</code> value results in a runtime error.</p><p>Instance variables differ from method arguments and other
variables that are declared inside the scope of a particular method. The
latter are called <a id="I_indexterm2_id639349" class="indexterm"/><span class="emphasis"><em>local</em></span> variables. They are effectively
private variables that can be seen only by code inside the method. Java
doesn’t initialize local variables, so you must assign values yourself.
If you try to use a local variable that has not yet been assigned a
value, your code generates a compile-time error. Local variables live
only as long as the method is executing and then disappear, unless
something else saves their value. Each time the method is invoked, its
local variables are recreated and must be assigned values.</p><p>We have used the new variables to make our previously stodgy
<code class="literal">paintComponent()</code> method more dynamic.
Now all the arguments in the call to <code class="literal">drawString()</code> are determined by these
variables.<a id="I_indexterm2_id639379" class="indexterm"/></p></div><div class="sect2" title="Constructors"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-3.2"/>Constructors</h2></div></div></div><p><a id="idx10056" class="indexterm"/> <a id="idx10069" class="indexterm"/>The <code class="literal">HelloComponent2</code>
class includes a special kind of a method called a <a id="I_indexterm2_id639426" class="indexterm"/><span class="emphasis"><em>constructor</em></span>. A constructor is called
to set up a new instance of a class. When a new object is created, Java
allocates storage for it, sets instance variables to their default
values, and calls the constructor method for the class to do whatever
application-level setup is required.</p><p>A constructor always has the same name as its class. For example,
the constructor for the <code class="literal">HelloComponent2</code> class is called <code class="literal">HelloComponent2()</code>. Constructors don’t have a
return type, but you can think of them as creating an object of their
class’s type. Like other methods, constructors can take arguments. Their
sole mission in life is to configure and initialize newly born class
instances, possibly using information passed to them in these
parameters.</p><p>An object is created with the <a id="I_indexterm2_id639462" class="indexterm"/><code class="literal">new</code> operator specifying
the constructor for the class and any necessary arguments. The resulting
object instance is returned as a value. In our example, a new <code class="literal">HelloComponent2</code> instance is created in the
<code class="literal">main()</code> method by this line:</p><a id="I_2_tt37"/><pre class="programlisting"> <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">HelloComponent2</code><code class="o">(</code><code class="s">"Hello, Java!"</code><code class="o">)</code> <code class="o">);</code></pre><p>This line actually does two things. We could write them as two
separate lines that are a little easier to understand:</p><a id="I_2_tt38"/><pre class="programlisting"> <code class="n">HelloComponent2</code> <code class="n">newObject</code> <code class="o">=</code> <code class="k">new</code> <code class="n">HelloComponent2</code><code class="o">(</code><code class="s">"Hello, Java!"</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">newObject</code> <code class="o">);</code></pre><p>The first line is the important one, where a new <code class="literal">HelloComponent2</code> object is created. The
<code class="literal">HelloComponent2</code> constructor takes a
<code class="literal">String</code> as an argument and, as we have
arranged it, uses it to set the message that is displayed in the window.
With a little magic from the Java compiler, quoted text in Java source
code is turned into a <a id="I_indexterm2_id639527" class="indexterm"/><a id="I_indexterm2_id639532" class="indexterm"/><code class="literal">String</code> object. (See
<a class="xref" href="ch10.html" title="Chapter 10. Working with Text">Chapter 10</a> for a complete discussion of the
<code class="literal">String</code> class.) The second line simply
adds our new component to the frame to make it visible, as we did in the
previous examples.</p><p><a id="I_indexterm2_id639555" class="indexterm"/> <a id="I_indexterm2_id639562" class="indexterm"/>While we’re on the topic, if you’d like to make our
message configurable, you can change the constructor line to the
following:</p><a id="I_2_tt39"/><pre class="programlisting"> <code class="n">HelloComponent2</code> <code class="n">newobj</code> <code class="o">=</code> <code class="k">new</code> <code class="n">HelloComponent2</code><code class="o">(</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">]</code> <code class="o">);</code></pre><p>Now you can pass the text on the command line when you run the
application using the following command:</p><a id="I_2_tt40"/><pre class="programlisting"> <code class="nl">C:</code><code class="err">\</code><code class="o">></code> <strong class="userinput"><code><code class="n">java</code> <code class="n">HelloJava2</code> <code class="s">"Hello, Java!"</code></code></strong></pre><p><a id="I_indexterm2_id639597" class="indexterm"/> <code class="literal">args[0]</code> refers to the
first command-line parameter. Its meaning will become clearer when we
discuss arrays later in the book. If you are using an IDE, such as
Eclipse, you will need to configure it to accept your parameters before
running it.</p><p><code class="literal">HelloComponent2</code>’s constructor
then does two things: it sets the text of <code class="literal">theMessage</code> instance variable and calls
<a id="I_indexterm2_id639623" class="indexterm"/><code class="literal">addMouseMotionListener()</code>. This method is part
of the event mechanism, which we discuss next. It tells the system,
“Hey, I’m interested in anything that happens involving the
mouse.”</p><a id="I_2_tt41"/><pre class="programlisting"> <code class="kd">public</code> <code class="nf">HelloComponent2</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">addMouseMotionListener</code><code class="o">(</code> <code class="k">this</code> <code class="o">);</code>
<code class="o">}</code></pre><p>The special, read-only variable called <a id="I_indexterm2_id639649" class="indexterm"/><a id="I_indexterm2_id639654" class="indexterm"/><code class="literal">this</code> is used to
explicitly refer to our object (the “current” object context) in the
call to <code class="literal">addMouseMotionListener()</code>. A
method can use <code class="literal">this</code> to refer to the
instance of the object that holds it. The following two statements are
therefore equivalent ways of assigning the value to <code class="literal">theMessage</code> instance variable:</p><a id="I_2_tt42"/><pre class="programlisting"> <code class="n">theMessage</code> <code class="o">=</code> <code class="n">message</code><code class="o">;</code></pre><p>or:</p><a id="I_2_tt43"/><pre class="programlisting"> <code class="k">this</code><code class="o">.</code><code class="na">theMessage</code> <code class="o">=</code> <code class="n">message</code><code class="o">;</code></pre><p>We’ll normally use the shorter, implicit form to refer to instance
variables, but we’ll need <code class="literal">this</code> when
we have to explicitly pass a reference to our object to a method in
another class. We often do this so that methods in other classes can
invoke our public methods or use our public variables.<a id="I_indexterm2_id639717" class="indexterm"/><a id="I_indexterm2_id639724" class="indexterm"/></p></div><div class="sect2" title="Events"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-3.3"/>Events</h2></div></div></div><p><a id="idx10060" class="indexterm"/> <a id="idx10071" class="indexterm"/>The last two methods of <code class="literal">HelloComponent2</code>, <a id="I_indexterm2_id639767" class="indexterm"/><code class="literal">mouseDragged()</code> and
<a id="I_indexterm2_id639778" class="indexterm"/><code class="literal">mouseMoved()</code>, let us
get information from the mouse. Each time the user performs an action,
such as pressing a key on the keyboard, moving the mouse, or perhaps
banging his or her head against a touch screen, Java generates an
<a id="I_indexterm2_id639790" class="indexterm"/><span class="emphasis"><em>event</em></span>. An event represents an action
that has occurred; it contains information about the action, such as its
time and location. Most events are associated with a particular GUI
component in an application. A keystroke, for instance, can correspond
to a character being typed into a particular text entry field. Pressing
a mouse button can activate a particular button on the screen. Even just
moving the mouse within a certain area of the screen can trigger effects
such as highlighting or changing the cursor’s shape.</p><p>To work with these events, we’ve imported a new package,
<a id="I_indexterm2_id639814" class="indexterm"/><code class="literal">java.awt.event</code>, which
provides specific <code class="literal">Event</code> objects that
we use to get information from the user. (Notice that importing <code class="literal">java.awt.*</code> doesn’t automatically import the
<a id="I_indexterm2_id639837" class="indexterm"/><code class="literal">event</code> package. Packages
don’t really contain other packages, even if the hierarchical naming
scheme would imply that they do.)</p><p>There are many different event classes, including <code class="literal">MouseEvent</code>, <a id="I_indexterm2_id639860" class="indexterm"/><code class="literal">KeyEvent</code>, and
<a id="I_indexterm2_id639870" class="indexterm"/><code class="literal">Action</code><code class="literal">Event</code>. For the most part, the meaning of
these events is fairly intuitive. A <a id="I_indexterm2_id639890" class="indexterm"/><code class="literal">MouseEvent</code> occurs when
the user does something with the mouse, a <code class="literal">KeyEvent</code> occurs when the user presses a key,
and so on. <code class="literal">ActionEvent</code> is a little
special; we’ll see it at work later in this chapter in our third version
of <code class="literal">HelloJava</code>. For now, we’ll focus on
dealing with <code class="literal">Mouse</code><code class="literal">Event</code>s.</p><p>GUI components in Java generate events for specific kinds of user
actions. For example, if you click the mouse inside a component, the
component generates a mouse event. Objects can ask to receive the events
from one or more components by registering a <a id="I_indexterm2_id639938" class="indexterm"/><span class="emphasis"><em>listener</em></span> with the event source. For
example, to declare that a listener wants to receive a component’s
mouse-motion events, you invoke that component’s <code class="literal">addMouseMotionListener()</code> method, specifying
the listener object as an argument. That’s what our example is doing in
its constructor. In this case, the component is calling its own
<a id="I_indexterm2_id639958" class="indexterm"/><code class="literal">addMouseMotionListener()</code> method, with the
argument <a id="I_indexterm2_id639969" class="indexterm"/><code class="literal">this</code>, meaning “I want
to receive my own mouse-motion events.”</p><p>That’s how we register to receive events. But how do we actually
get them? That’s what the two mouse-related methods in our class are
for. The <a id="I_indexterm2_id639990" class="indexterm"/><code class="literal">mouseDragged()</code> method
is called automatically on a listener to receive the events generated
when the user drags the mouse—that is, moves the mouse with any button
pressed. The <a id="I_indexterm2_id640004" class="indexterm"/><code class="literal">mouseMoved()</code> method is
called whenever the user moves the mouse over the area without pressing
a button. In this case, we’ve placed these methods in our <code class="literal">HelloComponent2</code> class and had it register
itself as the listener. This is entirely appropriate for our new
text-dragging component. More generally, good design usually dictates
that event listeners be implemented as <span class="emphasis"><em>adapter
classes</em></span> that provide better separation of GUI and “business
logic.” We’ll discuss that in detail later in the book.</p><p>Our <code class="literal">mouseMoved()</code> method is
boring: it doesn’t do anything. We ignore simple mouse motions and
reserve our attention for dragging. <code class="literal">mouseDragged()</code> has a bit more meat to it. This
method is called repeatedly by the windowing system to give us updates
on the position of the mouse. Here it is:</p><a id="I_2_tt44"/><pre class="programlisting"> <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></pre><p>The first argument to <code class="literal">mouseDragged()</code> is a <code class="literal">MouseEvent</code> object, <code class="literal">e</code>, that contains all the information we need
to know about this event. We ask the <code class="literal">MouseEvent</code> to tell us the <code class="literal">x</code> and <code class="literal">y</code>
coordinates of the mouse’s current position by calling its <code class="literal">getX()</code> and <code class="literal">getY()</code> methods. We save these in the <code class="literal">messageX</code> and <code class="literal">messageY</code> instance variables for use elsewhere.</p><p>The beauty of the event model is that you have to handle only the
kinds of events you want. If you don’t care about keyboard events, you
just don’t register a listener for them; the user can type all she wants
and you won’t be bothered. If there are no listeners for a particular
kind of event, Java won’t even generate it. The result is that event
handling is quite efficient.<sup>[<a id="learnjava3-CHP-2-FNOTE-2" href="#ftn.learnjava3-CHP-2-FNOTE-2" class="footnote">3</a>]</sup></p><p>While we’re discussing events, we should mention another small
addition we slipped into <code class="literal">HelloJava2</code>:</p><a id="I_2_tt45"/><pre class="programlisting"> <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></pre><p>This line tells the frame to exit the application when its close
button is pressed. It’s called the “default” close operation because
this operation, like almost every other GUI interaction, is governed by
events. We could register a window listener to get notification of when
the user pushes the close button and take whatever action we like, but
this convenience method handles the common cases.</p><p>Finally, we’ve danced around a couple of questions here: how does
the system know that our class contains the necessary <code class="literal">mouseDragged()</code> and <code class="literal">mouseMoved()</code> methods (where do these names
come from)? And why do we have to supply a <code class="literal">mouseMoved()</code> method that doesn’t do anything?
The answer to these questions has to do with interfaces. We’ll discuss
interfaces after clearing up some unfinished business with <code class="literal">repaint()</code>.<a id="I_indexterm2_id640192" class="indexterm"/><a id="I_indexterm2_id640199" class="indexterm"/></p></div><div class="sect2" title="The repaint() Method"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-3.4"/>The repaint() Method</h2></div></div></div><p><a id="idx10083" class="indexterm"/> <a id="idx10102" class="indexterm"/> <a id="idx10107" class="indexterm"/>Because we changed the coordinates for the message (when
we dragged the mouse), we would like <code class="literal">HelloComponent2</code> to redraw itself. We do this
by calling <code class="literal">repaint()</code>, which asks the
system to redraw the screen at a later time. We can’t call <code class="literal">paintComponent()</code> directly, even if we wanted
to, because we don’t have a graphics context to pass to it.</p><p>We can use the <code class="literal">repaint()</code> method
of the <code class="literal">JComponent</code> class to request
that our component be redrawn. <code class="literal">repaint()</code> causes the Java windowing system to
schedule a call to our <code class="literal">paintComponent()</code> method at the next possible
time; Java supplies the necessary <code class="literal">Graphics</code> object, as shown in <a class="xref" href="ch02s04.html#learnjava3-CHP-2-FIG-4" title="Figure 2-8. Invoking the repaint() method">Figure 2-8</a>.</p><p>This mode of operation isn’t just an inconvenience brought about
by not having the right graphics context handy. The foremost advantage
to this mode of operation is that the repainting behavior is handled by
someone else while we are free to go about our business. The Java system
has a separate, dedicated thread of execution that handles all <code class="literal">repaint()</code> requests. It can schedule and
consolidate <code class="literal">repaint()</code> requests as
necessary, which helps to prevent the windowing system from being
overwhelmed during painting-intensive situations like scrolling. Another
advantage is that all the painting functionality must be encapsulated
through our <code class="literal">paintComponent()</code> method;
we aren’t tempted to spread it throughout the application.</p><div class="figure"><a id="learnjava3-CHP-2-FIG-4"/><div class="figure-contents"><div class="mediaobject"><a id="I_2_tt46"/><img src="httpatomoreillycomsourceoreillyimages1707606.png" alt="Invoking the repaint() method"/></div></div><p class="title">Figure 2-8. Invoking the repaint() method</p></div></div><div class="sect2" title="Interfaces"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-2-SECT-3.5"/>Interfaces</h2></div></div></div><p><a id="idx10076" class="indexterm"/> <a id="idx10092" class="indexterm"/>Now it’s time to face the question we avoided earlier: how
does the system know to call <code class="literal">mouseDragged()</code> when a mouse event occurs? Is
it simply a matter of knowing that <code class="literal">mouseDragged()</code> is some magic name that our
event-handling method must have? Not quite; the answer to the question
touches on the discussion of interfaces, which are one of the most
important features of the Java language.</p><p>The first sign of an interface comes on the line of code that
introduces the <code class="literal">HelloComponent2</code> class:
we say that the class implements the <a id="I_indexterm2_id640417" class="indexterm"/><code class="literal">MouseMotionListener</code>
interface.</p><a id="I_2_tt47"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">HelloComponent2</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></pre><p><a id="idx10053" class="indexterm"/>Essentially, an interface is a list of methods that the
class must have; this particular interface requires our class to have
methods called <code class="literal">mouseDragged()</code> and
<code class="literal">mouseMoved()</code>. The interface doesn’t
say what these methods have to do; indeed, <code class="literal">mouseMoved()</code> doesn’t do anything. It does say
that the methods must take a <code class="literal">MouseEvent</code> as an argument and return no value
(that’s what <code class="literal">void</code> means).</p><p>An interface is a contract between you, the code developer, and
the compiler. By saying that your class implements the <code class="literal">MouseMotionListener</code> interface, you’re saying
that these methods will be available for other parts of the system to
call. If you don’t provide them, a compilation error will occur.</p><p>That’s not the only way interfaces impact this program. An
interface also acts like a class. For example, a method could return a
<code class="literal">MouseMotionListener</code> or take a
<code class="literal">MouseMotionListener</code> as an argument.
When you refer to an object by an interface name in this way, it means
that you don’t care about the object’s actual class; the only
requirement is that the class implements that interface. <a id="I_indexterm2_id640516" class="indexterm"/><code class="literal">addMouseMotionListener()</code> is such a method: its
argument must be an object that implements the <code class="literal">MouseMotionListener</code> interface. The argument we
pass is <code class="literal">this</code>, the <code class="literal">HelloComponent2</code> object itself. The fact that
it’s an instance of <code class="literal">JComponent</code> is
irrelevant; it could be a <code class="literal">Cookie</code>, an
<code class="literal">Aardvark</code>, or any other class we dream
up. What’s important is that it implements <code class="literal">MouseMotionListener</code> and, thus, declares that
it will have the two named methods. That’s why we need a <code class="literal">mouseMoved()</code> method, even though the one we
supplied doesn’t do anything: the <code class="literal">MouseMotionListener</code> interface says we must
have one.</p><p><a id="I_indexterm2_id640584" class="indexterm"/>The Java distribution comes with many interfaces that
define what classes have to do. This idea of a contract between the
compiler and a class is very important. There are many situations like
the one we just saw where you don’t care what class something is, you
just care that it has some capability, such as listening for mouse
events. Interfaces give us a way of acting on objects based on their
capabilities without knowing or caring about their actual type. They are
a tremendously important concept in how we use Java as an
object-oriented language, and we’ll talk about them in detail in <a class="xref" href="ch04.html" title="Chapter 4. The Java Language">Chapter 4</a>.</p><p>We’ll also see shortly that interfaces provide a sort of escape
clause to the Java rule that any new class can extend only a single
class (“single inheritance”). A class in Java can extend only one class,
but can implement as many interfaces as it wants; our next example
implements two interfaces and the final example in this chapter
implements three. In many ways, interfaces are almost like classes, but
not quite. They can be used as data types, can extend other interfaces
(but not classes), and can be inherited by classes (if class A
implements interface B, subclasses of A also implement B). The crucial
difference is that classes don’t actually inherit methods from
interfaces; the interfaces merely specify the methods the class must
have.<a id="I_indexterm2_id640620" class="indexterm"/><a id="I_indexterm2_id640627" class="indexterm"/><a id="I_indexterm2_id640634" class="indexterm"/></p></div><div class="footnotes"><br/><hr/><div class="footnote"><p><sup>[<a id="ftn.learnjava3-CHP-2-FNOTE-2" href="#learnjava3-CHP-2-FNOTE-2" class="para">3</a>] </sup>Event handling in Java 1.0 was a very different story. Early
on, Java did not have a notion of event listeners and all event
handling happened by overriding methods in base GUI classes. This
was both inefficient and led to poor design with a proliferation of
highly specialized components.</p></div></div></div></body></html>