Tải bản đầy đủ - 0 (trang)
Hack 42. Make Your Frame Dissolve

Hack 42. Make Your Frame Dissolve

Tải bản đầy đủ - 0trang

Here'sthebasicskeleton:

classDissolverextendsJComponentimplementsRunnable{



Frameframe;



Windowfullscreen;



intcount;



BufferedImageframe_buffer;



BufferedImagescreen_buffer;





publicDissolver(){}



DissolverisaJComponentthatimplementsRunnablesothatitcan



haveananimationloop.Ithasmembervariablesforthe

applicationframetodissolve(frame),thewindowthatcoversup

thescreen(fullscreen),ananimationcounter(count),andthe

twobuffersforstoringtheframeandthedesktopbackground

image(frame_bufferandscreen_buffer).



6.3.1.PreparetheDissolve

Dissolverhasonemethodtostartthedissolveprocesscalled

dissolveExit(),whichtakestheJFrameyouwanttodissolveand



generateseverythingelseitneedsinternally:











publicvoiddissolveExit(JFrameframe){



try{





this.frame=frame;





Robotrobot=newRobot();



























//capscreenw/frametoframebuffer

Rectangleframe_rect=frame.getBounds(

frame_buffer=robot.createScreenCaptur















//hideframe















frame.setVisible(false);













































//capscreenw/oframe

Dimensionscreensize=Toolkit.getDefau









.getS

Rectanglescreen_rect=newRectangle(0



screensize.width,screensize.he

screen_buffer=robot.createScreenCaptu













































//createbigwindoww/odecorations

fullscreen=newWindow(newJFrame());

fullscreen.setSize(screensize);

fullscreen.add(this);

this.setSize(screensize);

fullscreen.setVisible(true);















































}



//startanimation

newThread(this).start();

}catch(Exceptionex){



System.out.println(ex);



ex.printStackTrace();

}



dissolveExit()savesareferencetotheframeandcreatesanew

java.awt.Robottohandlethescreencaptures.Thenitcaptures



justtheareaofthescreencontainingtheframebycalling

robot.createScreenCatpure(),usingtherectanglereturnedby

frame.getBounds().Aftermakingthisscreencapture,ithidesthe

frameandthencapturestheentirescreenintothesecond

buffer.Finally,itcreatesanewWindowthatcoverstheentire

screen,addstheDissolverasthewindow'sonlychild,and

startstheanimationonanewthread.

Therearetwotrickythingstolookoutforhere.First,thecode



usesaWindowinsteadofaJFramesothatthewindowwon'tshow

upinatasklistorthedock.Thisalsomeansitwon'thaveany

windowdecorationsthatwouldruintheillusionoftransparency.

Second,theWindowconstructorrequiresyoutopassinanother

windoworframe.Thisisbecauseeverywindowisattachedtoa

parentwindowandwillonlybevisiblewhentheparentis(on

certainplatforms).Usingtheexistingapplicationframewon't

workbecauseit'sjustbeenhidden,butifyoucreateanew,

emptyJFrame,thewindowwillshowupfine.



6.3.2.RuntheAnimation

dissolveExit()createsanewthreadaroundtherun()method



(seethefollowingcode).Thismethodwillrequestarepainton

thecomponentevery100milliseconds,looping20timesand

thenquitting.Thiswillcreateatwo-seconddissolveanimation,

butyoucancertainlytweakthesevaluestoyourowntastes:



























publicvoidrun(){



try{





count=0;





Thread.currentThread().sleep(100);





for(inti=0;i<20;i++){







count=i;







fullscreen.repaint();







Thread.currentThread().sleep(1





}



}catch(InterruptedExceptionex){}



System.exit(0);

}



6.3.3.DotheDrawing



Nowthatthecomponentwillberepaintedforeachframeofthe

animation,youcanfinallydosomedrawing.Fadingtonothing

isreallyeasywithSwing.Youjustneedtodrawthebackground

imagefirst,andthendrawtheframeontopusingaComposite.A

Compositeisaclassthatknowstoadjustthestandardmechanism

insomeway.AnAlphaCompositewilldrawpartiallytransparent

imagesdependingonthealphavalueyoupassin.Analpha

valueof1willdrawtheimagefullyopaque,whileavalueof0

willbecompletelytransparent.Valuesbetween1and0will

drawtheimagepartiallytransparent.Alwaysbesuretosave

theoldcompositesoyoucanreturntheGraphicsobjecttoits

originalstatewhenyouaredone:













publicvoidpaint(Graphicsg){



Graphics2Dg2=(Graphics2D)g;



//drawthescreen,offsetincasethewindowi



g.drawImage(screen_buffer,-fullscreen.getX(),





-fullscreen.getY(),null);



































}



//drawtheframe

Compositeold_comp=g2.getComposite();

Compositefade=AlphaComposite.getInstance(



AlphaComposite.SRC_OVER,1.0f-((float)co

g2.setComposite(fade);

g2.drawImage(frame_buffer,frame.getX(),frame.g

g2.setComposite(old_comp);



TheclassinExample6-2createsaframewithonebuttoncalled

quit.WhenyoupresstheQuitbutton,thedissolvewillbe

activated,fadingthewindowintonothingandthencalling

System.exit().Ifyoucompileandrunthecode,itwilllook

somethinglikeFigure6-4.



Figure6-4.Afadedissolve



Example6-2.Asimpletestclass





publicclassDissolveHack{











publicstaticvoidmain(String[]args){



















































finalJFrameframe=newJFrame("Dissol

JButtonquit=newJButton("Quit");

quit.addActionListener(newActionListen



publicvoidactionPerformed(Act



newDissolver().dissolveExit(f



}

});































}













}



frame.getContentPane().add(quit);

frame.pack();

frame.setLocation(300,300);

frame.setSize(400,400);

frame.setVisible(true);



6.3.4.CreateaGenieEffect

OneofmyfavoritebitsofeyecandyfromMacOSXisthe

minimizedissolve.Whenyouclickontheminimizebuttonin

anyapplication,thewindowwillshrinkandslideintothedock.

Thisiscalledthegenieeffect,anditnotonlylookscool,butit

alsogivesyoufeedbackaboutwhereawindowhasgone.

Example6-3isasubclassofDissolverthatoverridesthepaint()

methodtocreateaspinning,shrinkingwindowthatsomewhat

mimicsthegenieeffect.



Example6-3.Addingagenieeffecttoyour

toolbox





classSpinDissolverextendsDissolver{















publicvoidpaint(Graphicsg){



Graphics2Dg2=(Graphics2D)g;



//drawthescreen,offsetincasethewindowi



g.drawImage(screen_buffer,-fullscreen.getX(),





-fullscreen.getY(),null);















//savethecurrenttransform

AffineTransformold_trans=g2.getTransform();















//movetotheupper-lefthandcornerofthefra

g2.translate(frame.getX(),frame.getY());















//movetheframeofftowardtheleft

g2.translate(-((count+1)*(frame.getX()+frame



















//shrinktheframe

floatscale=1f/((float)count+1);

g2.scale(scale,scale);



















//rotatearoundthecenter

g2.rotate(((float)count)/3.14/1.3,



frame.getWidth()/2,frame.getHeight()















//finallydrawtheframe

g2.drawImage(frame_buffer,0,0,null);









}







}



//restorethecurrenttransform

g2.setTransform(old_trans);



Thisdissolverwillshrinkthewindowandspinit,whilemovingit

towardtheleftatthesametime.Thismakethewindowlook

likeitisspinningoffintooblivion,asinFigure6-5.



Figure6-5.Aspindissolve



Thishackshowsoffjustafewofthereallycooleffectsyoucan

accomplishwithjustabitofJava2DcodeinyourSwing

application.BecausetheparentDissolveclasstakescareofmost

ofthetrickyparts,youcaneasilycreateyourownsubclasses

thatfocusonjusttheanimationitself.Youmightwanttotry

someotheranimations,suchasthecircleandlinearwipes

commontooldmovies,orabettergenieeffectthatworkswhen



youquityourapplication.Java2Dgivesyouthepowertodo

virtuallyanylineartransform(shear,scale,rotate,etc.),plus

compositesandconvolutions.Forevenmoreeffects,youcould

useJava3DorJOGLtocreatethree-dimensionaleffectslike

spinningcubesandperspectivetransforms.



Hack43.CreateCustomToolTips



Replacethestandardrollovertooltipwithanattractive

customversion,includingaborderandroundedcorners.

EverySwingcomponentcanhaveatooltip,alittlesnippetof

explanatorytextthatpopsupwhenyouletyourmousecursor

lingeroverthecomponent.Thesetooltipsareoftenuseful,but

theyusuallylookquiteboring.Thishackshowshowtocreate

visuallyinterestingtooltipswithacustomsubclass.

InSwing,alltooltipsareinstancesoftheJToolTipclass.To

createyourownversion,youneedonlysubclassJToolTipand

overridethepaintComponent()method.Inthishack,we'llcreatea

tooltipwitharectanglethathasabeveledborderandawhite

background.Theactualdrawingcanbetakencareofwithafew

Java2Ddrawingcommands.Example6-4isthecodetodraw

thetooltip'sbackgroundandborder.



Example6-4.Anice-lookingtooltip

classCustomToolTipextendsJToolTip{





publicvoidpaintComponent(Graphicsg){





//createaroundrectangle



Shaperound=newRoundRectangle2D.Float(4,4,

this.getWidth()-1-8,

this.getHeight()-1-8,





15,15);





//drawthewhitebackground















Graphics2Dg2=(Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,



RenderingHints.VALUE_ANTIALIAS_ON);

g2.setColor(Color.white);

g2.fill(round);

















//drawthegrayborder

g2.setColor(Color.gray);

g2.setStroke(newBasicStroke(5));

g2.draw(round);

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,



RenderingHints.VALUE_ANTIALIAS_DEFAULT);





//drawthetext



Stringtext=this.getComponent().getToolTipText();



if(text!=null){

FontMetricsfm=g2.getFontMetrics();

inth=fm.getAscent();

g2.setColor(Color.black);





g2.drawString(text,10,(this.getHeight()+h)/





}



}



Thiscodecreatesaroundrectangleshapethatisthenreused

todrawthebackgroundandborder.Noticethatanti-aliasingis

turnedonfordrawingtheshape,butit'sturnedbacktothe

default(whichcouldbeonoroff)beforedrawingthetext.It

wouldlookstrangetohaveanti-aliasedtextiftherestofthe

interfacewasstillusingstandardaliasedtextusingthedefaultis

asaferidea.

Becausethistooltipneedsextraspacearoundthetexttodraw

theborder,youwillneedtomodifythetooltip'spreferredsize.

ThegetPreferredSize()methodhereaddsanextra20pixelsin

eachdirection:



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Hack 42. Make Your Frame Dissolve

Tải bản đầy đủ ngay(0 tr)

×