📄 chapter13.html
字号:
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Applet2 <font color=#0000ff>extends</font> Applet {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> paint(Graphics g) {
g.drawString(<font color=#004488>"Second applet"</font>, 10, 15);
g.draw3DRect(0, 0, 100, 20, <font color=#0000ff>true</font>);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This puts a box around the string.
Of course, all the numbers are hard-coded and are based on pixels, so on some
machines the box will fit nicely around the string and on others it will
probably be off, because fonts will be different on different
machines.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There are other interesting things
you can find in the documentation for the <B>Graphic </B>class. Any sort of
graphics activity is usually entertaining, so further experiments of this sort
are left to the reader.</FONT><A NAME="_Toc408018682"></A><BR></P></DIV>
<A NAME="Heading397"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Demonstrating <BR>the framework methods</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It’s interesting to see some
of the framework methods in action. (This example will look only at
<A NAME="Index1567"></A><A NAME="Index1568"></A><B>init( )</B>,
<A NAME="Index1569"></A><A NAME="Index1570"></A><B>start( ),</B> and
<A NAME="Index1571"></A><A NAME="Index1572"></A><B>stop( ) </B>because
<B>paint( )</B> and <B>destroy( ) </B>are self-evident and not so
easily traceable.) The following applet keeps track of the number of times these
methods are called and displays them using
<B>paint( )</B>:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Applet3.java</font>
<font color=#009900>// Shows init(), start() and stop() activities</font>
<font color=#0000ff>import</font> java.awt.*;
<font color=#0000ff>import</font> java.applet.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Applet3 <font color=#0000ff>extends</font> Applet {
String s;
<font color=#0000ff>int</font> inits = 0;
<font color=#0000ff>int</font> starts = 0;
<font color=#0000ff>int</font> stops = 0;
<font color=#0000ff>public</font> <font color=#0000ff>void</font> init() { inits++; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> start() { starts++; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> stop() { stops++; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> paint(Graphics g) {
s = <font color=#004488>"inits: "</font> + inits +
<font color=#004488>", starts: "</font> + starts +
<font color=#004488>", stops: "</font> + stops;
g.drawString(s, 10, 10);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Normally when you override a method
you’ll want to look to see whether you need to call the base-class version
of that method, in case it does something important. For example, with
<B>init( )</B> you might need to call <B>super.init( )</B>. However,
the <B>Applet</B> documentation specifically states that the
<B>init( )</B>, <B>start( )</B>, and <B>stop( )</B> methods in
<B>Applet</B> do nothing, so it’s not necessary to call them
here.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When you experiment with this
applet you’ll discover that if you minimize the Web browser or cover it up
with another window you might not get calls to <B>stop( )</B> and
<B>start( )</B>.<B> </B>(This behavior seems to vary among implementations;
you might wish to contrast the behavior of Web browsers with that of applet
viewers.) The only time the calls will occur is when you move to a different Web
page and then come back to the one containing the
applet.</FONT><A NAME="_Toc375545447"></A><A NAME="_Toc408018683"></A><BR></P></DIV>
<A NAME="Heading398"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Making a button</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Making a button is quite simple:
you just call the <A NAME="Index1573"></A><A NAME="Index1574"></A><B>Button</B>
constructor with the label you want on the button. (You can also use the default
constructor if you want a button with no label, but this is not very useful.)
Usually you’ll want to create a handle for the button so you can refer to
it later.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>Button</B> is a component,
like its own little window, that will automatically get repainted as part of an
update. This means that you don’t explicitly paint a button or any other
kind of control; you simply place them on the form and let them automatically
take care of painting themselves. So to place a button on a form you override
<B>init( ) </B>instead of overriding <B>paint( )</B>:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Button1.java</font>
<font color=#009900>// Putting buttons on an applet</font>
<font color=#0000ff>import</font> java.awt.*;
<font color=#0000ff>import</font> java.applet.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Button1 <font color=#0000ff>extends</font> Applet {
Button
b1 = <font color=#0000ff>new</font> Button(<font color=#004488>"Button 1"</font>),
b2 = <font color=#0000ff>new</font> Button(<font color=#004488>"Button 2"</font>);
<font color=#0000ff>public</font> <font color=#0000ff>void</font> init() {
add(b1);
add(b2);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It’s not enough to create the
<B>Button</B> (or any other control). You must also call the <B>Applet</B>
<B>add( )</B> method to cause the button to be placed on the applet’s
form. This seems a lot simpler than it is, because the call to
<B>add( )</B> actually decides, implicitly, where to place the control on
the form. Controlling the layout of a form is examined
shortly.</FONT><A NAME="_Toc375545448"></A><A NAME="_Toc408018684"></A><BR></P></DIV>
<A NAME="Heading399"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Capturing an event</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You’ll notice that if you
compile and run the applet above, nothing happens when you press the buttons.
This is where you must step in and write some code to determine what will
happen. The basis of
<A NAME="Index1575"></A><A NAME="Index1576"></A><A NAME="Index1577"></A>event-driven
programming, which comprises a lot of what a GUI is about, is tying events to
code that responds to those events.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">After working your way this far
through the book and grasping some of the fundamentals of object-oriented
programming, you might think that of course there will be some sort of
object-oriented approach to handling events. For example, you might have to
inherit each button and override some “button pressed” method (this,
it turns out, is too tedious and restrictive). You might also think
there’s some master “event” class that contains a method for
each event you want to respond to.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Before objects, the typical
approach to handling events was the “giant switch statement.” Each
event would have a unique integer value and inside the master event handling
method you’d write a <B>switch</B> on that value.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The AWT in Java
1.0<A NAME="Index1578"></A> doesn’t use any object-oriented approach.
Neither does it use a giant <B>switch</B> statement that relies on the
assignment of numbers to events. Instead, you must create a cascaded set of
<B>if</B> statements. What you’re trying to do with the <B>if</B>
statements is detect the object that was the
<A NAME="Index1579"></A><A NAME="Index1580"></A><I>target</I> of the event. That
is, if you click on a button, then that particular button is the target.
Normally, that’s all you care about – if a button is the target of
an event, then it was most certainly a mouse click and you can continue based on
that assumption. However, events can contain other information as well. For
example, if you want to find out the pixel location where a mouse click occurred
so you can draw a line to that location, the <B>Event</B> object will contain
the location. (You should also be aware that Java 1.0 components can be limited
in the kinds of events they generate, while Java 1.1 and Swing/JFC components
produce a full set of events.)</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The Java
1.0<A NAME="Index1581"></A> AWT method where your cascaded <B>if</B> statement
resides is called
<A NAME="Index1582"></A><A NAME="Index1583"></A><B>action( )</B>. Although
the whole Java 1.0<A NAME="Index1584"></A> Event model has been deprecated in
Java 1.1<A NAME="Index1585"></A>, it is still widely used for simple applets and
in systems that do not yet support Java 1.1, so I recommend you become
comfortable with it, including the use of the following <B>action()</B> method
approach.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>action( )</B> has two
arguments: the first is of type
<A NAME="Index1586"></A><A NAME="Index1587"></A><B>Event</B> and contains all
the information about the event that triggered this call to
<B>action( )</B>. For example, it could be a mouse click, a normal keyboard
press or release, a special key press or release, the fact that the component
got or lost the focus, mouse movements, or drags, etc. The second argument is
usually the target of the event, which you’ll often ignore. The second
argument is also encapsulated in the <B>Event</B> object so it is redundant as
an argument.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The situations in which
<B>action( ) </B>gets called are extremely limited: When you place controls
on a form, some types of controls (buttons, check boxes, drop-down lists, menus)
have a “standard action” that occurs, which causes the call to
<B>action( )</B> with the appropriate <B>Event</B> object. For example,
with a button the <B>action( )</B> method is called when the button is
pressed and at no other time. Usually this is just fine, since that’s what
you ordinarily look for with a button. However, it’s possible to deal with
many other types of events via the
<A NAME="Index1588"></A><A NAME="Index1589"></A><B>handleEvent( )</B>
method as we will see later in this chapter.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The previous example can be
extended to handle button clicks as follows:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Button2.java</font>
<font color=#009900>// Capturing button presses</font>
<font color=#0000ff>import</font> java.awt.*;
<font color=#0000ff>import</font> java.applet.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Button2 <font color=#0000ff>extends</font> Applet {
Button
b1 = <font color=#0000ff>new</font> Button(<font color=#004488>"Button 1"</font>),
b2 = <font color=#0000ff>new</font> Button(<font color=#004488>"Button 2"</font>);
<font color=#0000ff>public</font> <font color=#0000ff>void</font> init() {
add(b1);
add(b2);
}
<font color=#0000ff>public</font> <font color=#0000ff>boolean</font> action(Event evt, Object arg) {
<font color=#0000ff>if</font>(evt.target.equals(b1))
getAppletContext().showStatus(<font color=#004488>"Button 1"</font>);
<font color=#0000ff>else</font> <font color=#0000ff>if</font>(evt.target.equals(b2))
getAppletContext().showStatus(<font color=#004488>"Button 2"</font>);
<font color=#009900>// Let the base class handle it:</font>
<font color=#0000ff>else</font>
<font color=#0000ff>return</font> <font color=#0000ff>super</font>.action(evt, arg);
<font color=#0000ff>return</font> <font color=#0000ff>true</font>; <font color=#009900>// We've handled it here</font>
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To see what the
<A NAME="Index1590"></A><A NAME="Index1591"></A>target is, ask the <B>Event</B>
object what its <B>target</B> member is and then use the
<A NAME="Index1592"></A><B>equals( )</B> method to see if it matches the
target object handle you’re interested in. When you’ve written
handlers for all the objects you’re interested in you must call
<A NAME="Index1593"></A><A NAME="Index1594"></A><B>super.action(evt, arg)</B> in
the <B>else</B> statement at the end, as shown above. Remember from Chapter 7
(polymorphism) that your overridden method is called instead of the base class
version. However, the base-class version contains code to handle all of the
cases that you’re not interested in, and it won’t get called unless
you call it explicitly. The return value indicates whether you’ve handled
it or not, so if you do match an event you should return <B>true</B>, otherwise
return whatever the base-class <B>event( )</B> returns.</FONT><BR></P></DIV>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -