Tải bản đầy đủ - 0 (trang)
Hack 64. Turn the Spotlight on Swing

Hack 64. Turn the Spotlight on Swing

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

8.10.1.TheMetaphor

Ifyouhaveeverbeentoacomicshow,tothetheatre,ortothe

circus,you'veprobablynoticedhowspotlightsareusedtomove

yourfocustoaparticularlocationonthestage.Asearch

operationcanbecomparedtoatheatrestage,whereactors

havebeenreplacedbysearchresults.Youjustneedtogetthe

usertofocusontherightlocation.

Takealookatanexampleapplication,showninFigure8-12,

whichdisplaysapredefinedsetofbooksandletsyousearchfor

oneormoreofthembyenteringasearchqueryinthetextfield

atthebottomofthewindow.

Sincetheapplicationisjustademo,youcanonlyenteroneof

thefollowingqueries:books,sci-fi,adams,andpratchett.Each

query,whenvalidatedbytheEnterkey,willfindtherelated



booksandspotlightthem,asshowninFigure8-13.



Figure8-12.Thebookshelfapplicationmustlet

theusersearchforbooks



Figure8-13.Searchingfor"sci-fi"highlights

ScienceFictionbooks



Youcanevengoonestepfurther:themorelightyoushed,the

lessdarknessthereis.Forinstance,whenseveralbooksare

found,itislikelythatthesearchquerywasnotveryprecise.

Thismeanstheuserwillbemoreinterestedinlotsofitems.

Whenthequeryyieldsonlyafewresults,itislikelythatthe

userwantstoseeonlyafewspecificitems.

Asyoucreateseveralspotlightsoneperresulttheinterfaceis

lessdarkenedthanwithonlyonespotlight.Ifyoutakeaclose

lookatFigure8-13,you'llbeabletoperceivetheotherbooks.

Nevertheless,asinglesearchresultwillpreventtheuserfrom

seeingtheotherbooks,asshowninFigure8-14.



Figure8-14.Withonlyonespotlight,itisalmost

impossibletoseetheotherbooks



8.10.2.AddtheSpotlight

TheimplementationofspotlightsforSwingisdividedintotwo

classes,SpotlightPanelandSpotlight.Thefirstclassisaglass

panethatneedstobesetuponaframe,andthesecond

definesthelocationandtheshapeofaspotlight.Hereisan

exampleofhowtousespotlights:

SpotlightPanelglassPane=newSpotlightPanel();

setGlassPane(glassPane);

Spotlights1=glassPane.addSpotlight(0,0,25,50);

Spotlights2=glassPane.addSpotlight(100,100,30);



Here,youcreatetwospotlights:s1ands2.Thefirstisanellipse

25-pixelswide,50-pixelshigh,andlocatedatthetop-left

corneroftheframe;thesecondisacirclewitharadiusof30

pixelsandlocated100pixelsawayfromthetopandtheleftof

theframe'sborder.Eachspotlightisimplementedasanellipse



withtheclassEllipse2D.Double,asshowninExample8-11.



Example8-11.Representingaspotlightwithan

Ellipse2D

publicclassSpotlight

{



protectedEllipse2D.Doublespot;



protectedRectangle2D.Doublebounds;





publicSpotlight(intx,inty,intw,inth)



{





this.spot=newEllipse2D.Double(x,y,w,h);



}











publicEllipse2DgetSpot()

{



returnspot;

}











}



publicdoublegetArea()

{



returnMath.PI*spot.getWidth()*spot.getHeig

}



Asyoucanseeinthecode,theSpotlightclassisfairlysimple

andcontainsonlytwopublicmethods.Thefirstone,getSpot(),

returnstheEllipse2Dinstanceusedtodrawthespotlight.Itcan

alsobeusedtodynamicallychangethelocationandthesizeof

thespotlight.Onceyou'veinstalledafewspotlights,youwillbe

abletogetEllipse2Dtoanimatethem.Bymovingthemaround,

shrinkingthem,orgrowingthem,youcancreatestunning

effects.Thesecondmethodofthisclass,getArea(),isusedby



SpotlightPaneltodefinetheamountofdarknessaccordingtothe



totalareaoccupiedbythespotlightsonthewindow.Thus,if

youhaveenoughspotlightstocover80%ofthewindowwith

light,SpotlightPanelwilluseadarknessof20%.Inshort,

getArea()computesthegeometricalareaofthespotlight's

ellipse.

TheSpotlightPanelpanelclass(showninExample8-12)only

needsafewmethodsaswell.Youmustbeabletocreate

spotlights,toremoveaparticularspotlight,toremoveall

spotlights,andtopaintspotlightsonthescreen.Youalsoneed

twoconstructors.Ifyoulookatthepreviousfigures,youshould

seethatthespotlights'bordersareblurredtogetanicer

rendering.

Unfortunately,theblurringmethodusedinthepainting

algorithmisveryslowandpreventssmoothanimationofthe

spotlights.Toaccountforthis,youneedaspecialconstructorto

instructthepaneltodrawblurredborders,alongwitha

constructorthatleavesblurringatitsdefault(oninthisclass,

althoughyoumaywanttoleaveitoffnormally).Whenyou

needstillspotlights,activatetheblurtogetanicerresult.On

thecontrary,whenyouwanttoanimatethespotlights,

deactivatetheblurtogetfull-speedanimations.



Example8-12.ConstructorsoftheSpotlightPanel

class



publicclassSpotlightPanelextendsJComponentimplementsMouse

{



protectedbooleanblur;



protectedListspotlights;



protectedConvolveOpblurOp;



protectedRenderingHintshints;





publicSpotlightPanel()



































{



this(true);

}

publicSpotlightPanel(booleanblur)

{



this.blur=blur;



spotlights=newArrayList();



blurOp=newConvolveOp(getBlurKernel(3),Convo



hints=newRenderingHints(RenderingHints.KEY_R











RenderingHints.



hints.put(RenderingHints.KEY_ANTIALIASING,







RenderingHints.VALUE_ANTIALIAS_



hints.put(RenderingHints.KEY_FRACTIONALMETRICS,







RenderingHints.VALUE_FRACTIONAL

}





}



//othermethodsomitted



Thedefaultconstructorenablestheblur.Youcanusethe

secondconstructorandpassitfalsetodeactivatethisoption.

Therenderingoftheblureffectisdonewiththehelpofa

ConvolveOp.Youlearnedabouttheinnerworkingsofablur

operationwhenyoublurreddisabledcomponents[Hack#9].

TheconstructoralsocreatesaninstanceofArrayListinwhichall

thespotlightsarestored:

publicSpotlightaddSpotlight(intx,inty,intw,inth)

{



if(spotlights.size()==0)



{













}



setVisible(true);

addMouseListener(this);









}



Spotlightspot=newSpotlight(x,y,w,h);

spotlights.add(spot);

returnspot;



Whenanewspotlightisadded,thepanelismadevisible

immediately,andanewmouselistenerisregisteredonthe

glasspane.ThismouselistenersimplywaitsforamouseClicked()

eventtoclearthespotlightsandhidetheglasspane.This

featureisnecessarytolettheuserdecidewhenshewantsto

getbacktotheapplicationandhidethesearchresults.The

othermethodsrelatedtospotlightmanagementare

removeSpotlight(Spotlights)andclearSpotlights().Bothremovethe

mouselistenerandhidetheglasspanewhenallthespotlights

havebeenremoved.

ThemostimportantworkisdoneinthepaintSpotlights()method,

calledbythepaintComponent()method:

protectedvoidpaintSpotlights(Graphicsg)

{



if(spotlights.size()>0)



{





intwidth=getWidth();





intheight=getHeight();













doublescreenArea=width*height;

doublespotsArea=0.0;















Rectangle2Dscreen=newRectangle2D.Double(0,

Areamask=newArea(screen);











{



for(inti=0;i


















}



Spotlightspot=(Spotlight)spotlights.get(i);

spotsArea+=spot.getArea();

mask.subtract(newArea(spot.getSpot()));





Graphics2Dg2=(Graphics2D)g;



ColorshieldColor=newColor(0.0f,0.0f,0.0f,1.0f-

(spotsArea/screenArea));













if(blur)

{



BufferedImagebuffer=newBufferedImage(width,



BufferedImage.TYPE_INT_ARGB);



Graphics2Dg2buffer=(Graphics2D)buffer.creat



















g2buffer.setRenderingHints(hints);

g2buffer.setColor(shieldColor);

g2buffer.fill(mask);



















}

















}



g2.drawImage(buffer,blurOp,0,0);

}else{



g2.setRenderingHints(hints);



g2.setColor(shieldColor);



g2.fill(mask);



}



Theveryfirststepistocomputetheareaoftheglasspaneand

thetotalareaoccupiedbythespotlights.Whenthespotlights

listisbrowsedtocomputethearea,aparticularshapeis

created.AnAreaisaJava2Dshapethatenclosesanothershape,

andonwhichyoucanthenperformgeometricalboolean

operationslikesubtractingormergingshapes.Inthisexample,



spotlightscanbeseenasellipsoidalholesinablackrectangle.

Therefore,youfirstcreateanArea,calledmask,withaRectangle2D

thesizeoftheglasspaneandsubtracteachspotlighttothis

shape.UsinganAreahasmanyadvantages,themore

interestingbeingthepossibilitytooverlapthespotlights,as

showninFigure8-15.



Figure8-15.Bysubtractingellipsestoa

rectangle,youcaneasilyoverlapthespotlights



Thenextstepistodrawtheshapecontainingthespotlights.

Beforedoingthat,though,youneedtocomputetheopacityof

mask.WhenyoucreateanewColorinstance,youcandefinethe

opacityasanumberbetween0.0(fullytransparent),and1.0

(fullyopaque).Tocomputetherequiredopacity,theprogram

firstdividestheareaofthespotlightsbythetotalarea.

Thereby,ifspotlightsoccupy20%ofthetotalarea,youobtain

thevalue0.2.Subtractthisfrom1.0tocomputethefinal

opacity.Inthisexample,theopacitywouldbe0.8,or80%.

Thefinalstepoftherenderingdependsonwhetherblurringis



activated.Whenblurringisoff,themaskissimplyfilledwith

shieldColor.Notethattherenderinghintsdefinedinthe

constructorareusedatthismomenttodrawanti-aliased

shapes.Ifblurringisactivated,anextrastepisrequired.

Insteadofdrawingthespotlightsdirectlyontotheglasspane's

graphicssurface,anoffscreenbufferiscreated,withthesame

sizeasthepanelitself.Afterhavingdrawnmaskonthisoffscreen

buffer,theresultingpictureisdrawnontothepanel'sgraphics

surface.AllthemagichappenswhenyoucallthedrawImage()

methodwithaConvolveOpasthesecondparameter.Themethod

appliesourblurfilteronthepicturewhiledrawingit.

RomainGuy



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

Hack 64. Turn the Spotlight on Swing

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

×