epubjs
Version:
Render ePub documents in the browser, across many devices
121 lines (120 loc) • 16 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Event Hookups and Adapters</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="Event Hookups and Adapters"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-22-SECT-4"/>Event Hookups and Adapters</h1></div></div></div><p>Beans use events to communicate. As we mentioned in <a class="xref" href="ch16.html" title="Chapter 16. Swing">Chapter 16</a>, events are not limited to GUI components
but can be used for signaling and passing information in more general
applications. An event is simply a notification; information describing
the event and other data are wrapped up in a subclass of <code class="literal">EventObject</code> and passed to the receiving object
by a method invocation. Event sources register listeners that want to
receive the events when they occur. Event receivers implement the
appropriate listener interface containing the method needed to receive the
events. This is Java’s general event mechanism in a nutshell.</p><p>It’s often useful to place an adapter between an event source and a
listener. An adapter can be used when an object doesn’t know how to
receive a particular event; it enables the object to handle the event
anyway. The adapter can translate the event into some other action, such
as a call to a different method or an update of some data. One of the jobs
of NetBeans is to help us hook up event sources to event listeners.
Another job is to produce adapter code that allows us to hook up events in
more complex ways.</p><div class="sect2" title="Taming the Juggler"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-22-SECT-4.1"/>Taming the Juggler</h2></div></div></div><p><a id="idx11146" class="indexterm"/> <a id="idx11155" class="indexterm"/> <a id="idx11166" class="indexterm"/>Let’s get our juggler under control with the following
steps:</p><div class="orderedlist"><ol class="orderedlist"><li class="listitem"><p>Using the Properties pane, change the label of your button
to read “Start.”</p></li><li class="listitem"><p>Now click the small Connection Mode icon at the top of the
GUI builder (the second icon, showing two items with arrows
pointing at one another).</p></li><li class="listitem"><p>After pressing the button, NetBeans is waiting for us to
select two components to “hook up.” Click first on the Start
button and then on the <code class="literal">Juggler</code>.
NetBeans pops up the Connection Wizard, indicating the source
component (the button) and prompting you to choose from a large
list of events (see <a class="xref" href="ch22s04.html#learnjava3-CHP-22-FIG-4" title="Figure 22-4. Selecting a source event in the Connection Wizard">Figure 22-4</a>).
Most of them are standard Swing events that can be generated by
any kind of <code class="literal">JComponent</code>. What
we’re after is the button’s action event.</p></li><li class="listitem"><p>Expand the folder named <span class="emphasis"><em>action</em></span>, and
select <code class="literal">actionPerformed</code> as the
source event.</p></li><li class="listitem"><p>At the bottom of the dialog box NetBeans indicates the name
of an event handler method that it will generate for us. Leave the
method name as is. Click Next to go to the Specify Target
Operation screen for the <code class="literal">Juggler</code>.</p></li><li class="listitem"><p>The wizard prompts us to choose a property to set on the
<code class="literal">Juggler</code>, as shown in <a class="xref" href="ch22s04.html#learnjava3-CHP-22-FIG-5" title="Figure 22-5. Specifying a target operation in the Connection Wizard">Figure 22-5</a>. The display shows three of
the <code class="literal">Juggler</code>’s properties.
Choose the <code class="literal">juggling</code> property as
the target and click Next.</p></li><li class="listitem"><p>Enter <strong class="userinput"><code>true</code></strong> in the
Value field and click Finish. NetBeans takes you to the source
view and shows you the method it has generated to respond to the
button action.</p></li></ol></div><p>We have completed a hookup between the button and the
<code class="literal">Juggler</code>. When the button fires an
action event, the <code class="literal">juggling</code> property
of the <code class="literal">Juggler</code> is set to <code class="literal">true</code>.</p><p>Scroll around the source view and take a look at the code that
NetBeans has generated to make this connection for us. Specifically, in
the <code class="literal">initComponents()</code> method of our
class, it has created an anonymous inner class to serve as the <code class="literal">ActionListener</code> for <code class="literal">ActionEvent</code>s from our button (which it has
named <code class="literal">jButton1</code>):</p><a id="I_22_tt1215"/><pre class="programlisting"> <code class="n">jButton1</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code><code class="k">new</code> <code class="n">java</code><code class="o">.</code><code class="na">awt</code><code class="o">.</code><code class="na">event</code><code class="o">.</code><code class="na">ActionListener</code><code class="o">()</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">actionPerformed</code><code class="o">(</code><code class="n">java</code><code class="o">.</code><code class="na">awt</code><code class="o">.</code><code class="na">event</code><code class="o">.</code><code class="na">ActionEvent</code> <code class="n">evt</code><code class="o">)</code> <code class="o">{</code>
<code class="n">jButton1ActionPerformed</code><code class="o">(</code><code class="n">evt</code><code class="o">);</code>
<code class="o">}</code>
<code class="o">});</code></pre><p>The adapter calls a private method that sets the property on our
<code class="literal">Juggler</code>:</p><a id="I_22_tt1216"/><pre class="programlisting"> <code class="kd">private</code> <code class="kt">void</code> <code class="nf">jButton1ActionPerformed</code><code class="o">(</code><code class="n">java</code><code class="o">.</code><code class="na">awt</code><code class="o">.</code><code class="na">event</code><code class="o">.</code><code class="na">ActionEvent</code> <code class="n">evt</code><code class="o">)</code> <code class="o">{</code>
<code class="n">juggler1</code><code class="o">.</code><code class="na">setJuggling</code><code class="o">(</code><code class="kc">true</code><code class="o">);</code>
<code class="o">}</code></pre><div class="figure"><a id="learnjava3-CHP-22-FIG-4"/><div class="figure-contents"><div class="mediaobject"><a id="I_22_tt1217"/><img src="httpatomoreillycomsourceoreillyimages1707708.png" alt="Selecting a source event in the Connection Wizard"/></div></div><p class="title">Figure 22-4. Selecting a source event in the Connection Wizard</p></div><div class="figure"><a id="learnjava3-CHP-22-FIG-5"/><div class="figure-contents"><div class="mediaobject"><a id="I_22_tt1218"/><img src="httpatomoreillycomsourceoreillyimages1707709.png.jpg" alt="Specifying a target operation in the Connection Wizard"/></div></div><p class="title">Figure 22-5. Specifying a target operation in the Connection Wizard</p></div><p>You’ll notice that most of the code that was written for us is
shaded grey to indicate that it is autogenerated code and can’t be
directly modified. The body of the private method is open, however, and
we could modify it to perform arbitrary activities when the button is
pushed. In NetBeans, the hookup is just a starting point.</p><p>This may all seem a little obtuse. After all, if we had made the
<code class="literal">Juggler</code> an <code class="literal">ActionListener</code> in the first place, we would
expect to hook it directly to the button. The use of adapters provides a
great deal of flexibility, however, as we’ll see next.</p><p>To complete our example, click the Design button, then repeat the
process, adding a second <code class="literal">JButton</code>
labeled “Stop.” We could implement the Stop button in the same way that
we did the Start button, by passing a specific value to the juggling
method, but we’re going to try an alternative here. Click the Connection
Wizard icon; select the Stop button and the <code class="literal">Juggler</code> as its target. Again, choose the
<code class="literal">actionPerformed</code> method as the source,
but this time, instead of selecting a property on the <code class="literal">Juggler</code>, click the Method Call radio button to
see a list of available methods on the <code class="literal">Juggler</code> bean. Scroll all the way down and
select the <code class="literal">stopJuggling()</code> method.
Click Finish to complete the hookup, and look at the generated code if
you wish. With this, we have seen an example of hooking up a source of
action events to generate an arbitrary method call on a bean. (Of
course, there is a <code class="literal">startJuggling()</code>
method as well, which we could have used for the first button.)</p><div class="sect3" title="Running the example"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-22-SECT-4.1.1"/>Running the example</h3></div></div></div><p>Now, the <code class="literal">Juggler</code> will do our
bidding. Right-click on the <span class="emphasis"><em>LearningJava1.java</em></span>
file in the Projects tab of the Explorer pane (or in the source view
of the file) and select Run File. Watch as NetBeans compiles and runs
our example. You should be able to start and stop the juggler using
the buttons! When you are done, quit the juggler application and
return to the GUI editor. Close this example by closing its tab in the
workspace, and let’s move on. (There is no need to save the file
explicitly; NetBeans saves automatically as you edit.)<a id="I_indexterm22_id821301" class="indexterm"/><a id="I_indexterm22_id821308" class="indexterm"/><a id="I_indexterm22_id821315" class="indexterm"/></p></div></div><div class="sect2" title="Molecular Motion"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-22-SECT-4.2"/>Molecular Motion</h2></div></div></div><p><a id="idx11147" class="indexterm"/> <a id="idx11156" class="indexterm"/>Let’s look at one more interesting example, shown in <a class="xref" href="ch22s04.html#learnjava3-CHP-22-FIG-6" title="Figure 22-6. The Molecule bean and the Timer">Figure 22-6</a>. Create a new file in our project
as before, choosing Java GUI Forms from the Categories pane and JFrame
Form in the File Types pane. Call this file
<span class="emphasis"><em>LearningJava2</em></span>.</p><p>Grab a <a id="I_indexterm22_id821370" class="indexterm"/><code class="literal">Molecule</code> bean and place
it in the workspace. (The default <code class="literal">BorderLayout</code> maximizes its area if you place
the bean in the center.) If you run the example now, you will see that
by dragging the mouse within the image, you can rotate the model in
three dimensions. Try changing the type of molecule by using the
Properties pane: ethane is fun.<sup>[<a id="learnjava3-CHP-22-FN-1" href="#ftn.learnjava3-CHP-22-FN-1" class="footnote">45</a>]</sup></p><p>Let’s see what we can do with our molecule. Grab a <a id="I_indexterm22_id821403" class="indexterm"/><code class="literal">Timer</code> bean from the
palette. <code class="literal">Timer</code> is a clock.<sup>[<a id="learnjava3-CHP-22-FN-2" href="#ftn.learnjava3-CHP-22-FN-2" class="footnote">46</a>]</sup> Every so many milliseconds, <code class="literal">Timer</code> fires an event. The timer is controlled
by an <code class="literal">long</code> property called <code class="literal">delay</code>, which determines the number of
milliseconds between events. <code class="literal">Timer</code> is
an “invisible” bean; it is not derived from a <code class="literal">JComponent</code> and doesn’t have a graphical
appearance, just as an internal timer in an application doesn’t normally
have a presence on the screen. NetBeans shows these invisible beans just
like any other bean in the Navigator pane on the left. When you wish to
select the <code class="literal">Timer</code>, click on it in the
tree in the Navigator pane.</p><p>Let’s hook the <code class="literal">Timer</code> to our
<code class="literal">Molecule</code>. Start the Connection Wizard
and select the <code class="literal">Timer</code> (from the tree)
and then the <code class="literal">Molecule</code>. Choose the
<code class="literal">Timer</code>’s <a id="I_indexterm22_id821505" class="indexterm"/><code class="literal">timerFired()</code> event from
the list (expand the folder to display it). Click Next and select the
Method Call radio button. Find and select the <a id="I_indexterm22_id821517" class="indexterm"/><code class="literal">rotateOnX()</code> method and
click Finish. Run the example. Now the <code class="literal">Molecule</code> should turn on its own every time it
receives an event from the timer. Try changing the timer’s <code class="literal">delay</code> property. You can also hook the <code class="literal">Timer</code> to the <code class="literal">Molecule</code>’s <a id="I_indexterm22_id821551" class="indexterm"/><code class="literal">rotateOnY()</code> method. Use
a different instance of <code class="literal">Timer</code> and, by
setting different delay values, make it turn at different rates in each
dimension. Fun!<a id="I_indexterm22_id821569" class="indexterm"/><a id="I_indexterm22_id821576" class="indexterm"/></p><div class="figure"><a id="learnjava3-CHP-22-FIG-6"/><div class="figure-contents"><div class="mediaobject"><a id="I_22_tt1219"/><img src="httpatomoreillycomsourceoreillyimages1707710.png" alt="The Molecule bean and the Timer"/></div></div><p class="title">Figure 22-6. The Molecule bean and the Timer</p></div></div><div class="footnotes"><br/><hr/><div class="footnote"><p><sup>[<a id="ftn.learnjava3-CHP-22-FN-1" href="#learnjava3-CHP-22-FN-1" class="para">45</a>] </sup>As of this writing, Sun’s Molecule example has some problems
when used in NetBeans. Selecting a molecule type other than the
default causes a compile-time error. You can use the Preview Design
button on the NetBeans form editor to try the other molecule
types.</p></div><div class="footnote"><p><sup>[<a id="ftn.learnjava3-CHP-22-FN-2" href="#learnjava3-CHP-22-FN-2" class="para">46</a>] </sup>A <code class="literal">Timer</code> bean used to come
with the NetBeans distribution but disappeared in version 4.0, so
we’ve added our own replacement. We won’t discuss it here, but the
source code is with the other bean examples and there is nothing
special that isn’t covered elsewhere.</p></div></div></div></body></html>