📄 ch5.htm
字号:
which is used internally by <TT><FONT FACE="Courier">drawImage</FONT></TT>
to get information about the image.
<P>
The first version of <TT><FONT FACE="Courier">drawImage</FONT></TT>
draws the image at the specified <TT><FONT FACE="Courier">x</FONT></TT>
and <TT><FONT FACE="Courier">y</FONT></TT> location-<TT><FONT FACE="Courier">x</FONT></TT>
and <TT><FONT FACE="Courier">y</FONT></TT> represent the upper-left
corner of the image. The second version draws the image inside
the rectangle formed by <TT><FONT FACE="Courier">x</FONT></TT>,
<TT><FONT FACE="Courier">y</FONT></TT>, <TT><FONT FACE="Courier">width</FONT></TT>,
and <TT><FONT FACE="Courier">height</FONT></TT>. If this rectangle
is different than the image rectangle, the image will be scaled
to fit. The third version of <TT><FONT FACE="Courier">drawImage</FONT></TT>
draws the image with transparent areas filled in with the background
color specified in the <TT><FONT FACE="Courier">bgcolor</FONT></TT>
parameter. The last version of <TT><FONT FACE="Courier">drawImage</FONT></TT>
combines the capabilities in the first three, enabling you to
draw an image within a given rectangle and with a background color.
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Don't worry if you haven't heard of transparency before; you learn all about it in <A HREF="ch6.htm" >Day 6</A>, "Sprite Animation." For now, just think of it as areas in an image that aren't drawn, resulting in the background showing through.
</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<P>
The process of drawing an image involves calling the <TT><FONT FACE="Courier">getImage</FONT></TT>
method to load the image, followed by a call to <TT><FONT FACE="Courier">drawImage</FONT></TT>,
which actually draws the image on a graphics context. The DrawImage
sample applet shows how easy it is to draw an image (see Figure
5.8).
<P>
<A HREF="f5-8.gif" ><B>Figure 5.8 : </B><I>The DrawImage sample applet.</I></A>
<P>
The source code for the DrawImage sample applet is shown in Listing
5.2.
<HR>
<BLOCKQUOTE>
<B>Listing 5.2. The DrawImage sample applet.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">// DrawImage Class<BR>
// DrawImage.java<BR>
<BR>
// Imports<BR>
import java.applet.*;<BR>
import java.awt.*;<BR>
<BR>
public class DrawImage extends Applet {<BR>
public void paint(Graphics g) {<BR>
Image img = getImage(getCodeBase(), "Res/Ride.gif");
<BR>
<BR>
g.drawImage(img, (size().width - img.getWidth(this))
/ 2,<BR>
(size().height - img.getHeight(this))
/ 2, this);<BR>
}<BR>
}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The DrawImage sample applet loads an image in the <TT><FONT FACE="Courier">paint</FONT></TT>
method using <TT><FONT FACE="Courier">getImage</FONT></TT>. The
<TT><FONT FACE="Courier">getCodeBase</FONT></TT> method is used
to specify the applet directory where applet resources are usually
located, while the image name itself is simply given as a string.
The image is actually stored in the <I>Res</I> subdirectory beneath
the applet directory, as evident by the image name (<TT><FONT FACE="Courier">"Res/Ride.gif"</FONT></TT>)
passed into <TT><FONT FACE="Courier">getImage</FONT></TT>. The
image is then drawn centered in the applet window using the <TT><FONT FACE="Courier">drawImage</FONT></TT>
method. It's as simple as that!
<H2><A NAME="TrackingImages"><B><FONT SIZE=5 COLOR=#FF0000>Tracking
Images</FONT></B></A></H2>
<P>
Even though images are a very neat way of displaying high-quality
graphics within a Java applet, they aren't without their drawbacks.
The biggest problem with using images is the fact that they must
be transmitted over the Web as needed, which brings up the issue
of transmitting multimedia content over a limited bandwidth. This
means that the speed at which images are transferred over a Web
connection will often cause a noticeable delay in a Java applet
reliant on them, such as games.
<P>
There is a standard technique for dealing with transmission delay
as it affects static images. You've no doubt seen this technique
at work in your Web browser when you've viewed images in Web pages.
The technique is known as <I>interlacing</I>, and it makes images
appear blurry until they have been completely transferred. To
use interlacing, images must be stored in an interlaced format
(usually GIF version 89a), which means that the image data is
arranged in a way so that the image can be displayed before it
is completely transmitted. Interlacing is a good approach to dealing
with transmission delays for static images because it enables
you to see the image as it is being transferred. Without interlacing,
you have to wait until the entire image has been transferred before
seeing it at all.
<P>
Before you get too excited about interlacing, keep in mind that
it is useful only for static images. You're probably wondering
why this is the case. It has to do with the fact that animations
(dynamic images) rely on rapidly displaying a sequence of images
over time, all of which must be readily available to successfully
create the effect of movement.
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Don't worry if this animation stuff is new to you; you learn all the juicy details on <A HREF="ch6.htm" >Day 6</A>.
</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<P>
An animation sequence wouldn't look right using interlacing, because
some of the images would be transferred before others. A good
solution would be to just wait until all the images have been
transferred before displaying the animation. That's fine, but
how do you know when the images have all been transferred? Enter
the Java media tracker.
<P>
The Java media tracker is an object that tracks when media objects,
such as images, have been successfully transferred. Using the
media tracker, you can keep track of any number of media objects
and query to see when they have finished being transmitted. For
example, suppose you have an animation with four images. Using
the media tracker, you would register each of these images and
then wait until they have all been transferred before displaying
the animation. The media tracker keeps up with the load status
of each image. When the media tracker reports that all the images
have been successfully loaded, you are guaranteed that your animation
has all the necessary images to display correctly.
<H3><A NAME="TheMediaTrackerClass"><B>The </B><TT><B><FONT SIZE=4 FACE="Courier">MediaTracker</FONT></B></TT><B><FONT SIZE=4>
Class</FONT></B></A></H3>
<P>
The Java <TT><FONT FACE="Courier">MediaTracker</FONT></TT> class
is part of the awt package and contains a variety of members and
methods for tracking media objects. Unfortunately, the <TT><FONT FACE="Courier">MediaTracker</FONT></TT>
class that ships with release 1.0 of the Java development kit
supports only image tracking. Future versions of Java are expected
to add support for other types of media objects such as sound
and music.
<P>
The <TT><FONT FACE="Courier">MediaTracker</FONT></TT> class provides
member flags for representing various states associated with tracked
media objects. These flags are returned by many of the member
functions of <TT><FONT FACE="Courier">MediaTracker</FONT></TT>
and are as follows:
<UL>
<LI><TT><FONT FACE="Courier">LOADING</FONT></TT>: Indicates that
a media object is currently in the process of being loaded.
<LI><TT><FONT FACE="Courier">ABORTED</FONT></TT>: Indicates that
the loading of a media object has been aborted.
<LI><TT><FONT FACE="Courier">ERRORED</FONT></TT>: Indicates that
some type of error occurred while loading a media object.
<LI><TT><FONT FACE="Courier">COMPLETE</FONT></TT>: Indicates that
a media object has been successfully loaded.
</UL>
<P>
The <TT><FONT FACE="Courier">MediaTracker</FONT></TT> class provides
a variety of methods for helping to track media objects:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">MediaTracker(Component comp)<BR>
void addImage(Image image, int id)<BR>
synchronized void addImage(Image image, int id, int w, int h)
<BR>
boolean checkID(int id)<BR>
synchronized boolean checkID(int id, boolean load)<BR>
boolean checkAll()<BR>
synchronized boolean checkAll(boolean load)<BR>
void waitForID(int id)<BR>
synchronized boolean waitForID(int id, long ms)<BR>
void waitForAll()<BR>
synchronized boolean waitForAll(long ms)<BR>
int statusID(int id, boolean load)<BR>
int statusAll(boolean load)<BR>
synchronized boolean isErrorID(int id)<BR>
synchronized boolean isErrorAny()<BR>
synchronized Object[] getErrorsID(int id)<BR>
synchronized Object[] getErrorsAny()</FONT></TT>
</BLOCKQUOTE>
<P>
The constructor for <TT><FONT FACE="Courier">MediaTracker</FONT></TT>
takes a single parameter of type <TT><FONT FACE="Courier">Component</FONT></TT>.
This parameter specifies the <TT><FONT FACE="Courier">Component</FONT></TT>
object on which tracked images will eventually be drawn. This
parameter reflects the current limitation of being able to track
only images with the <TT><FONT FACE="Courier">MediaTracker</FONT></TT>
class and not sounds or other types of media.
<P>
The <TT><FONT FACE="Courier">addImage</FONT></TT> methods add
an image to the list of images currently being tracked. Both methods
take as their first parameter an <TT><FONT FACE="Courier">Image</FONT></TT>
object and as their second parameter an identifier that uniquely
identifies the image. If you want to track a group of images together,
you can use the same identifier for each image. The second <TT><FONT FACE="Courier">addImage</FONT></TT>
method has additional parameters for specifying the width and
height of a tracked image. This version of <TT><FONT FACE="Courier">addImage</FONT></TT>
is used for tracking images that you are going to scale; you pass
the width and height that you want to use for the scaled the image.
<P>
After you have added images to the <TT><FONT FACE="Courier">MediaTracker</FONT></TT>
object, you are ready to check their status. You use the <TT><FONT FACE="Courier">checkID</FONT></TT>
methods to check whether images matching the passed identifier
have finished loading. Both versions of <TT><FONT FACE="Courier">checkID</FONT></TT>
return <TT><FONT FACE="Courier">false</FONT></TT> if the images
have not finished loading, and <TT><FONT FACE="Courier">true</FONT></TT>
otherwise. Both methods return <TT><FONT FACE="Courier">true</FONT></TT>
even if the loading has been aborted or if an error has occurred.
You must call the appropriate error checking methods to see whether
an error has occurred. (You learn the error checking methods a
little later in this section.) The only difference between the
two <TT><FONT FACE="Courier">checkID</FONT></TT> methods is how
each loads an image. The first version of <TT><FONT FACE="Courier">checkID</FONT></TT>
does not load an image if that image has not already begun loading.
The second version enables you to specify that the image should
be loaded even if it hasn't already begun loading, which is carried
out by passing <TT><FONT FACE="Courier">true</FONT></TT> in the
<TT><FONT FACE="Courier">load</FONT></TT> parameter.
<P>
The <TT><FONT FACE="Courier">checkAll</FONT></TT> methods are
very similar to the <TT><FONT FACE="Courier">checkID</FONT></TT>
methods, except that they apply to all images, not just those
matching a certain identifier. Similar to the <TT><FONT FACE="Courier">checkID</FONT></TT>
methods, the <TT><FONT FACE="Courier">checkAll</FONT></TT> methods
come in two versions. The first version checks to see whether
the images have finished loading, but doesn't load any images
that haven't already begun loading. The second version also checks
the status of loading images but enables you to indicate that
images are to be loaded if they haven't started already.
<P>
You use the <TT><FONT FACE="Courier">waitForID</FONT></TT> methods
to begin loading images with a certain identifier. This identifier
should match the identifier used when the images were added to
the media tracker with the <TT><FONT FACE="Courier">addImage</FONT></TT>
method. Both versions of <TT><FONT FACE="Courier">waitForID</FONT></TT>
are synchronous, meaning that they do not return until all the
specified images have finished loading or an error occurs. The
second version of <TT><FONT FACE="Courier">waitForID</FONT></TT>
enables you to specify a timeout period, in which case the load
will end and <TT><FONT FACE="Courier">waitForID</FONT></TT> will
return <TT><FONT FACE="Courier">true</FONT></TT>. You specify
the timeout period in milliseconds by using the <TT><FONT FACE="Courier">ms</FONT></TT>
parameter.
<P>
The <TT><FONT FACE="Courier">waitForAll</FONT></TT> methods are
very similar to the <TT><FONT FACE="Courier">waitForID</FONT></TT>
methods, except they operate on all images. Like the <TT><FONT FACE="Courier">waitForID</FONT></TT>
methods, there are versions of <TT><FONT FACE="Courier">waitForAll</FONT></TT>
both with and without timeout support.
<P>
You use the <TT><FONT FACE="Courier">statusID</FONT></TT> method
to determine the status of images matching the identifier passed
in the <TT><FONT FACE="Courier">id</FONT></TT> parameter. <TT><FONT FACE="Courier">statusID</FONT></TT>
returns the bitwise <TT><FONT FACE="Courier">OR</FONT></TT> of
the status flags related to the images. The possible flags are
<TT><FONT FACE="Courier">LOADING</FONT></TT>, <TT><FONT FACE="Courier">ABORTED</FONT></TT>,
<TT><FONT FACE="Courier">ERRORED</FONT></TT>, and <TT><FONT FACE="Courier">COMPLETE</FONT></TT>.
To check for a particular status flag, you mask the flag out of
the return value of <TT><FONT FACE="Courier">statusID</FONT></TT>,
like this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">if (tracker.statusID(0, true) & MediaTracker.ERRORED)
{<BR>
// there was an error!<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
The second parameter to <TT><FONT FACE="Courier">statusID</FONT></TT>,
<TT><FONT FACE="Courier">load</FONT></TT>, should be familiar
to you by now because of its use in the other media tracker methods.
It specifies whether you want the images to begin loading if they
haven't begun already. This functionality is very similar to that
provided by the second version of the <TT><FONT FACE="Courier">checkID</FONT></TT>
and <TT><FONT FACE="Courier">waitForID</FONT></TT> methods.
<P>
The <TT><FONT FACE="Courier">statusAll</FONT></TT> method is very
similar to the <TT><FONT FACE="Courier">statusId</FONT></TT> method;
the only difference is that <TT><FONT FACE="Courier">statusAll</FONT></TT>
returns the status of all the images being tracked rather than
those matching a specific identifier.
<P>
Finally, you arrive at the error-checking methods mentioned earlier
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -