Tải bản đầy đủ - 0 (trang)
Hack 29. Display Shortcuts in the JFileChooser

Hack 29. Display Shortcuts in the JFileChooser

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

LikeeverySwingcomponent,thelookoftheJFileChooseris

controlledbytheinstalledLookandFeel(L&F).However,the

JFileChooseralsousesacustomclasssimilartoatablecell

rendererfordrawingtheactualfilesandfolders.Thatclass,

FileView,isthebestplacetostarthackingtheJFileChooser's

display.

TheFileViewcontainsfivemethodsthatdeterminethenames,

icons,andotherattributesthatareactuallydisplayedina

JFileChooser.Byoverridingthesemethods,youcanchangethe

lookortextofanyfile.Todrawshortcutsaslinkedfolders,you

justneedtooverridethegetIcon()andisTRaversable()methods.

getIcon()returnstheicontousewhendrawingthefile.



Figure4-3.StandardWindowsfilechooser



isTraversable()tellsthefilechooserifagivenfileisadirectory



typeofobject,meaningtheusercanclickandopenittolist

newfiles.Thesetwomethodswilltransformashortcut.lnkfile

intoashortcutdirectorywiththerighticon.



Forthesakeofbrevity,thisisaWindows-specifichack.Youshouldbe

abletomodifythishackeasilytoworkwithsym-linksonUnixand

Linux,aswellasMacOSX.Considerithomework!



Togetstarted,createtheShortcutFileViewclass.Thisextends

FileView,overridingtheisTraversable()methodtoreturntrueif

theisDirLink()methodindicatesthatthefileisindeedalink

(determinedbylookingforthe.lnkextension).Ifthefileisnot

alink,isDirLink()willreturnnull.



NoticethatisTraversable()returnsaBooleaninsteadofaboolean.This

allowsanulltobereturnedinadditiontothetrue/falsevaluesthat

booleanwouldallow.



AnymethodofFileViewsubclassesthatreturnnullwillcausethe

filechoosertodefertoitsdefaultfileview,insteadofusingthe

customview:





classShortcutFileViewextendsFileView{





























publicbooleanisDirLink(Filef){



if(f.getName().toLowerCase().endsWith(".lnk"))





returntrue;



}



returnfalse;

}

publicBooleanisTraversable(Filef){



if(isDirLink(f)){





returnnewBoolean(true);



}



returnnull;





}



}



BelowisasampleprogramtotesttheShortcutFileView.Itcreates

anewfilechooser,setsthefileviewtoanewShortcutFileView,

andthenopensthedialog.Itisimportanttosettheviewbefore

theshowOpenDialog()becausefilechooserscannotbechanged

aftertheyhavebeenshownonscreen:

















publicclassDisplayShortcutTest{



publicstaticvoidmain(String[]args)throwsE





JFileChooserchooser=newJFileChooser





chooser.setFileView(newShortcutFileVie





chooser.showOpenDialog(null);



}

}



Thisprogramchangesthelookofshortcutstolooklikefolders

andbeclickable,buttheystilldon'thavethelinkicon.Thiswill

requireabitmorework.Thesecondmethodtooverrideinthe

fileviewisthegetIcon()method.Theplanistogetastandard

foldericonthendrawitontoanewiconwiththeoverlaidlink

graphic.ThispartwillcreateanewJFileChooserandgeta

referencetoitsnormalfileview.ThefollowingFileChooserUIcode

forcesthefilechoosertoinitializeitsLookandFeelsubsystem,

ensuringthattheFileViewwillbevalid:







publicIcongetIcon(Filef){



if(isDirLink(f)){



























JFileChooserchooser=newJFileChooser

FileChooserUIfcui=(FileChooserUI)UI

fcui.installUI(chooser);















FileViewdef=fcui.getFileView(chooser



Onceyouhavethefileview,youneedtopulloutafoldericon.

Youcandothisbyaskingfortheiconofaknownfolder,inthis

caseC:\windows:













//getthestandardiconforafolder

Filetmp=newFile("C:\\windows");

Iconfolder=def.getIcon(tmp);

intw=folder.getIconWidth();

inth=folder.getIconHeight();



Onceyouhavetheicon,youcanbuildanewimagetodrawit

on,andthenoverlaythelinkgraphic:





//createabufferedimagethesamesizeastheicon



Imageimg=newBufferedImage(w,h,









BufferedImage.TYPE_4BYTE_ABGR);

Graphicsg=img.getGraphics();





//drawthenormalicon



folder.paintIcon(chooser,g,0,0);









//drawtheshortcutimageontopoftheicon

Imageshortcut=newImageIcon("shortcut.png").getImage

g.drawImage(shortcut,0,0,null);





//cleanupandreturn



g.dispose();



returnnewImageIcon(img);

}

returnsuper.getIcon(f);

}



That'sit.Withthenewiconcreated,yourfilechoosershould

looklikeFigure4-4.



Figure4-4.JFileChoosershowingashortcut



Hack30.RealWindowsShortcutSupport



SupportWindowsshortcutsbyactuallyopeningand

parsingfileswiththeunder-documentedLNKformat.

It'sonethingtoproperlydisplayWindowsshortcuts[Hack

#29]bylookingforthe.lnkextensionandchangingthedefault

icontolooklikealink.Butthere'saglaringflaw:whenyou

clickontheshortcutitdoesn'tactuallylinkanywhere!Thishack

willmaketheshortcutsreallyworkbyhackingintothe

undocumentedshortcutfilesthemselves.

Sincelinksarenotsupportednativelybythefilesystem,

Windowsfakesitbystoringtheshortcutmetadata(path,icon,

andotherinformation)ina.lnkfile.Whenyouclickonthe

shortcut,thewindowsfilemanagerreadstheLNKfile,extracts

thetargetfile/directorypath,andthenopensanewwindowat

thereallocation.YourJavaprogramcandotheexactsame

thingusingacustomFileSystemView.Theonlytrickypartis

actuallyparsingtheLNKfiles.

MicrosofthasneverdocumentedtheLNKfileformat,preferring

nativeWindowsdeveloperstousesystemAPIsforall

manipulation.CreativehackersontheWebhavereverse

engineeredmostoftheformat,whichfortunatelyincludesthe

partsyouneedtoextracttargetfilepaths.



JesseHagerhascompiledagreatPDFdescribingtheformatindetail.I

usedthatdocumenttowritethecodeinthishack.Youcanreadthefull

documentathttp://www.i2slab.com/Papers/The_Windows_Shortcut_File_Format.pdf.



TheLNKfilesarebinarydatabrokenupintoaheaderfollowed

byafewoptionalblocksofdata.Theformatprovidesoffsets

thatmakeparsingiteasy.Thefollowingcodeisthebeginning

ofaLNKparser:



































publicclassLnkParser{



publicLnkParser(Filef)throwsException{





parse(f);



}



publicvoidparse(Filef)throwsException{





//readtheentirefileintoabytebuf





FileInputStreamfin=newFileInputStre





ByteArrayOutputStreambout=newByteAr





byte[]buff=newbyte[256];





while(true){







intn=fin.read(buff);







if(n==-1){break;}







bout.write(buff,0,n);





}





fin.close();





byte[]link=bout.toByteArray();



Theclassdefinesoneimportantmethod,parse(),whichaccepts

aFileobjectrepresentingtheLNKfile.Thefirststepistoload

theentirefileintoabytebuffer.



Ihaveseensomeversionsofthiscodeuseamorestream-oriented

approachwithloopsthatreadbytebybyte.SinceLNKfilesarealways

prettysmall(usuallyunder5k),Ifelttheextramemorywasworthitto

allowcleanercodeusingindexoffsets.



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

Hack 29. Display Shortcuts in the JFileChooser

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

×