Tải bản đầy đủ - 0 (trang)
Hack 12. Add Translucence to Menus

Hack 12. Add Translucence to Menus

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

AllMenuItemsareimplementedbysomeformofthe

javax.swing.plaf.MenuItemUIclass.WhencreatingcustomUI

classes,itisalwaysbesttostartbysubclassingsomethingin

thejavax.swing.plaf.basicpackage(inthiscase,BasicMenuItemUI)

becauseithandlesmostoftheheavyliftingforyou,asshown

inExample1-28.



Example1-28.ExtendingthebasicUI











publicclassCustomMenuItemUIextendsBasicMenuItemUI{



publicstaticComponentUIcreateUI(JComponentc





returnnewCustomMenuItemUI();



}



















publicvoidpaint(Graphicsg,JComponentcomp)



//painttothebufferedimage



BufferedImagebufimg=newBufferedImag

































































































}



Graphics2Dg2=bufimg.createGraphics()

//restoretheforegroundcolorincase

g2.setColor(g.getColor());

super.paint(g2,comp);

//doanalphacomposite

Graphics2Dgx=(Graphics2D)g;

gx.setComposite(AlphaComposite.getInsta



AlphaComposite.SRC_OVER,0.8f));

gx.drawImage(bufimg,0,0,null);







}



comp.getWidth(),

comp.getHeight(),

BufferedImage.TYPE_INT_ARGB);



NoconstructorisrequiredbecauseallUIclasseshaveano-arg

constructorautomatically.AllUIclassesalsoneedastatic

createUI()methodtocreateanewinstanceoftheclass,asyou

canseeintheexample.Inthepaint()method,insteadof

drawingonthegraphicsobjectpassedin,thecodecreatesa

bufferedimagewiththesamedimensionsasthecomponent,

andthencallssuper.paint().Thiswilldrawthecomponentonto

thebufferedimageinsteadofthescreen.Oncethepaintingis

done,itcanapplyatransformandthendrawtheimagebuffer

ontotherealGraphics.Inthiscase,thetransformisanalpha

compositeof0.8.Thismeansthatinsteadofdrawingthebuffer

asis,itwilldrawthebufferpartiallytransparent(80%solid,in

thiscase).Thiswilldrawthebufferedimageintotherealgraphics

withatranslucenteffect.Youcanvarythestrengthofthe

translucencybymodifyingthesecondparametertothe

AlphaComposite.getInstance()method(1resultsinasolid,0istotally

transparent).



1.13.2.AddaCustomJMenu

Ifyoustoppedwithjustthecustommenuitems,themenus

wouldseemabittranslucent,buttherestofthewindow

wouldn'tshinethrough.Thisisbecausethemenuitemsare

insideofanothercomponent;infact,they'reinsideofthree!

TheJMenuputsallofthemenuitemsinsideofaJPopupMenu,which

isplacedinsideofaJPanel,andthenthewholedealisputina

layeredpaneatthetopoftheframe.Thelayeredpaneis

alreadytransparent,soyoudon'tneedtoworryaboutit,but

theJPanelandJPopupMenuaregoingtobeaproblem.Example129handlesthecustomUIforthese.



Example1-29.HandlingtranslucenceforJPanels

andJPopupMenus













publicclassCustomPopupMenuUIextendsBasicPopupMenuUI



publicstaticComponentUIcreateUI(JComponentc





returnnewCustomPopupMenuUI();



}























publicvoidinstallUI(JComponentc){



super.installUI(c);



popupMenu.setOpaque(false);

}































publicPopupgetPopup(JPopupMenupopup,intx,



Popuppp=super.getPopup(popup,x,y);



JPanelpanel=(JPanel)popup.getParent(



panel.setOpaque(false);



returnpp;

}







}



Thecustompop-upmenuUIusedhereissimilartothe

CustomMenuItemUI(fromExample1-28).IthasastaticcreateUI

menuandnoconstructor.Thepop-upmenuisalreadystoredas

aprotectedmemberoftheBasicPopupMenuUIparentclass,soIcan

accessiteasily.TheinstallUI()methodiscalledrightafterthe

JPopupMenuiscreated,sothisisthebestplacetoputacallto

setOpaque(false).FormostL&Fs,thiswillmakethecomponent

transparent.

Thattakescareofthepop-upmenu,butwhatabouttheparent

JPanel?TheJPaneliscreatedandinitializeddeepwithinthe

javax.swing.PopupFactoryclass,soit'sprettywelloutofreach.This

isoneplacewherehavingaccesstotheJREsourcecodeis

invaluable.Withoutthat,thisentirehackwouldhavebeen

impossibletofigureout.Fortunately,wehaveaccesstothe

finishedJPopupMenufromwithinthegetPopupmethod.Ioverrode



thattocallthesuperclassandthengrabthenewlyminted

parentofthepop-upmenuandcastittoaJPanel.Now,Ican

finallysetittobetransparent,too.



1.13.3.TestItOut

WithyourtwocustomUIclassesinplace,testthemoutwith

Example1-30,whichshowsaframecontainingtwosetsof

menusandafewcomponents.Beforecreatinganycomponents,

theprograminstalledthecustomUIclasseswithtwocallsto

UIManager.put().



AnytimeyouwanttooverridepartofaL&F,youcanuse

UIManager.put().



Example1-30.Testingoutthetranslucentmenus





























publicclassMenuTest{



publicstaticvoidmain(String[]args)throwsE





UIManager.put("PopupMenuUI","CustomPopu





UIManager.put("MenuItemUI","CustomMenuI





JFrameframe=newJFrame();





JMenuBarmb=newJMenuBar();





frame.setJMenuBar(mb);





JMenumenu=newJMenu("File");





mb.add(menu);





menu.add(newJMenuItem("Open"));





menu.add(newJMenuItem("Save"));





menu.add(newJMenuItem("Close"));





menu.add(newJMenuItem("Exit"));





















menu=newJMenu("Edit");

mb.add(menu);











































































menu.add(newJMenuItem("Cut"));

menu.add(newJMenuItem("Copy"));

menu.add(newJMenuItem("Paste"));

menu.add(newJMenuItem("PasteSpecial..

frame.getContentPane().setLayout(newBo

frame.getContentPane().add("North",new

frame.getContentPane().add("Center",new

frame.getContentPane().add("South",new

frame.pack();

frame.setSize(200,150);

frame.show();











}



}



Withallofthecodeinplace,youcancompileitandget

somethingthatlookslikeFigure1-30.



Figure1-30.Translucentmenu



Onebugyouwillnoticeisthatafteryouopenthemenuand

startmovingthecursorbetweenmenuitems,thebackground

won'tshinethroughanymore.ThisisbecauseSwing,inan

efforttospeeduptheUI,onlyrepaintsthepartsitknowshave

changed.Itrepaintsthemenuitem,butnottheframecontents

below(thebuttonandlabel,inthiscase)becauseitthinksthey

areobscuredbythemenuitem.Ofcourse,themenuitemis

translucent,sothecomponentsshouldshinethrough,but

Swingdoesn'tknowthat.Tofixtheproblem,you'llneedto

developafullrepaintmanager[Hack#53]thatwillforce

Swingtoalwaysrepainttheentirecomponenttree,insteadof

justthemenuitems.It'sabitslower,butworthitifyoureally

wantthiseffect:







UIManager.put("MenuItemUI","CustomMenuItemUI");

RepaintManager.setCurrentManager(newFullRepaintManager



Onemorebugisthatthemenumustfitwithintheframe.There

aretwokindsofmenusinSwing:heavyweightandlightweight.

LightweightmenusarenormalSwingcomponents.Heavyweight

menus,ontheotherhand,aredrawnintheirowntop-level

window.Thismeansthattherearetwowindowsbeingdrawn:

onefortherealframeandoneforthemenu.Ifyouuse

heavyweightmenus,theeffectwillstopcompletelybecausethe

windowsthemselvescan'tbetransparent.Normally,Swingwill

uselightweightmenus,butifthemenuhastobedrawnoutside

oftheframewhichcanhappenifyouhaveasmallwindowora

reallylargemenuthenitwillswitchtoheavyweightmenus

automaticallyandnothingcanswitchitbackuntilthe

applicationrestarts.Thismeansyoushouldalwaysmakesure

yourmenusfitinsideofyourwindows.



1.13.4.FutureIdeas

Thishackshowsjustoneexampleofhowyoucancompletely

changeacomponent'sbehaviorbycustomizingitsLookand

Feelclass.Java2Dgivesyouthepowertocreateawidevariety

ofgraphicalhacks.Asanextensionofthistechnique,youcould

tryblurringthecomponentsunderneaththemenuorcreatea

properlysmootheddropshadow.



Chapter2.ListsandCombos

Section2.1.Hacks1320:Introduction

Hack13.FilterJLists

Hack14.AddaFilterHistory

Hack15.MakeJListsCheckable

Hack16.MakeDifferentListItemsLookDifferent

Hack17.ReorderaJListwithDrag-and-Drop

Hack18.AnimateYourJListSelections

Hack19.TurnMethodsintoListRenderers

Hack20.CreateaCollections-AwareJComboBox



2.1.Hacks1320:Introduction

Listsareunderratedandunderappreciated,anddeveloperswho

don'tappreciateJListsoftenuseJTableswhentheydon'tneed

to.Butlistsseemtobemakingacomebackindesktop

applications,andwithgoodreason.Alotofthedatawedeal

witharesingle-dimensioncollectionssearchresults,recent

URLs,downloadedfiles,etc.andbymakingtheonscreenversion

ofthemmoreappealingandmoreusable,alististherightway

topresentthisdatatotheuser.



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

Hack 12. Add Translucence to Menus

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

×