Tải bản đầy đủ - 0 (trang)
Hack 18. Animate Your JList Selections

Hack 18. Animate Your JList Selections

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

importjava.awt.*;

importjavax.swing.*;

importjavax.swing.event.*;

importjava.util.*;

publicclassAnimatedJListextendsJList

implementsListSelectionListener{

staticjava.util.Randomrand=newjava.util.Random();



staticColorlistForeground,listBackground,

listSelectionForeground,listSelectionBackground;

staticfloat[]foregroundComps,backgroundComps,

foregroundSelectionComps,backgroundSelectionComps;



static{

UIDefaultsuid=UIManager.getLookAndFeel().getDefaults

listForeground=uid.getColor("List.foreground");

listBackground=uid.getColor("List.background");

listSelectionForeground=uid.getColor("List.selection

listSelectionBackground=uid.getColor("List.selection

foregroundComps=

listForeground.getRGBColorComponents(null);

foregroundSelectionComps=

listSelectionForeground.getRGBColorComponents(null)

backgroundComps=

listBackground.getRGBColorComponents(null);

backgroundSelectionComps=

listSelectionBackground.getRGBColorComponents(null)

}

publicColorcolorizedSelectionForeground,

colorizedSelectionBackground;

publicstaticfinalintANIMATION_DURATION=1000;

publicstaticfinalintANIMATION_REFRESH=50;



publicAnimatedJList(){



super();

addListSelectionListener(this);

setCellRenderer(newAnimatedCellRenderer());

}



publicvoidvalueChanged(ListSelectionEventlse){

if(!lse.getValueIsAdjusting()){

HashSetselections=newHashSet();

for(inti=0;i
if(getSelectionModel().isSelectedIndex(i))

selections.add(newInteger(i));

}

CellAnimatoranimator=newCellAnimator(selection

animator.start();

}

}

publicstaticvoidmain(String[]args){

JListlist=newAnimatedJList();

DefaultListModeldefModel=newDefaultListModel();

list.setModel(defModel);

String[]listItems={

"Chris","Joshua","Daniel","Michael",

"Don","Kimi","Kelly","Keagan"

};

Iteratorit=Arrays.asList(listItems).iterator();

while(it.hasNext())

defModel.addElement(it.next());

//showlist

JScrollPanescroller=

newJScrollPane(list,

ScrollPaneConstants.VERTICAL_SCROLLBAR

ScrollPaneConstants.HORIZONTAL_SCROLLB

JFrameframe=newJFrame("CheckboxJList");

frame.getContentPane().add(scroller);

frame.pack();

frame.setVisible(true);

}



classCellAnimatorextendsThread{

Object[]selections;

longstartTime;

longstopTime;

publicCellAnimator(Object[]s){

selections=s;

}

publicvoidrun(){

startTime=System.currentTimeMillis();

stopTime=startTime+ANIMATION_DURATION;

while(System.currentTimeMillis()
colorizeSelections();

repaint();

try{Thread.sleep(ANIMATION_REFRESH);}

catch(InterruptedExceptionie){}

}

//onemore,at100%selectedcolor

colorizeSelections();

repaint();

}

//colorizeSelections()listingbelow

//AnimatedCellRendererlistingbelow

}



Likeseveralprevioushacks,thishackstartswithsomestatic

codetogettheplatformcolorsforselectedandunselected

foregroundandbackgroundcolors.Butthistime,italsosaves

themoffintoarraysoftheirred,green,andbluecomponents.

ThecomponentsetsupaListSelectionListener,whichfiresoffa

CellAnimatoreverytimeitgetsthelastofaseriesof

ListSelectionEvents.TheCellAnimatorisathreadthatrunsfora



shorttimeonly(definedbytheclassvariableANIMATION_DURATION),

repeatedlycallingcolorizeSelections()andthensleepingbriefly.

colorizeSelections(),showninExample2-19,calculatesafloatto



expresshowmuchoftheanimationdurationhaselapsed.It

thenappliesthisasaproportiontothedistancebetweenthe

startandendvaluesforeachofthered,green,andblue

components.Forexample,iftheunselectedbackgroundcoloris

white(255,255,255),andtheselectedcolorispureblue(0,0,

255),thenhalfwaythroughtheanimationthecolorshouldbe

(127,127,255),where127ishalfwaybetweenthestartand

endvaluesoftheredandgreencomponents,andbluedoesn't

change.



Example2-19.Determininganimationcolorfor

selectedcells



publicvoidcolorizeSelections(){

//calculate%completionrelativetostart/stoptimes

floatelapsed=(float)(System.currentTimeMillis()-start

floatcompleteness=Math.min((elapsed/ANIMATION_DURATION)

//calculatescaledcolor

floatcolorizedForeComps[]=newfloat[3];

floatcolorizedBackComps[]=newfloat[3];

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

colorizedForeComps[i]=

foregroundComps[i]+

(completeness*

(foregroundSelectionComps[i]-foregroundComps[i]))

colorizedBackComps[i]=

backgroundComps[i]+

(completeness*

(backgroundSelectionComps[i]-backgroundComps[i]))

}

colorizedSelectionForeground=

newColor(colorizedForeComps[0],



colorizedForeComps[1],

colorizedForeComps[2]);

colorizedSelectionBackground=

newColor(colorizedBackComps[0],

colorizedBackComps[1],

colorizedBackComps[2]);

}



ThecellrendererinExample2-20isverysimple:itjustlooksto

seeifthecellit'srenderingisselected;ifso,itsetsits

foregroundandbackgroundtothecolorizedvalues.Italsosets

thecelltobeopaque,meaningthattherendererwantsthe

responsibilityofdrawingallthepixels,whichisnecessaryto

makethebackgroundcolorfillthecell.Inamorecomplexcell

layout,youmightneedtoapplytheforegroundandbackground

colorstoallthecell'schildrenandmakethemopaque,too.



Example2-20.Renderingtheanimatedlistcells



classAnimatedCellRendererextendsDefaultListCellRenderer{

publicComponentgetListCellRendererComponent(JListlist,

Objectvalue,

intindex,

booleanisSel

booleanhasFo

ComponentreturnMe=

super.getListCellRendererComponent(list,value,ind

isSelected,hasF

if(isSelected){

returnMe.setForeground(colorizedSelectionForeground

returnMe.setBackground(colorizedSelectionBackground

/*thismightbenecessaryifyouhavemore

elaboratecells



if(returnMeinstanceofContainer){

Component[]children=

((Container)returnMe).getComponents();

System.out.println(children.length+"children

for(inti=0;

(children!=null)&&(i
children[i].setForeground(colorizedSelect

children[i].setBackground(colorizedSelectionBac

}

}

*/

if(returnMeinstanceofJComponent)

((JComponent)returnMe).setOpaque(true);

}

returnreturnMe;

}

}



Whenyourunthecode,clickingonacellmakesitbrieflyfade

intotheselectioncolor,asseeninFigure2-11.

Onepotentialimprovement:ifyourlistallowsmultiple

selections,thenalltheselectedcellswillanimate,anditwould

makemoresensetoanimatejusttheonethattheuserhas

clickedon.Youcoulddothisbyfiguringout(bycaching

previousselections[Hack#15])whichitemisthenew

selection,andsettingaflagsothatthecellrendererapplies

onlythecolorizedforegroundandbackgroundcolorstothat

cell.



Figure2-11.Fadinginacellselection



Hack19.TurnMethodsintoListRenderers



Byusingalittlebitofreflection,youcanmakeageneric

ListCellRendererthatcanrenderdatausinganymethodat

runtime.

JLists,likeJTableandJTRee,useadecoratorpatterntocustomize



howtheylook.Thissystemofcellrenderersworkswell,butit

canrequireyoutobuildauniquerendererclassforeachtypeof

objectyouwanttoputintoyourlists.Often,allyoureallywant

todoiscallaparticularmethodontheobjectsinyourlist,but

writingacompleteclasstojustcallonemethodisalotofwork

forsuchasmalltask.Thishackshowsyouhowtousereflection

tocreateagenericcellrendererthatcanbereusedonany

objectwithoutsubclassing.



2.8.1.BuildingaGenericRenderer

ThedefaultJListcellrendererwilljustcalltoString()onthe

objectsinthelistanddrawtheresultingstringtothescreen.

Thisisfineforsimpleuseswhereyoureallyarejustlookingat

alistofstringsorobjectswithappropriatetoString()methods.

Morecomplicatedapplicationsandtheyallbecomemore

complicatedeventuallyrequiremorecomplicatedobjects,and

thoseobjectsmightnothaveaconvenientorusefultoString()

method.Eventually,youhavetowriteacustomrendererforthe

particularobjectyouwishtostore.Butthereisanotherway:

reflection.

Reflectionletsyouprogrammaticallydiscoverandaccess

methodsandfieldsinajavaclassatruntime.Forthishack,you

willusereflectiontocallanarbitrarymethod.Thiswillallowthe



programmerusingyourgenericrenderertospecifyamethod

usingastring.Thismethodwillbeusedtorenderthe

component.Becauseyouwillbeusingreflection,youdon'tneed

toknowthekindofobjectsinthelist.Aslongasamethodwith

therequestednameexists,youcancallitandgetavalueout.

ThiswillworkevenifsomeoftheobjectsintheJListhave

differenttypes.Butlet'snotgetaheadofourselves.First,you

needabasiccellrenderer,asseeninExample2-21.



Example2-21.Abasiccellrenderer



publicclassGenericListCellRendererextendsDefaultListCellRen

protectedStringmethod;

publicGenericListCellRenderer(Stringmethod){

super();

this.method=method;

}



publicComponentgetListCellRendererComponent(JListlist,O

intindex,booleanisSelected,booleancellHasFocus){



JLabellabel=(JLabel)super.getListCellRendererCompone

list,value,index,isSelected,cellHasFocus);

label.setText("mytext");

returnlabel;

}



Example2-21declaresasubclassofthe

DefaultListCellRendererthestandardimplementationofa

ListCellRenderer.TheGenericListCellRendererclasstakesamethod

stringinitsconstructor.Thisstringisthenameofthemethod

tocallonthelistvalueobjects.

AllListCellRenderershaveagetListCellRendererComponent()method,



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

Hack 18. Animate Your JList Selections

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

×