📄 ch13.htm
字号:
<BR> /**<BR> * Standard paint routine for an applet.<BR> * @param g contains the Graphics classto use for painting<BR> */<BR> public void paint(Graphics g)<BR> {<BR> if ( complete)<BR> {<BR> g.drawImage(allImages[current],roll_x, 40, this);<BR> }<BR> else<BR> {<BR> g.drawString("Imagesnot yet loaded", 0, 20);<BR> }<BR> }<BR><BR> public void start()<BR> {<BR> if ( animation== null )<BR> {<BR> animation= new Thread(this);<BR> animation.start();<BR> }<BR> }<BR><BR> public void stop()<BR> {<BR> if ( animation!= null )<BR> {<BR> animation.stop();<BR> animation= null;<BR> }<BR> }<BR><BR> public void run()<BR> {<BR> while ( !checkRoll()) sleep(250);<BR> complete = true;<BR> while (true)<BR> {<BR> roll(0,this.size().width-42); // rollleft to right<BR> roll(this.size().width-42,0); // roll right to left<BR> }<BR> }<BR><BR> boolean checkRoll()<BR> {<BR> boolean finished= true;<BR> for ( int i =0; i < 4; i++ )<BR> {<BR> if( (tracker.statusID(i, true) & MediaTracker.COMPLETE) == 0)<BR> finished= false;<BR> }<BR> return finished;<BR> }<BR><BR> void roll(int begin, int end)<BR> {<BR> if ( begin <end )<BR> {<BR> for( int x = begin; x <= end; x += 21 )<BR> {<BR> roll_x= x;<BR> repaint();<BR> current--;<BR> if( current == -1 ) current = 3;<BR> sleep(150);<BR> }<BR> }<BR> else<BR> {<BR> for( int x = begin; x >= end; x -= 21 )<BR> {<BR> roll_x= x;<BR> repaint();<BR> current++;<BR> if( current == 4 ) current = 0;<BR> sleep(150);<BR> }<BR> }<BR> }<BR><BR> /**<BR> * A simple sleep routine<BR> * @param a the number of millisecondsto sleep<BR> */<BR> private void sleep(int a)<BR> {<BR> try<BR> {<BR> Thread.currentThread().sleep(a);<BR> }<BR> catch (InterruptedExceptione)<BR> {<BR> }<BR> }<BR>}</TT></BLOCKQUOTE><HR><P>The first thing the <TT>run()</TT>method does is start loading the four images; this is done byusing a MediaTracker object. It would have been more efficientto assign the same ID to all four, but I wanted to show you howto track individual images as well. When all the images have loaded,the animation can start. The <TT>run()</TT>thread updates the <TT>roll_x</TT>variable and image number every 150 milliseconds, and then issuesa repaint request.<P>The <TT>paint()</TT> method simplydraws the current image to the requested location.<BR><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD><B>Note</B></TD></TR><TR VALIGN=TOP><TD><BLOCKQUOTE>This applet will work even if the images are not preloaded with MediaTracker; however, failing to preload causes incomplete images to display. The object's position updates even though there are no images to paint. It's much more professional to wait until all the images are complete before beginning an animation.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>To really appreciate the power behind Java images, you need tounderstand the consumer/<BR>producer model in detail. Powerful graphics applications use theadvantages of this model to perform their visual wizardry. Inparticular, you can write effective image filters only if youunderstand the underlying model.<H2><A NAME="ImageProducers"><FONT SIZE=5 COLOR=#FF0000>ImageProducers</FONT></A></H2><P>The ImageProducer interface has the following methods:<UL><LI><TT>public void addConsumer(ImageConsumeric);</TT><LI><TT>public boolean isConsumer(ImageConsumeric);</TT><LI><TT>public void removeConsumer(ImageConsumeric);</TT><LI><TT>public void startProduction(ImageConsumeric);</TT><LI><TT>public void requestTopDownLeftRightResend(ImageConsumeric);</TT></UL><P>Notice that all the methods require an ImageConsumer object. Thereare no backdoors; an ImageProducer can output only through anassociated ImageConsumer. A given producer can have multiple objectsas client consumers, though this is not usually the case. Typically,as soon as a consumer registers itself with a producer <TT>[addConsumer()]</TT>,the image data is immediately delivered through the consumer'sinterface.<H3><A NAME="ImageConsumers">Image Consumers</A></H3><P>The ImageProducer interface is clean and straightforward, butthe ImageConsumer is quite a bit more complex. It has the followingmethods:<UL><LI><TT>public void setDimensions(int width,int height);</TT><LI><TT>public void setProperties(Hashtableprops);</TT><LI><TT>public void setColorModel(ColorModelmodel);</TT><LI><TT>public void setHints(int hintflags);</TT><LI><TT>public void setPixels(int x, inty, int w, int h, ColorModel model, byte pixels[], int off, intscansize);</TT><LI><TT>public void setPixels(int x, inty, int w, int h, ColorModel model, int pixels[], int off, intscansize);</TT><LI><TT>public void imageComplete(int status);</TT></UL><P>Figure 13.1 shows the normal progression of calls to the ImageConsumerinterface. Several methods are optional: <TT>setProperties()</TT>,<TT>setHints()</TT>, and <TT>setColorModel()</TT>.The core methods are first <TT>setDimensions()</TT>,followed by one or more calls to <TT>setPixels()</TT>.Finally, when there are no more <TT>setPixels()</TT>calls, <TT>imageComplete()</TT> isinvoked.<P><A HREF="f13-1.gif" ><B>Figure 13.1 : </B><I>Normal flow of calls to an ImageConsumar.</I></A><P>Each image has fixed rectangular dimensions, which are passedin <TT>setDimensions()</TT>. The consumerneeds to save this data for future reference. The <TT>setProperties()</TT>method has no discernible use right now, and most consumers don'tdo anything with it. The hint flags, however, are a differentstory. <I>Hints</I> are supposed to give clues about the formatof the producer's data. Table 13.1 lists the values for hint flags.<BR><P><CENTER><B>Table 13.1. Hint flag values for </B><TT><B>setHints()</FONT></B></TT><B><FONT SIZE=5>.</FONT></B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=152><I>Name</I></TD><TD WIDTH=438><I>Meaning</I></TD></TR><TR VALIGN=TOP><TD WIDTH=152><TT>RANDOMPIXELORDER=1</TT></TD><TD WIDTH=438>No assumptions should be made about the delivery of pixels.</TD></TR><TR VALIGN=TOP><TD WIDTH=152><TT>TOPDOWNLEFTRIGHT=2</TT></TD><TD WIDTH=438>Pixel delivery will paint in top to bottom, left to right.</TD></TR><TR VALIGN=TOP><TD WIDTH=152><TT>COMPLETESCANLINES=4</TT></TD><TD WIDTH=438>Pixels will be delivered in multiples of complete rows.</TD></TR><TR VALIGN=TOP><TD WIDTH=152><TT>SINGLEPASS=8</TT></TD><TD WIDTH=438>Pixels will be delivered in a single pass. No pixel will appear in more than one <TT>setPixel()</TT> call.</TD></TR><TR VALIGN=TOP><TD WIDTH=152><TT>SINGLEFRAME=16</TT></TD><TD WIDTH=438>The image consists of a single static frame.</TD></TR></TABLE></CENTER><P><P>When all the pixel information has been transmitted, the producerwill call <TT>imageComplete()</TT>.The status parameter will have one of three values: <TT>IMAGEERROR=1</TT>,<TT>SINGLEFRAMEDONE=2</TT>, or <TT>STATICFRAMEDONE=3</TT>.<P><TT>SINGLEFRAMEDONE</TT> indicatesthat additional frames will follow; for example, a video camerawould use this technique. Special-effect filters could also use<TT>SINGLEFRAMEDONE</TT>. <TT>STATICFRAMEDONE</TT>is used to indicate that no more pixels will be transmitted forthe image. The consumer should remove itself from the producerafter receiving <TT>STATICFRAMEDONE</TT>.<P>The two <TT>setPixels()</TT> callsprovide the image data. Keep in mind that the image size was setby <TT>setDimensions()</TT>. The arraywithin <TT>setPixels()</TT> callsdoes not necessarily contain all the pixels within an image. Infact, it usually contains only a rectangular subset of the totalimage. Figure 13.2 shows a rectangle of <TT>setPixels()</TT>within an entire image.<P><A HREF="f13-2.gif" ><B>Figure 13.2 : </B><I>The relationship of </I>SetPixels()<I> calls to an entire image.</I></A><P>The row size of the array is the <TT>scansize</TT>.The width and height parameters indicate the usable pixels withinthe array, and the offset contains the starting index. It is upto the consumer to map the passed array onto the entire image.The sub-image's location within the total image is contained inthe <TT>x</TT> and <TT>y</TT>parameters.<P>The ColorModel contains all needed color information for the image.The call to <TT>setColorModel()</TT>is purely informational because each <TT>setPixels()</TT>call passes a specific ColorModel parameter. No assumptions shouldbe made about the ColorModel from <TT>setColorModel()</TT>calls.<H2><A NAME="FilteringanImage"><FONT SIZE=5 COLOR=#FF0000>Filteringan Image</FONT></A></H2><P>Image filters sit between an ImageProducer and an ImageConsumerand must implement both these interfaces. Java supplies two separate
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -