Tải bản đầy đủ - 0 (trang)
Hack 44. Turn Dialogs into Frame-Anchored Sheets

Hack 44. Turn Dialogs into Frame-Anchored Sheets

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

Asheetdoesn'thaveaclosebox

Dialogcloseboxesareoneofthemosthatefulandstupid

conceptsinWindowsanditsmanyLinuximitators.What

doesthecloseboxmean?Cancel?Thedefaultoption?What

doesitmeanwhenthedialoghasmultipleoptionsofequal

plausibilityandthusnodefault?Perhapstheworstthing

aboutthecloseboxwasbackintheAWTerawhenJava

developerstoolazytoaddandwire-upanOKbuttontotheir

dialogsjustfigureduserscoulddismissthedialogwiththe

closebox.MacOS8and9dialogsdidn'thavecloseboxes,

sowhenaJavaapplicationbroughtupsuchadialog,the

applicationblockeditselfforever.Duh.Sheetsmeanhaving

toclickoneoftheprovidedbuttons,sotheuser'schoices

areunambiguous.



Asheetisusedtoblockonewindow

Thisisanobvioussideeffectofbeingvisuallytiedtoa

singlewindow,butthat'sprobablythemostcommoncase.

Asasideeffect,thisgivesgreaterprominencetodialogs

thatblockallwindowsforasingleapplication("Areyou

sureyouwanttoQuitandloseallunsavedchangesinall

documents?")anddialogsthatblockallapplications("Are

yousureyouwanttoShutDown?").



So,ifyouagreethatit'sanexcellentGUIconcept,thenext

questionis"howdoImimicsheetsinSwing?"



6.5.2.UsetheGlassPane

OnewaytoimitatetheMacOSXsheetistousetheglass

panealayerintheLayeredPaneusedbyallRootPaneContainers,

includingJApplets,JFrames,JInternalFrames,JWindows,andJDialogs.In

termsofz-ordertheorderingoflayerson"top"ofoneanother

fromtheuser'sperspectivetheglasspaneis"above"the

contentpaneandthemenubarintheLayeredPane.Itisusually

emptyandunfilled.Oneofthemoretypicalusesfortheglass

paneistoaddaMouseListenerandMouseMotionListenertodeny

eventstothecontentpaneandtherebyblockit.

Toimitatethesheetwiththeglasspane,theideaistotakethe

contentsyou'dusuallyputintoaJDialogandplacetheminstead

intotheglasspane.Thiswillputthemintheframe,aboveand

infrontoftheframe'scontents.Topositionyourcontentsatthe

topcenteroftheglasspane,youcanuseaGridBagLayoutthat

givesthesheetaNORTHanchor,andthenadda"glue"component

inthenextrowthattakesupasmuchverticalspaceas

possible,pushingthesheettothetopofthepane.

Example6-7showsasubclassofJFramethatexposesa

showJDialogAsSheet()method,whichgrabstheJDialog'scontent

paneJComponentandinsertsitintotheglasspaneasthesheet.



Example6-7.AddingasheetinaJFrame'sglass

pane









importjavax.swing.*;

importjavax.swing.border.*;

importjava.awt.*;







importjava.awt.event.*;







publicclassSheetableJFrameextendsJFrame{









JComponentsheet;

JPanelglass;















































}



publicSheetableJFrame(Stringname){



super(name);



glass=(JPanel)getGlassPane();

}

publicJComponentshowJDialogAsSheet(JDialogdialog){



sheet=(JComponent)dialog.getContentPane();



sheet.setBackground(Color.red);



glass.setLayout(newGridBagLayout());



sheet.setBorder(newLineBorder(Color.black,1)



glass.removeAll();



GridBagConstraintsgbc=newGridBagConstraints



gbc.anchor=GridBagConstraints.NORTH;



glass.add(sheet,gbc);



gbc.gridy=1;



gbc.weighty=Integer.MAX_VALUE;



glass.add(Box.createGlue(),gbc);



glass.setVisible(true);



returnsheet;

}

publicvoidhideSheet(){



glass.setVisible(false);

}



Simpleenough,isn'tit?Totestthiscomponent,justcreatea

JFrameandaJDialogtoinsertintotheframe.TheSheetTestclassin

Example6-8,whichexercisestheSheetableJFrame,fillstheframe

withinterestingcontentbymakingaJLabelfromanimagefile.



ItthencreatesaJDialogtheeasywaybymakingJOptionPanedoit.



Ifyou'reusedtocallingJOptionPane'svariousshowXXXDialog()methods,

youmightbeunfamiliarwiththeideaofconstructingandholdingonto

aJOptionPaneandcreatingdialogsfromit.Thisapproachisn'tcommon,

butit'susefulifyouwanttoholdontotheJDialog,maybeforreuse

(e.g.,youhavememoryorperformanceconcernswithrepeatedly

creatinganddisposingofdialogs)orbecauseyoudon'twanttoblock

assoonasyoushowit.Inthecaseofthisdemo,theadvantageisto

getadialogtoplaywith,withouthavingtolayoutandwireup

everythingyourself.



Example6-8.TestingtheSheetableJFrame











importjavax.swing.*;

importjava.awt.*;

importjava.awt.event.*;

importjava.beans.*;









publicclassSheetTestextendsObject



implementsPropertyChangeListener{















JOptionPaneoptionPane;

SheetableJFrameframe;



















publicstaticvoidmain(String[]args){



newSheetTest();

}



























publicSheetTest(){



frame=newSheetableJFrame("Sheettes



//putanimageintheframe'scontent



ImageIconicon=newImageIcon("keagy

JLabellabel=newJLabel(icon);





































































frame.getContentPane().add(label);



//buildJOptionPanedialogandholdon



optionPane=newJOptionPane("Doyouw











JOption











JOption

frame.pack();



frame.setVisible(true);



optionPane.addPropertyChangeListener(t



//pauseforeffect,thenshowtheshee



try{Thread.sleep(1000);}



catch(InterruptedExceptionie){}



JDialogdialog=





optionPane.createDialog(frame,



frame.showJDialogAsSheet(dialog);

}



































}



publicvoidpropertyChange(PropertyChangeEvent

if(pce.getPropertyName().equals(JOptionPa





System.out.println("Selectedo









pce.getNewValue





frame.hideSheet();

}

}



Theotherthingthat'sinterestingaboutholdingontoa

JOptionPaneisthatitnotthedialogiswhatfireseventswhenthe

userclicksoneofthebuttons.Thesearefiredas

PropertyChangeEventswiththepropertynamevalue,whichyou

shouldrefertoasJOptionPane.VALUE_PROPERTY.Inthiscase,what

youwanttolistenforisanychangeinthevalue,which

indicatesthatsomethinghasbeenclickedandmeansit'stime

tohidethesheet.

WhenyourunSheetTest,theimagecomesupinaSheetableJFrame



and,afteraone-secondpauseforeffect,thesheetappearsat

topcenter,asseeninFigure6-8.



Figure6-8.JDialogshownasa"sheet"inthe

glasspane



Whenyouclickeitheroftheoptions,theeventlistenerhides

theglasspane,whichmakesthesheetdisappear.

Thisisaprettysimplecaseofusingtheglasspaneinfact,the

testisafewlineslongerthantheimplementationofthesheet.

Theonlythingthat'smissingisthecharminganimationofthe

sheetslidingin[Hack#45]….



Hack45.AnimatingaSheetDialog



Byanimatingthesheet'sappearanceanddisappearance,

yougivetheuserabettercluethathisattentionis

required.Plus,itlookscool.

AnotherreallygreatthingaboutthesheetfunctionalityinMac

OSXisthatitdoesn'tjustsuddenlyappearitslidesoutfromthe

titlebar,asifunrollingfromunderthebar.Thisanimation

furtherreinforcestherelationshipbetweenthesheetandthe

windowbecausetheshortanimationcatchesyoureyeand

alertsyoutothefactthatsomethingaboutthewindowhas

changeddramaticallynamely,thatitisnowblockedbythesheet

dialog.



6.6.1.AnimatetheSheet

Youalreadyknowhowtogetcomponentsintotheglasspane

[Hack#44],soyoushouldexpectthatthekeytosheet

animationistoperformtheanimationintheglasspane,ontop

oftheothercomponents.Ofcourse,youmighthavealso

guessedthatthetrickypartofthisisgoingtobeshowing

successivelylargerpartsofthedialogastheanimation

progresses.

Tomakethiswork,youfirstneedtocreateacustom

componentfortheanimatingversionofthesheet,separate

fromthesheetitself.Then,oneachpassoftheanimationcycle,

changethesizeofthecustomcomponent.Itwillalwayshave

thesamewidththewidthoftherealsheetbutitsheightwillbe

somepercentageoftheheightoftheoriginal,basedonhow

muchoftheanimationtimehaselapsed.Thisapproachcan



workforbothdirectionsoftheanimation:whenthesheetis

incoming,theheightwillgetprogressivelygreater;whenthe

sheetisgoingout,theheightwilldecrease.

Toactuallydrawtheanimatingsheetduringtheanimation,you

canuseBufferedImage.getSubimage()tograbaportionofthereal

sheet,andthendrawthatintoitsownGraphicsviapaint()

callbacks.Whentheanimationcompletes,theanimatingsheet

isremovedfromtheglasspaneandtherealsheetisadded.



Aninterestingsideeffectofthisisthattheusercan'tclickthebuttons

asthesheetappearsorretractsbecauseit'sjustanimageofthesheet,

notthesheetitself.Ofcourse,theanimationissoshort(onesecondin

Example6-9,andMacOSX'sactuallycomesoutfasterthanthat),that

it'sunlikelyausercouldtrackthemovingsheetwithhermouseand

successfullyclickabuttonanyway.



Oneadvantageofusingacustomcomponentlikethisisthat

thekindsofthingsthatworkedforbasicsheets[Hack#44]all

workhereaswell.Forexample,youcoulduseasimple

GridBagLayout(wow,there'saphraseyoudon'thearoften)toget

thesheetcenteredatoptheglasspane.Asthesheetisareal

component,itshouldalsohandleresizingappropriately.

Settingasidethedetailsofthecustomcomponentneededto

createtheanimatedversionofthesheet,Example6-9shows

thereworkedversionofthesheetframe,whichI'vecalled

AniSheetableJFrame.



Example6-9.JFrameforanimatingsheet

appearanceanddisappearance





importjavax.swing.*;



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

Hack 44. Turn Dialogs into Frame-Anchored Sheets

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

×