a swing architecture overview

12
24/12/2014 A Swing Architecture Overview http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 1/12 A Swing Architecture Overview The Inside Story on JFC Component Design By Amy Fowler Most Swing developers know by now that Swing components have a separable modelandview design. And many Swing users have run across articles saying that Swing is based on something called a "modified MVC (modelviewcontroller) architecture." But accurate explanations of how Swing components are designed, and how their parts all fit together, have been hard to come by until now. The silence ends with the publication of this article, a major white paper on Swing component design. It provides a comprehensive technical overview of Swing's modified MVC structure and demystifies many other facets of Swing component architecture as well. This document presents a technical overview of the Swing component architecture. In particular, it covers the following areas in detail: Design goals Roots in MVC Separable model architecture Pluggable lookandfeel architecture Design Goals The overall goal for the Swing project was: To build a set of extensible GUI components to enable developers to more rapidly develop powerful Java front ends for commercial applications. To this end, the Swing team established a set of design goals early in the project that drove the resulting architecture . These guidelines mandated that Swing would: Be implemented entirely in Java to promote crossplatform consistency and easier maintenance. Provide a single API capable of supporting multiple lookandfeels so that developers and endusers would not be locked into a single lookand feel. Enable the power of modeldriven programming without requiring it in the highestlevel API. Adhere to JavaBeans design principles to ensure that components behave well in IDEs and builder tools. Provide compatibility with AWT APIs where there is overlapping, to leverage the AWT knowledge base and ease porting. Roots in MVC Swing architecture is rooted in the modelviewcontroller ( MVC) design that dates back to SmallTalk . MVC architecture calls for a visual application to be broken up into three separate parts: A model that represents the data for the application. The view that is the visual representation of that data. A controller that takes user input on the view and translates that to changes in the model. Early on, MVC was a logical choice for Swing because it provided a basis for meeting the first three of our design goals within the bounds of the latter two. The first Swing prototype followed a traditional MVC separation in which each component had a separate model object and delegated its lookand feel implementation to separate view and controller objects. The delegate We quickly discovered that this split didn't work well in practical terms because the view and controller parts of a component required a tight coupling (for example, it was very difficult to write a generic controller that didn't know specifics about the view). So we collapsed these two entities into a single UI (userinterface) object, as shown in this diagram: (The UI delegate object shown in this picture is sometimes called a delegate object, or UI delegate. The UI delegate used in Swing is described in more detail in the Pluggable lookandfeel section of this article, under the subheading " The UI delegate ".) As the diagram illustrates, Swing architecture is loosely based but not strictly based on the traditional MVC design. In the world of Swing, this new quasiMVC design is sometimes referred to a separable model architecture. Swing's separable model design treats the model part of a component as a separate element, just as the MVC design does. But Swing collapses the view and controller parts of each component into a single UI (userinterface) object. To MVC or not to MVC? One noteworthy point is that as an application developer, you should think of a component's view/controller responsibilities as being handled by the generic component class (such as. JButton, JTree, and so on). The component class then delegates the lookandfeelspecific aspects of those responsibilities to the UI object that is provided by the currently installed lookandfeel. For example, the code that implements doublebuffered painting is in Swing's JComponent class (the "mother" of most Swing component classes), while the code that renders a JButton's label is in the button's UI delegate class. The preceding diagram illustrates this subtle (and often confusing) point: So Swing does have a strong MVC lineage. But it's also important to reiterate that our MVC architecture serves two distinct purposes: First, separating the model definition from a component facilitates modeldriven programming in Swing. Second, the ability to delegate some of a component's view/controller responsibilities to separate lookandfeel objects provides the basis for Swing's pluggable lookandfeel architecture. Although these two concepts are linked by the MVC design, they may be treated somewhat orthogonally from the developer's perspective. The remainder of this document will cover each of these mechanisms in greater detail. Oracle Technology Network Java Products Solutions Downloads Store Support Training Partners About OTN Sign In/Register Help Country Communities I am a... I want to... Search

Upload: ricki0912

Post on 17-Sep-2015

225 views

Category:

Documents


3 download

DESCRIPTION

h

TRANSCRIPT

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 1/12

    ASwingArchitectureOverview

    TheInsideStoryonJFCComponentDesignByAmyFowler

    MostSwingdevelopersknowbynowthatSwingcomponentshaveaseparablemodelandviewdesign.AndmanySwingusershaverunacrossarticlessayingthatSwingisbasedonsomethingcalleda"modifiedMVC(modelviewcontroller)architecture."

    ButaccurateexplanationsofhowSwingcomponentsaredesigned,andhowtheirpartsallfittogether,havebeenhardtocomebyuntilnow.

    Thesilenceendswiththepublicationofthisarticle,amajorwhitepaperonSwingcomponentdesign.ItprovidesacomprehensivetechnicaloverviewofSwing'smodifiedMVCstructureanddemystifiesmanyotherfacetsofSwingcomponentarchitectureaswell.

    ThisdocumentpresentsatechnicaloverviewoftheSwingcomponentarchitecture.Inparticular,itcoversthefollowingareasindetail:

    DesigngoalsRootsinMVCSeparablemodelarchitecturePluggablelookandfeelarchitecture

    DesignGoalsTheoverallgoalfortheSwingprojectwas:

    TobuildasetofextensibleGUIcomponentstoenabledeveloperstomorerapidlydeveloppowerfulJavafrontendsforcommercialapplications.

    Tothisend,theSwingteamestablishedasetofdesigngoalsearlyintheprojectthatdrovetheresultingarchitecture.TheseguidelinesmandatedthatSwingwould:

    BeimplementedentirelyinJavatopromotecrossplatformconsistencyandeasiermaintenance.ProvideasingleAPIcapableofsupportingmultiplelookandfeelssothatdevelopersandenduserswouldnotbelockedintoasinglelookandfeel.EnablethepowerofmodeldrivenprogrammingwithoutrequiringitinthehighestlevelAPI.AdheretoJavaBeansdesignprinciplestoensurethatcomponentsbehavewellinIDEsandbuildertools.ProvidecompatibilitywithAWTAPIswherethereisoverlapping,toleveragetheAWTknowledgebaseandeaseporting.

    RootsinMVCSwingarchitectureisrootedinthemodelviewcontroller(MVC)designthatdatesbacktoSmallTalk.MVCarchitecturecallsforavisualapplicationtobebrokenupintothreeseparateparts:

    Amodelthatrepresentsthedatafortheapplication.Theviewthatisthevisualrepresentationofthatdata.Acontrollerthattakesuserinputontheviewandtranslatesthattochangesinthemodel.Earlyon,MVCwasalogicalchoiceforSwingbecauseitprovidedabasisformeetingthefirstthreeofourdesigngoalswithintheboundsofthelattertwo.

    ThefirstSwingprototypefollowedatraditionalMVCseparationinwhicheachcomponenthadaseparatemodelobjectanddelegateditslookandfeelimplementationtoseparateviewandcontrollerobjects.

    Thedelegate

    Wequicklydiscoveredthatthissplitdidn'tworkwellinpracticaltermsbecausetheviewandcontrollerpartsofacomponentrequiredatightcoupling(forexample,itwasverydifficulttowriteagenericcontrollerthatdidn'tknowspecificsabouttheview).SowecollapsedthesetwoentitiesintoasingleUI(userinterface)object,asshowninthisdiagram:

    (TheUIdelegateobjectshowninthispictureissometimescalledadelegateobject,orUIdelegate.TheUIdelegateusedinSwingisdescribedinmoredetailinthePluggablelookandfeelsectionofthisarticle,underthesubheading"TheUIdelegate".)

    Asthediagramillustrates,SwingarchitectureislooselybasedbutnotstrictlybasedonthetraditionalMVCdesign.IntheworldofSwing,thisnewquasiMVCdesignissometimesreferredtoaseparablemodelarchitecture.

    Swing'sseparablemodeldesigntreatsthemodelpartofacomponentasaseparateelement,justastheMVCdesigndoes.ButSwingcollapsestheviewandcontrollerpartsofeachcomponentintoasingleUI(userinterface)object.

    ToMVCornottoMVC?

    Onenoteworthypointisthatasanapplicationdeveloper,youshouldthinkofacomponent'sview/controllerresponsibilitiesasbeinghandledbythegenericcomponentclass(suchas.JButton,JTree,andsoon).ThecomponentclassthendelegatesthelookandfeelspecificaspectsofthoseresponsibilitiestotheUIobjectthatisprovidedbythecurrentlyinstalledlookandfeel.

    Forexample,thecodethatimplementsdoublebufferedpaintingisinSwing'sJComponentclass(the"mother"ofmostSwingcomponentclasses),whilethecodethatrendersaJButton'slabelisinthebutton'sUIdelegateclass.Theprecedingdiagramillustratesthissubtle(andoftenconfusing)point:

    SoSwingdoeshaveastrongMVClineage.Butit'salsoimportanttoreiteratethatourMVCarchitectureservestwodistinctpurposes:

    First,separatingthemodeldefinitionfromacomponentfacilitatesmodeldrivenprogramminginSwing.Second,theabilitytodelegatesomeofacomponent'sview/controllerresponsibilitiestoseparatelookandfeelobjectsprovidesthebasisforSwing'spluggablelookandfeelarchitecture.AlthoughthesetwoconceptsarelinkedbytheMVCdesign,theymaybetreatedsomewhatorthogonallyfromthedeveloper'sperspective.Theremainderofthisdocumentwillcovereachofthesemechanismsingreaterdetail.

    OracleTechnologyNetwork Java

    Products Solutions Downloads Store Support Training Partners About OTN

    SignIn/Register Help Country Communities Iama... Iwantto... Search

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 2/12

    SeparablemodelarchitectureItisgenerallyconsideredgoodpracticetocenterthearchitectureofanapplicationarounditsdataratherthanarounditsuserinterface.Tosupportthisparadigm,Swingdefinesaseparatemodelinterfaceforeachcomponentthathasalogicaldataorvalueabstraction.ThisseparationprovidesprogramswiththeoptionofpluggingintheirownmodelimplementationsforSwingcomponents.

    ThefollowingtableshowsthecomponenttomodelmappingforSwing.

    Component ModelInterface ModelTypeJButton ButtonModel GUI

    JToggleButton ButtonModel GUI/data

    JCheckBox ButtonModel GUI/data

    JRadioButton ButtonModel GUI/data

    JMenu ButtonModel GUI

    JMenuItem ButtonModel GUI

    JCheckBoxMenuItem ButtonModel GUI/data

    JRadioButtonMenuItem ButtonModel GUI/data

    JComboBox ComboBoxModel data

    JProgressBar BoundedRangeModel GUI/data

    JScrollBar BoundedRangeModel GUI/data

    JSlider BoundedRangeModel GUI/data

    JTabbedPane SingleSelectionModel GUI

    JList ListModel data

    JList ListSelectionModel GUI

    JTable TableModel data

    JTable TableColumnModel GUI

    JTree TreeModel data

    JTree TreeSelectionModel GUI

    JEditorPane Document data

    JTextPane Document data

    JTextArea Document data

    JTextField Document data

    JPasswordField Document data

    GUIstatevs.applicationdatamodelsThemodelsprovidedbySwingfallintotwogeneralcategories:GUIstatemodelsandapplicationdatamodels.

    GUIstatemodels

    GUIstatemodelsareinterfacesthatdefinethevisualstatusofaGUIcontrol,suchaswhetherabuttonispressedorarmed,orwhichitemsareselectedinalist.GUIstatemodelstypicallyarerelevantonlyinthecontextofagraphicaluserinterface(GUI).WhileitisoftenusefultodevelopprogramsusingGUIstatemodelseparationparticularlyifmultipleGUIcontrolsarelinkedtoacommonstate(suchasinasharedwhiteboardprogram),orifmanipulatingonecontrolautomaticallychangesthevalueofanothertheuseofGUIstatemodelsisnotrequiredbySwing.ItispossibletomanipulatethestateofaGUIcontrolthroughtoplevelmethodsonthecomponent,withoutanydirectinteractionwiththemodelatall.Intheprecedingtable,GUIstatemodelsinSwingarehighlightedinblue.

    Applicationdatamodels

    Anapplicationdatamodelisaninterfacethatrepresentssomequantifiabledatathathasmeaningprimarilyinthecontextoftheapplication,suchasthevalueofacellinatableortheitemsdisplayedinalist.ThesedatamodelsprovideaverypowerfulprogrammingparadigmforSwingprogramsthatneedacleanseparationbetweentheirapplicationdata/logicandtheirGUI.FortrulydatacentricSwingcomponents,suchasJTreeandJTable,interactionwiththedatamodelisstronglyrecommended.Applicationdatamodelsarehighlightedinredinthetablepresentedatthebeginningofthissection.

    Ofcoursewithsomecomponents,themodelcategorizationfallssomewhereinbetweenGUIstatemodelsandapplicationdatamodels,dependingonthecontextinwhichthemodelisused.ThisisthecasewiththeBoundedRangeModelonJSliderorJProgressBar.Thesemodelsarehighlightedinpurpleintheprecedingtable.

    Swing'sseparablemodelAPImakesnospecificdistinctionsbetweenGUIstatemodelsandapplicationdatamodelshowever,wehaveclarifiedthisdifferenceheretogivedevelopersabetterunderstandingofwhenandwhytheymightwishtoprogramwiththeseparablemodels.

    SharedmodeldefinitionsReferringagaintothetableatthebeginningofthissection,noticethatmodeldefinitionsaresharedacrosscomponentsincaseswherethedataabstractionforeachcomponentissimilarenoughtosupportasingleinterfacewithoutovergenericizingthatinterface.Commonmodelsenableautomaticconnectabilitybetweencomponenttypes.Forexample,becausebothJSliderandJScrollbarusetheBoundedRangeModelinterface,asingleBoundedRangeModelinstancecouldbepluggedintobothaJScrollbarandaJSliderandtheirvisualstatewouldalwaysremaininsync.

    TheseparablemodelAPISwingcomponentsthatdefinemodelssupportaJavaBeansboundpropertyforthemodel.Forexample,JSliderusestheBoundedRangeModelinterfaceforitsmodeldefinition.Consequently,itincludesthefollowingmethods:

    publicBoundedRangeModelgetModel()publicvoidsetModel(BoundedRangeModelmodel)AllSwingcomponentshaveonethingincommon:Ifyoudon'tsetyourownmodel,adefaultiscreatedandinstalledinternallyinthecomponent.Thenamingconventionforthesedefaultmodelclassesistoprependtheinterfacenamewith"Default."ForJSlider,aDefaultBoundedRangeModelobjectisinstantiatedinitsconstructor:

    publicJSlider(intorientation,intmin,

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 3/12

    intmax,intvalue){checkOrientation(orientation)this.orientation=orientationthis.model=newDefaultBoundedRangeModel(value,0,min,max)this.model.addChangeListener(changeListener)updateUI()}

    IfaprogramsubsequentlycallssetModel(),thisdefaultmodelisreplaced,asinthefollowingexample:

    JSliderslider=newJSlider()BoundedRangeModelmyModel=newDefaultBoundedRangeModel(){publicvoidsetValue(intn){System.out.println("SetValue:"+n)super.setValue(n)}})slider.setModel(myModel)

    Formorecomplexmodels(suchasthoseforJTableandJList),anabstractmodelimplementationisalsoprovidedtoenabledeveloperstocreatetheirownmodelswithoutstartingfromscratch.Theseclassesareprependedwith"Abstract".

    Forexample,JList'smodelinterfaceisListModel,whichprovidesbothDefaultListModelandAbstractListModelclassestohelpthedeveloperinbuildingalistmodel.

    ModelchangenotificationModelsmustbeabletonotifyanyinterestedparties(suchasviews)whentheirdataorvaluechanges.SwingmodelsusetheJavaBeansEventmodelfortheimplementationofthisnotification.TherearetwoapproachesforthisnotificationusedinSwing:

    Sendalightweightnotificationthatthestatehas"changed"andrequirethelistenertorespondbysendingaquerybacktothemodeltofindoutwhathaschanged.Theadvantageofthisapproachisthatasingleeventinstancecanbeusedforallnotificationsfromaparticularmodelwhichishighlydesirablewhenthenotificationstendtobehighinfrequency(suchaswhenaJScrollBarisdragged).Sendastatefulnotificationthatdescribesmorepreciselyhowthemodelhaschanged.Thisalternativerequiresaneweventinstanceforeachnotification.Itisdesirablewhenagenericnotificationdoesn'tprovidethelistenerwithenoughinformationtodetermineefficientlywhathaschangedbyqueryingthemodel(suchaswhenacolumnofcellschangevalueinaJTable).

    LightweightnotificationThefollowingmodelsinSwingusethelightweightnotification,whichisbasedontheChangeListener/ChangeEventAPI:

    Model Listener EventBoundedRangeModel ChangeListener ChangeEventButtonModel ChangeListener ChangeEventSingleSelectionModel ChangeListener ChangeEvent

    TheChangeListenerinterfacehasasinglegenericmethod:

    publicvoidstateChanged(ChangeEvente)TheonlystateinaChangeEventistheevent"source."Becausethesourceisalwaysthesameacrossnotifications,asingleinstancecanbeusedforallnotificationsfromaparticularmodel.ModelsthatusethismechanismsupportthefollowingmethodstoaddandremoveChangeListeners:

    publicvoidaddChangeListener(ChangeListenerl)publicvoidremoveChangeListener(ChangeListenerl)Therefore,tobenotifiedwhenthevalueofaJSliderhaschanged,thecodemightlooklikethis:

    JSliderslider=newJSlider()BoundedRangeModelmodel=slider.getModel()model.addChangeListener(newChangeListener(){publicvoidstateChanged(ChangeEvente){//needtoquerythemodel//togetupdatedvalue...BoundedRangeModelm=(BoundedRangeModel)e.getSource()System.out.println("modelchanged:"+m.getValue())

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 4/12

    }})

    Toprovideconvenienceforprogramsthatdon'twishtodealwithseparatemodelobjects,someSwingcomponentclassesalsoprovidetheabilitytoregisterChangeListenersdirectlyonthecomponent(sothecomponentcanlistenforchangesonthemodelinternallyandthenpropagatesthoseeventstoanylistenersregistereddirectlyonthecomponent).Theonlydifferencebetweenthesenotificationsisthatforthemodelcase,theeventsourceisthemodelinstance,whileforthecomponentcase,thesourceisthecomponent.

    Sowecouldsimplifytheprecedingexampleto:

    JSliderslider=newJSlider()slider.addChangeListener(newChangeListener(){publicvoidstateChanged(ChangeEvente){//thesourcewillbe//thesliderthistime..JSliders=(JSlider)e.getSource()System.out.println("valuechanged:"+s.getValue())}})

    StatefulnotificationModelsthatsupportstatefulnotificationprovideeventListenerinterfacesandeventobjectsspecifictotheirpurpose.Thefollowingtableshowsthebreakdownforthosemodels:

    Model Listener EventListModel ListDataListener ListDataEventListSelectionModel ListSelectionListener ListSelectionEventComboBoxModel ListDataListener ListDataEventTreeModel TreeModelListener TreeModelEventTreeSelectionModel TreeSelectionListener TreeSelectionEventTableModel TableModelListener TableModelEvent

    TableColumnModel TableColumnModelListenerTableColumnModelEvent

    Document DocumentListener DocumentEventDocument UndoableEditListener UndoableEditEvent

    TheusageoftheseAPIsissimilartothelightweightnotification,exceptthatthelistenercanquerytheeventobjectdirectlytofindoutwhathaschanged.Forexample,thefollowingcodedynamicallytrackstheselectediteminaJList:

    Stringitems[]={"One","Two","Three")JListlist=newJList(items)ListSelectionModelsModel=list.getSelectionModel()sModel.addListSelectionListener(newListSelectionListener(){publicvoidvalueChanged(ListSelectionEvente){//getchangeinformationdirectly//fromtheeventinstance...if(!e.getValueIsAdjusting()){System.out.println("selectionchanged:"+e.getFirstIndex())}}})

    AutomaticViewUpdates

    Amodeldoesnothaveanyintrinsicknowledgeoftheviewthatrepresentsit.(Thisrequirementiscriticaltoenablemultipleviewsonthesamemodel).Instead,amodelhasonlyalistoflistenersinterestedinknowingwhenitsstatehaschanged.ASwingcomponenttakesresponsibilityforhookinguptheappropriatemodellistenersothatitcanappropriatelyrepaintitselfasthemodelchanges(ifyoufindthatacomponentisnotupdatingautomaticallywhenthemodelchanges,itisabug!).Thisistruewhetheradefaultinternalmodelisusedorwhetheraprograminstallsitsownmodelimplementation.

    IgnoringmodelscompletelyAsmentionedpreviously,mostcomponentsprovidethemodeldefinedAPIdirectlyinthecomponentclasssothatthecomponentcanbemanipulatedwithoutinteractingwiththemodelatall.Thisisconsideredperfectlyacceptableprogrammingpractice(especiallyfortheGUIstatemodels).Forexample,followingisJSlider'simplementationofgetValue(),whichinternallydelegatesthemethodcalltoitsmodel:

    publicintgetValue(){

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 5/12

    returngetModel().getValue()}Andsoprogramscansimplydothefollowing:

    JSliderslider=newJSlider()intvalue=slider.getValue()//what'sa"model,"anyway?

    SeparablemodelsummarySowhileit'susefultounderstandhowSwing'smodeldesignworks,itisn'tnecessarytousethemodelAPIforallaspectsofSwingprogramming.Youshouldcarefullyconsideryourapplication'sindividualneedsanddeterminewherethemodelAPIwillenhanceyourcodewithoutintroducingunnecessarycomplexity.

    Inparticular,werecommendtheusageoftheApplicationDatacategoryofmodelsforSwing(modelsforJTable,JTree,andthelike)becausetheycangreatlyenhancethescalabilityandmodularityofyourapplicationoverthelongrun.

    PluggablelookandfeelarchitectureSwing'spluggablelookandfeelarchitectureallowsustoprovideasinglecomponentAPIwithoutdictatingaparticularlookandfeel.TheSwingtoolkitprovidesadefaultsetoflookandfeelshowever,theAPIis"open"adesignthatadditionallyallowsdeveloperstocreatenewlookandfeelimplementationsbyeitherextendinganexistinglookandfeelorcreatingonefromscratch.AlthoughthepluggablelookandfeelAPIisextensible,itwasintentionallydesignedatalevelbelowthebasiccomponentAPIinsuchawaythatadeveloperdoesnotneedtounderstanditsintricatedetailstobuildSwingGUIs.(Butifyouwanttoknow,readon...)

    Whilewedon'texpect(oradvise)themajorityofdeveloperstocreatenewlookandfeelimplementations,werealizePL&Fisaverypowerfulfeatureforasubsetofapplicationsthatwanttocreateauniqueidentity.Asitturnsout,PL&FisalsoideallysuitedforuseinbuildingGUIsthatareaccessibletouserswithdisabilities,suchasvisuallyimpairedusersoruserswhocannotoperateamouse.

    Inanutshell,pluggablelookandfeeldesignsimplymeansthattheportionofacomponent'simplementationthatdealswiththepresentation(thelook)andeventhandling(thefeel)isdelegatedtoaseparateUIobjectsuppliedbythecurrentlyinstalledlookandfeel,whichcanbechangedatruntime.

    ThepluggablelookandfeelAPIThepluggablelookandfeelAPIincludes:

    SomesmallhooksintheSwingcomponentclasses.SometoplevelAPIforlookandfeelmanagement.AmorecomplexAPIthatactuallyimplementslookandfeelsinseparatepackages.Thecomponenthooks

    EachSwingcomponentthathaslookandfeelspecificbehaviordefinesanabstractclassintheswing.plafpackagetorepresentitsUIdelegate.Thenamingconventionfortheseclassesistotaketheclassnameforthecomponent,removethe"J"prefix,andappend"UI."Forexample,JButtondefinesitsUIdelegatewiththeplafclassButtonUI.

    TheUIdelegateiscreatedinthecomponent'sconstructorandisaccessibleasaJavaBeansboundpropertyonthecomponent.Forexample,JScrollBarprovidesthefollowingmethodstoaccessitsUIdelegate:

    publicScrollBarUIgetUI()publicvoidsetUI(ScrollBarUIui)ThisprocessofcreatingaUIdelegateandsettingitasthe"UI"propertyforacomponentisessentiallythe"installation"ofacomponent'slookandfeel.

    EachcomponentalsoprovidesamethodwhichcreatesandsetsaUIdelegateforthe"default"lookandfeel(thismethodisusedbytheconstructorwhendoingtheinstallation):

    publicvoidupdateUI()AlookandfeelimplementationprovidesconcretesubclassesforeachabstractplafUIclass.Forexample,theWindowslookandfeeldefinesWindowsButtonUI,aWindowsScrollBarUI,andsoon.WhenacomponentinstallsitsUIdelegate,itmusthaveawaytolookuptheappropriateconcreteclassnameforthecurrentdefaultlookandfeeldynamically.ThisoperationisperformedusingahashtableinwhichthekeyisdefinedprogrammaticallybythegetUIClassID()methodinthecomponent.Theconventionistousetheplafabstractclassnameforthesekeys.Forexample,JScrollbarprovides:

    publicStringgetUIClassID(){return"ScrollBarUI"}Consequently,thehashtableintheWindowslookandfeelwillprovideanentrythatmaps"ScrollBarUI"to

    "com.sun.java.swing.plaf.windows.WindowsScrollBarUI"

    Lookandfeelmanagement

    SwingdefinesanabstractLookAndFeelclassthatrepresentsalltheinformationcentraltoalookandfeelimplementation,suchasitsname,itsdescription,whetherit'sanativelookandfeelandinparticular,ahashtable(knownasthe"DefaultsTable")forstoringdefaultvaluesforvariouslookandfeelattributes,suchascolorsandfonts.

    EachlookandfeelimplementationdefinesasubclassofLookAndFeel(forexample,swing.plaf.motif.MotifLookAndFeel)toprovideSwingwiththenecessaryinformationtomanagethelookandfeel.

    TheUIManageristheAPIthroughwhichcomponentsandprogramsaccesslookandfeelinformation(theyshouldrarely,ifever,talkdirectlytoaLookAndFeelinstance).UIManagerisresponsibleforkeepingtrackofwhichLookAndFeelclassesareavailable,whichareinstalled,andwhichiscurrentlythedefault.TheUIManageralsomanagesaccesstotheDefaultsTableforthecurrentlookandfeel.

    The'default'lookandfeel

    TheUIManageralsoprovidesmethodsforgettingandsettingthecurrentdefaultLookAndFeel:

    publicstaticLookAndFeelgetLookAndFeel()

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 6/12

    publicstaticvoidsetLookAndFeel(LookAndFeelnewLookAndFeel)publicstaticvoidsetLookAndFeel(StringclassName)

    Asadefaultlookandfeel,SwinginitializesthecrossplatformJavalookandfeel(formerlyknownas"Metal").However,ifaSwingprogramwantstosetthedefaultLookandFeelexplicitly,itcandothatusingtheUIManager.setLookAndFeel()method.Forexample,thefollowingcodesamplewillsetthedefaultLookandFeeltobeCDE/Motif:

    UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel")Sometimesanapplicationmaynotwanttospecifyaparticularlookandfeel,butinsteadwantstoconfigurealookandfeelinsuchawaythatitdynamicallymatcheswhateverplatformithappenstoberunningon(forinstance,the.WindowslookandfeelifitisrunningonWindowsNT,orCDE/MotififitrunningonSolaris).Or,perhaps,anapplicationmightwanttolockdownthelookandfeeltothecrossplatformJavalookandfeel.

    TheUIManagerprovidesthefollowingstaticmethodstoprogrammaticallyobtaintheappropriateLookAndFeelclassnamesforeachofthesecases:

    publicstaticStringgetSystemLookAndFeelClassName()publicstaticStringgetCrossPlatformLookAndFeelClassName()So,toensurethataprogramalwaysrunsintheplatform'ssystemlookandfeel,thecodemightlooklikethis:

    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())DynamicallyChangingtheDefaultLookandFeel

    WhenaSwingapplicationprogrammaticallysetsthelookandfeel(asdescribedabove),theidealplacetodosoisbeforeanySwingcomponentsareinstantiated.ThisisbecausetheUIManager.setLookAndFeel()methodmakesaparticularLookAndFeelthecurrentdefaultbyloadingandinitializingthatLookAndFeelinstance,butitdoesnotautomaticallycauseanyexistingcomponentstochangetheirlookandfeel.

    RememberthatcomponentsinitializetheirUIdelegateatconstructtime,therefore,ifthecurrentdefaultchangesaftertheyareconstructed,theywillnotautomaticallyupdatetheirUIsaccordingly.Itisuptotheprogramtoimplementthisdynamicswitchingbytraversingthecontainmenthierarchyandupdatingthecomponentsindividually.(NOTE:SwingprovidestheSwingUtilities.updateComponentTreeUI()methodtoassistwiththisprocess).

    ThelookandfeelofacomponentcanbeupdatedatanytimetomatchthecurrentdefaultbyinvokingitsupdateUI()method,whichusesthefollowingstaticmethodonUIManagertogettheappropriateUIdelegate:

    publicstaticComponentUIgetUI(JComponentc)Forexample,theimplementationofupdateUI()fortheJScrollBarlookslikethefollowing:

    publicvoidupdateUI(){setUI((ScrollBarUI)UIManager.getUI(this))}AndsoifaprogramneedstochangethelookandfeelofaGUIhierarchyafteritwasinstantiated,thecodemightlooklikethefollowing:

    //GUIalreadyinstantiated,wheremyframe//istoplevelframetry{

    UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel")myframe.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR))SwingUtilities.updateComponentTreeUI(myframe)myframe.validate()

    }catch(UnsupportedLookAndFeelExceptione){}finally{myframe.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR))}

    Managinglookandfeeldata

    TheUIManagerdefinesastaticclass,namedUIManager.LookAndFeelInfo,forstoringthehighlevelname(suchas."Metal")andparticularclassname(suchas"com.sun.java.swing.plaf.MetalLookAndFeel")foraLookAndFeel.ItusestheseclassesinternallytomanagetheknownLookAndFeelobjects.ThisinformationcanbeaccessedfromtheUIManagerviathefollowingstaticmethods:

    publicstaticLookAndFeelInfo[]

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 7/12

    getInstalledLookAndFeels()

    publicstaticvoidsetInstalledLookAndFeels(LookAndFeelInfo[]infos)throwsSecurityException

    publicstaticvoidinstallLookAndFeel(LookAndFeelInfoinfo)

    publicstaticvoidinstallLookAndFeel(Stringname,StringclassName)

    Thesemethodscanbeusedtoprogrammaticallydeterminewhichlookandfeelimplementationsareavailable,whichisusefulwhenbuildinguserinterfaceswhichallowtheendusertodynamicallyselectalookandfeel.

    Thelookandfeelpackages

    TheUIdelegateclassesprovidedinswing.plaf(ButtonUI,ScrollBarUI,andsoon)definethepreciseAPIthatacomponentcanusetointeractwiththeUIdelegateinstance.(NOTE:Interfaceswereoriginallyusedhere,buttheywerereplacedwithabstractclassesbecausewefelttheAPIwasnotmatureenoughtowithstandtheconcretecastingofaninterface.)TheseplafAPIsaretherootofalllookandfeelimplementations.

    Eachlookandfeelimplementationprovidesconcretesubclassesoftheseabstractplafclasses.Allsuchclassesdefinedbyaparticularlookandfeelimplementationarecontainedinaseparatepackageundertheswing.plafpackage(forexample,.swing.plaf.motif,swing.plaf.metal,andsoon).Alookandfeelpackagecontainsthefollowing:

    TheLookAndFeelsubclass(forinstance,MetalLookAndFeel).Alllookandfeel'sUIdelegateclasses(forexample,MetalButtonUI,MetalTreeUI,andthelike).Anylookandfeelutilityclasses(MetalGraphicsUtils,MetalIconFactory,andsoon).Otherresourcesassociatedwiththelookandfeel,suchasimagefiles.InimplementingthevariousSwinglookandfeels,wesoondiscoveredthattherewasalotofcommonalityamongthem.Wefactoredoutthiscommoncodeintoabaselookandfeelimplementation(called"basic")whichextendstheplafabstractclassesandfromwhichthespecificlookandfeelimplementations(motif,windows,andsoon.)extend.Thebasiclookandfeelpackagesupportsbuildingadesktoplevellookandfeel,suchasWindowsorCDE/Motif.

    Thebasiclookandfeelpackageisjustoneexampleofhowtobuildapluggablelookandfeelthearchitectureisflexibleenoughtoaccommodateotherapproachesaswell.

    Theremainderofthisdocumentwillshowhowalookandfeelpackageworksatthegenericlevel,leavingthedetailsonthebasicpackageforafuturedocument.

    WARNING:AllAPIsdefinedbelowtheswing.plafpackagearenotfrozeninthe1.0.XversionofSwing.WearecurrentlycleaningupthoseAPIsfortheversionofSwingthatwillshipwithJDK1.2beta4,atwhichtimetheywillbecomefrozen.Soifyouaredevelopingyourownlookandfeelimplementationusingthe1.0.1API,thisislikelytoaffectyou.

    TheLookAndFeelSubclass

    TheLookAndFeelclassdefinesthefollowingabstractmethods,whichallsubclassesmustimplement:

    publicStringgetName()publicStringgetID()publicStringgetDescription()publicbooleanisNativeLookAndFeel()publicbooleanisSupportedLookAndFeel()ThegetName(),getID(),andgetDescription()methodsprovidegenericinformationaboutthelookandfeel.

    TheisNativeLookAndFeel()methodreturnstrueifthelookandfeelisnativetothecurrentplatform.Forexample,MotifLookAndFeelreturnstrueifitiscurrentlyrunningontheSolarisplatform,andreturnsfalseotherwise.

    TheisSupportedLookAndFeel()methodreturnswhetherornotthislookandfeelisauthorizedtorunonthecurrentplatform.Forexample,WindowsLookAndFeelreturnstrueonlyifitisrunningonaWindows95,Windows98,orWindowsNTmachine.

    ALookAndFeelclassalsoprovidesmethodsforinitializationanduninitialization:

    publicvoidinitialize()publicvoiduninitialize()Theinitialize()methodisinvokedbytheUIManagerwhentheLookAndFeelismadethe"default"usingtheUIManager.setLookAndFeel()method.uninitialize()isinvokedbytheUIManagerwhentheLookAndFeelisabouttobereplacedasthedefault.

    TheDefaultsTable

    Finally,theLookAndFeelclassprovidesamethodtoreturnthelookandfeel'simplementationoftheDefaultsTable:

    publicUIDefaultsgetDefaults()TheDefaultsTableisrepresentedbytheUIDefaultsclass,adirectextensionofjava.util.Hashtable,whichaddsmethodsforaccessingspecifictypesofinformationaboutalookandfeel.ThistablemustincludealltheUIClassIDtoclassnamemappinginformation,aswellasanydefaultvaluesforpresentationrelatedproperties(suchascolor,font,border,andicon)foreachUIdelegate.Forexample,followingisasampleofwhatafragmentofgetDefaults()mightlooklikeforahypotheticallookandfeelinapackagecalled"mine":

    publicUIDefaultsgetDefaults(){UIDefaultstable=newUIDefaults()

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 8/12

    Object[]uiDefaults={

    "ButtonUI","mine.MyButtonUI","CheckBoxUI","mine.MyCheckBoxUI","MenuBarUI","mine.MyMenuBarUI",..."Button.background",newColorUIResource(Color.gray),"Button.foreground",newColorUIResource(Color.black),"Button.font",newFontUIResource("Dialog",Font.PLAIN,12),"CheckBox.background",newColorUIResource(Color.lightGray),"CheckBox.font",newFontUIResource("Dialog",Font.BOLD,12),

    ...}table.putDefaults(uiDefaults)returntable

    }

    WhenthedefaultlookandfeelissetwithUIManager.setLookAndFeel(),theUIManagercallsgetDefaults()onthenewLookAndFeelinstanceandstoresthehashtableitreturns.SubsequentcallstotheUIManager'slookupmethodswillbeappliedtothistable.Forexample,aftermaking"mine"thedefaultLookandFeel:

    UIManager.get("ButtonUI")=>"mine.MyButtonUI"TheUIclassesaccesstheirdefaultinformationinthesameway.Forexample,ourexampleButtonUIclasswouldinitializetheJButton's"background"propertylikethis:

    button.setBackground(UIManager.getColor("Button.background")Thedefaultsareorganizedthiswaytoallowdeveloperstooverridethem.MoredetailaboutSwing'sDefaultsmechanismwillbepublishedinafuturearticle.

    DistinguishingbetweenUIsetandappsetproperties

    Swingallowsapplicationstosetpropertyvalues(suchascolorandfont)individuallyoncomponents.Soit'scriticaltomakesurethatthesevaluesdon'tgetclobberedwhenalookandfeelsetsupits"default"propertiesforthecomponent.

    ThisisnotanissuethefirsttimeaUIdelegateisinstalledonacomponent(atconstructtime)becauseallpropertieswillbeuninitializedandlegallysettablebythelookandfeel.Theproblemoccurswhentheapplicationsetsindividualpropertiesaftercomponentconstructionandthensubsequentlysetsanewlookandfeel(thatis,dynamiclookandfeelswitching).Thismeansthatthelookandfeelmustbeabletodistinguishbetweenpropertyvaluessetbytheapplication,andthosesetbyalookandfeel.

    Thisissueishandledbymarkingallvaluessetbythelookandfeelwiththeplaf.UIResourceinterface.Theplafpackageprovidesasetof"marked"classesforrepresentingthesevalues,ColorUIResource,FontUIResource,andBorderUIResource.TheprecedingcodeexampleshowstheusageoftheseclassestomarkthedefaultpropertyvaluesforthehypotheticalMyButtonUIclass.

    TheUIdelegateThesuperclassofallUIDelegateclassesisswing.plaf.ComponentUI.Thisclasscontainstheprimary"machinery"formakingthepluggablelookandfeelwork.ItsmethodsdealwithUIinstallationanduninstallation,andwithdelegationofacomponent'sgeometryhandlingandpainting.

    ManyoftheUIDelegatesubclassesalsoprovideadditionalmethodsspecifictotheirownrequiredinteractionwiththecomponenthowever,thisdocumentfocusesprimarilyonthegenericmechanismimplementedbyComponentUI.

    UIinstallationanddeinstallation

    Firstoff,theComponentUIclassdefinesthesemethodsmethodsforUIdelegateinstallationanduninstallation:

    publicvoidinstallUI(JComponentc)publicvoiduninstallUI(JComponentc)LookingattheimplementationofJComponent.setUI()(whichisalwaysinvokedfromthesetUImethodonJComponentsubclasses),wecanclearlyseehowUIdelegateinstallation/deinstallationworks:

    protectedvoidsetUI(ComponentUInewUI){if(ui!=null){ui.uninstallUI(this)

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 9/12

    }ComponentUIoldUI=uiui=newUIif(ui!=null){ui.installUI(this)}invalidate()firePropertyChange("UI",oldUI,newUI)}

    UIinstallationillustratedThisarticlecomeswithagiantpostersizechartthatillustratestheprocessinstallingaUIdelegate.Itcanprovideyouwithavaluableoverviewofthedelegateinstallationprocess.

    Tofoldoutthechart,justfollowthislink

    TheUIdelegate'sinstallUI()methodisresponsibleforthefollowing:

    Setdefaultfont,color,border,andopacitypropertiesonthecomponent.Installanappropriatelayoutmanageronthecomponent.AddanyappropriatechildsubcomponentstothecomponentRegisteranyrequiredeventlistenersonthecomponent.Registeranylookandfeelspecifickeyboardactions(mnemonics,etc.)forthecomponent.Registerappropriatemodellistenerstobenotifiedwhentorepaint.Initializeanyappropriateinstancedata.Forexample,theinstallUI()methodforanextensionofButtonUImightlooklikethis:

    protectedMyMouseListenermouseListenerprotectedMyChangeListenerchangeListener

    publicvoidinstallUI(JComponentc){AbstractButtonb=(AbstractButton)c//Installdefaultcolors&opacityColorbg=c.getBackground()if(bg==null||bginstanceofUIResource){c.setBackground(UIManager.getColor("Button.background"))}Colorfg=c.getForeground()if(fg==null||fginstanceofUIResource){c.setForeground(UIManager.getColor("Button.foreground"))}c.setOpaque(false)//InstalllistenersmouseListener=newMyMouseListener()c.addMouseListener(mouseListener)c.addMouseMotionListener(mouseListener)changeListener=newMyChangeListener()b.addChangeListener(changeListener)}

    Conventionsforinitializingcomponentproperties

    Swingdefinesanumberofconventionsforinitializingcomponentpropertiesatinstalltime,includingthefollowing:

    Allvaluesusedforsettingcolors,font,andborderpropertiesshouldbeobtainedfromtheDefaultstable(asdescribedinthesubsectionontheLookAndFeelsubclass).Color,fontandborderpropertiesshouldbesetifandonlyiftheapplicationhasnotalreadysetthem.TofacilitateconventionNo1,theUIManagerclassprovidesanumberofstaticmethodstoextractpropertyvaluesofaparticulartype(forinstance,thestaticmethodsUIManager.getColor(),UIManager.getFont(),andsoon).

    ConventionNo.2isimplementedbyalwayscheckingforeitheranullvalueoraninstanceofUIResourcebeforesettingtheproperty.

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 10/12

    TheComponentUI'suninstall()methodmustcarefullyundoeverythingthatwasdoneintheinstallUI()methodsothatthecomponentisleftinapristinestateforthenextUIdelegate.Theuninstall()methodisresponsiblefor:

    ClearingtheborderpropertyifithasbeensetbyinstallUI().RemovethelayoutmanagerifithadbeensetbyinstallUI().RemoveanysubcomponentsaddedbyinstallUI().Removeanyevent/modellistenersthatwereaddedbyinstallUI().RemoveanylookandfeelspecifickeyboardactionsthatwereinstalledbyinstallUI().Nullifyanyinitializedinstancedata(toallowGCtocleanup).Forexample,anuninstall()methodtoundowhatwedidintheaboveexampleinstallationmightlooklikethis:

    publicvoiduninstallUI(JComponentc){AbstractButtonb=(AbstractButton)c//Uninstalllistenersc.removeMouseListener(mouseListener)c.removeMouseMotionListener(mouseListener)mouseListener=nullb.removeChangeListener(changeListener)changeListener=null}

    Defininggeometry

    IntheAWT(andthusinSwing)acontainer'sLayoutManagerwilllayoutthechildcomponentsaccordingtoitsdefinedalgorithmthisisknownas"validation"ofacontainmenthierarchy.TypicallyLayoutManagerswillquerythechildcomponents'preferredSizeproperty(andsometimesminimumSizeand/ormaximumSizeaswell,dependingonthealgorithm)inordertodeterminepreciselyhowtopositionandsizethosechildren.

    Obviously,thesegeometrypropertiesaresomethingthatalookandfeelusuallyneedstodefineforagivencomponent,soComponentUIprovidesthefollowingmethodsforthispurpose:

    publicDimensiongetPreferredSize(JComponentc)publicDimensiongetMinimumSize(JComponentc)publicDimensiongetMaximumSize(JComponentc)publicbooleancontains(JComponentc,intx,inty)

    JComponent'sparallelmethods(whichareinvokedbytheLayoutManagerduringvalidation)thensimplydelegatetotheUIobject'sgeometrymethodsifthegeometrypropertywasnotexplicitlysetbytheprogram.BelowistheimplementationofJComponent.getPreferredSize()whichshowsthisdelegation:

    publicDimensiongetPreferredSize(){if(preferredSize!=null){returnpreferredSize}Dimensionsize=nullif(ui!=null){size=ui.getPreferredSize(this)}return(size!=null)?size:super.getPreferredSize()}

    EventhoughtheboundingboxforallcomponentsisaRectangle,it'spossibletosimulateanonrectangularcomponentbyoverridingtheimplementationofthecontains()methodfromjava.awt.Component.(Thismethodisusedforthehittestingofmouseevents).But,liketheothergeometrypropertiesinSwing,theUIdelegatedefinesitsownversionofthecontains()method,whichisalsodelegatedtobyJComponent.contains():

    publicbooleancontains(JComponentc,intx,inty){return(ui!=null)?ui.contains(this,x,y):super.contains(x,y)}SoaUIdelegatecouldprovidenonrectangular"feel"bydefiningaparticularimplementationofcontains()(forexample,ifwewantedourMyButtonUIclasstoimplementabuttonwithroundedcorners).

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 11/12

    JavaSDKsandTools

    JavaSE

    JavaEEandGlassfish

    Painting

    Finally,theUIdelegatemustpaintthecomponentappropriately,henceComponentUIhasthefollowingmethods:

    publicvoidpaint(Graphicsg,JComponentc)publicvoidupdate(Graphicsg,JComponentc)Andonceagain,JComponent.paintComponent()takescaretodelegatethepainting:

    protectedvoidpaintComponent(Graphicsg){if(ui!=null){GraphicsscratchGraphics=SwingGraphics.createSwingGraphics(g.create())try{ui.update(scratchGraphics,this)}finally{scratchGraphics.dispose()}}}

    SimilarlytothewayinwhichthingsaredoneinAWT,theUIdelegate'supdate()methodclearsthebackground(ifopaque)andtheninvokesitspaint()method,whichisultimatelyresponsibleforrenderingthecontentsofthecomponent.

    Statelessvs.statefuldelegates

    AllthemethodsonComponentUItakeaJComponentobjectasaparameter.ThisconventionenablesastatelessimplementationofaUIdelegate(becausethedelegatecanalwaysquerybacktothespecifiedcomponentinstanceforstateinformation).StatelessUIdelegateimplementationsallowasingleUIdelegateinstancetobeusedforallinstancesofthatcomponentclass,whichcansignificantlyreducethenumberofobjectsinstantiated.

    ThisapproachworkswellformanyofthesimplerGUIcomponents.Butformorecomplexcomponents,wefounditnottobea"win"becausetheinefficiencycreatedbyconstantstaterecalculationswasworsethancreatingextraobjects(especiallysincethenumberofcomplexGUIcomponentscreatedinagivenprogramtendstobesmall).

    TheComponentUIclassdefinesastaticmethodforreturningadelegateinstance:

    publicstaticComponentUIcreateUI(JComponentc)It'stheimplementationofthismethodthatdetermineswhetherthedelegateisstatelessorstateful.That'sbecausetheUIManager.getUI()methodinvokedbythecomponenttocreatetheUIdelegateinternallyinvokesthiscreateUImethodonthedelegateclasstogettheinstance.

    TheSwinglookandfeelimplementationsusebothtypesofdelegates.Forexample,Swing'sBasicButtonUIclassimplementsastatelessdelegate:

    //SharedUIobjectprotectedstaticButtonUIbuttonUIpublicstaticComponentUIcreateUI(JComponentc)if(buttonUI==null){buttonUI=newBasicButtonUI()}returnbuttonUI}

    WhileSwing'sBasicTabbedPaneUIusesthestatefulapproach:

    publicstaticComponentUIcreateUI(JComponentc)returnnewBasicTabbedPaneUI()}

    PluggableLookandFeelsummaryThepluggablelookandfeelfeatureofSwingisbothpowerfulandcomplex(whichyouunderstandifyou'vegottenthisfar!).Itisdesignedtobeprogrammedbyasmallsubsetofdeveloperswhohaveaparticularneedtodevelopanewlookandfeelimplementation.Ingeneral,applicationdevelopersonlyneedtounderstandthecapabilitiesofthismechanisminordertodecidehowtheywishtosupportlookandfeels(suchaswhethertolockdowntheprogramtoasinglelookandfeelorsupportlookandfeelconfigurationbytheuser).Swing'sUIManagerprovidestheAPIforapplicationstomanagethelookandfeelatthislevel.

    Ifyou'reoneofthosedeveloperswhoneeds(orwants)todevelopacustomlookandfeel,it'scriticaltounderstandtheseunderpinningsbeforeyouwriteasinglelineofcode.We'reworkingonprovidingbetterdocumentationtohelpwiththisprocessstartingwiththisdocument,andcontinuingwithothersthatwillfollowsoon.

  • 24/12/2014 ASwingArchitectureOverview

    http://www.oracle.com/technetwork/java/architecture142923.html?printOnly=1 12/12

    JavaME

    JavaCard

    NetBeansIDE

    JavaMissionControl

    JavaResources

    JavaAPIs

    TechnicalArticles

    DemosandVideos

    Forums

    JavaMagazine

    Java.net

    DeveloperTraining

    Tutorials

    Java.com