Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Article-EditorContributor/EditorContributor.html235
-rw-r--r--Article-EditorContributor/images/Adarrow.gifbin0 -> 857 bytes
-rw-r--r--Article-EditorContributor/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-EditorContributor/images/articles.gifbin0 -> 2012 bytes
-rw-r--r--Article-EditorContributor/images/howto_banner.jpgbin0 -> 9877 bytes
-rw-r--r--Article-EditorContributor/images/htmltoolbar.jpgbin0 -> 39205 bytes
-rw-r--r--Article-EditorContributor/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-EditorContributor/images/markers.jpgbin0 -> 190691 bytes
-rw-r--r--Article-EditorContributor/images/normaltoolbar.jpgbin0 -> 24853 bytes
-rw-r--r--Article-EditorContributor/images/note.gifbin0 -> 1014 bytes
-rw-r--r--Article-EditorContributor/images/notifiers.gifbin0 -> 7404 bytes
-rw-r--r--Article-EditorContributor/images/srctoolbar.jpgbin0 -> 38142 bytes
-rw-r--r--Article-EditorContributor/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-EditorContributor/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-EditorContributor/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-EditorContributor/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-EditorContributor/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-EditorContributor/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-EditorContributor/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-EditorContributor/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-EditorContributor/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-EditorContributor/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-EditorContributor/images/write.pngbin0 -> 1982 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/default_style.css11
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/folding.html395
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/Thumbs.dbbin0 -> 77312 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/annotationSummary.pngbin0 -> 6781 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/hover.pngbin0 -> 3761 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/note.gifbin0 -> 1014 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/projectionAnnotation.pngbin0 -> 5421 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/withFolding.pngbin0 -> 6893 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/withoutFolding.pngbin0 -> 4266 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/xmlEditor.pngbin0 -> 9712 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/images/xmlEditor1.gifbin0 -> 18496 bytes
-rw-r--r--Article-Folding-in-Eclipse-Text-Editors/xmlEditorPlugin.zipbin0 -> 36521 bytes
-rw-r--r--Article-GEF-Draw2d/GEF-Draw2d.html379
-rw-r--r--Article-GEF-Draw2d/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-GEF-Draw2d/images/UMLDiagGIF.gifbin0 -> 6806 bytes
-rw-r--r--Article-GEF-Draw2d/images/classDiagConnectionGIF.gifbin0 -> 7191 bytes
-rw-r--r--Article-GEF-Draw2d/images/classDiagDecoGIF.gifbin0 -> 7081 bytes
-rw-r--r--Article-GEF-Draw2d/images/classDiagGIF.gifbin0 -> 1359 bytes
-rw-r--r--Article-GEF-Draw2d/images/classDiagLabelsGIF.gifbin0 -> 7274 bytes
-rw-r--r--Article-GEF-Draw2d/images/class_obj.gifbin0 -> 194 bytes
-rw-r--r--Article-GEF-Draw2d/images/field_private_obj.gifbin0 -> 109 bytes
-rw-r--r--Article-GEF-Draw2d/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-GEF-Draw2d/images/methpub_obj.gifbin0 -> 121 bytes
-rw-r--r--Article-GEF-Draw2d/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-GEF-Draw2d/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-GEF-Draw2d/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-GEF-Draw2d/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-GEF-Draw2d/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-GEF-Draw2d/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-GEF-Draw2d/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-GEF-Draw2d/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-GEF-Draw2d/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-GEF-Draw2d/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-GEF-EMF/article_style.css25
-rw-r--r--Article-GEF-EMF/files/shapesemf.zipbin0 -> 124972 bytes
-rw-r--r--Article-GEF-EMF/files/shapesmerlin.zipbin0 -> 126914 bytes
-rw-r--r--Article-GEF-EMF/files/shapesrcp.zipbin0 -> 83666 bytes
-rw-r--r--Article-GEF-EMF/gef-emf.html758
-rw-r--r--Article-GEF-EMF/images/connection.pngbin0 -> 6399 bytes
-rw-r--r--Article-GEF-EMF/images/ediagram.jpgbin0 -> 76959 bytes
-rw-r--r--Article-GEF-EMF/images/shape.pngbin0 -> 5108 bytes
-rw-r--r--Article-GEF-EMF/images/shapesdiagram.pngbin0 -> 4215 bytes
-rw-r--r--Article-GEF-EMF/images/shapesmerlin.pngbin0 -> 47038 bytes
-rw-r--r--Article-GEF-EMF/images/shapesmodel.pngbin0 -> 23852 bytes
-rw-r--r--Article-GEF-EMF/images/shapesrcp.pngbin0 -> 29524 bytes
-rw-r--r--Article-GEF-EMF/images/shapetypes.pngbin0 -> 4808 bytes
-rw-r--r--Article-GEF-diagram-editor/default_style.css49
-rw-r--r--Article-GEF-diagram-editor/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-GEF-diagram-editor/images/delete_action3.gifbin0 -> 11173 bytes
-rw-r--r--Article-GEF-diagram-editor/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-GEF-diagram-editor/images/shape_screenshot2.jpgbin0 -> 61063 bytes
-rw-r--r--Article-GEF-diagram-editor/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-GEF-diagram-editor/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-GEF-diagram-editor/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-GEF-diagram-editor/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-GEF-diagram-editor/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-GEF-diagram-editor/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-GEF-diagram-editor/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-GEF-diagram-editor/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-GEF-diagram-editor/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-GEF-diagram-editor/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-GEF-diagram-editor/shape.html1289
-rw-r--r--Article-GEF-dnd/DNDExample.java57
-rw-r--r--Article-GEF-dnd/GEF-dnd.html321
-rw-r--r--Article-GEF-editor/gef-schema-editor.html1000
-rw-r--r--Article-GEF-editor/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-GEF-editor/images/editor.JPGbin0 -> 72480 bytes
-rw-r--r--Article-GEF-editor/images/layout.gifbin0 -> 866 bytes
-rw-r--r--Article-GEF-editor/images/revalidate-s.JPGbin0 -> 18872 bytes
-rw-r--r--Article-GEF-editor/images/revalidate.JPGbin0 -> 63161 bytes
-rw-r--r--Article-GEF-editor/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-GEF-editor/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-GEF-editor/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-GEF-editor/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-GEF-editor/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-GEF-editor/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-GEF-editor/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-GEF-editor/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-GEF-editor/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-GEF-editor/schemaeditor.zipbin0 -> 172647 bytes
-rw-r--r--Article-Image-Viewer/Image_viewer.html831
-rw-r--r--Article-Image-Viewer/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Image-Viewer/images/activity.bmpbin0 -> 241436 bytes
-rw-r--r--Article-Image-Viewer/images/allClass.jpgbin0 -> 105528 bytes
-rw-r--r--Article-Image-Viewer/images/all_classes.jpgbin0 -> 105528 bytes
-rw-r--r--Article-Image-Viewer/images/buttons.bmpbin0 -> 9206 bytes
-rw-r--r--Article-Image-Viewer/images/buttons.jpgbin0 -> 12660 bytes
-rw-r--r--Article-Image-Viewer/images/flower.jpgbin0 -> 260619 bytes
-rw-r--r--Article-Image-Viewer/images/gap.bmpbin0 -> 53368 bytes
-rw-r--r--Article-Image-Viewer/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Image-Viewer/images/model.bmpbin0 -> 838424 bytes
-rw-r--r--Article-Image-Viewer/images/note.gifbin0 -> 260 bytes
-rw-r--r--Article-Image-Viewer/images/open.bmpbin0 -> 332456 bytes
-rw-r--r--Article-Image-Viewer/images/open1.bmpbin0 -> 396564 bytes
-rw-r--r--Article-Image-Viewer/images/open_activity.jpgbin0 -> 47605 bytes
-rw-r--r--Article-Image-Viewer/images/paint.bmpbin0 -> 424742 bytes
-rw-r--r--Article-Image-Viewer/images/render_flowchart.jpgbin0 -> 42340 bytes
-rw-r--r--Article-Image-Viewer/images/render_model.jpgbin0 -> 136577 bytes
-rw-r--r--Article-Image-Viewer/images/screen_shot.jpgbin0 -> 66441 bytes
-rw-r--r--Article-Image-Viewer/images/scroll_zoom_activity.jpgbin0 -> 47790 bytes
-rw-r--r--Article-Image-Viewer/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Image-Viewer/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Image-Viewer/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Image-Viewer/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Image-Viewer/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Image-Viewer/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Image-Viewer/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Image-Viewer/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Image-Viewer/images/transform.bmpbin0 -> 145056 bytes
-rw-r--r--Article-Image-Viewer/images/transform.jpgbin0 -> 25281 bytes
-rw-r--r--Article-Image-Viewer/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Image-Viewer/images/viewer.jpgbin0 -> 66441 bytes
-rw-r--r--Article-Image-Viewer/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Image-Viewer/imageviewer.zipbin0 -> 34037 bytes
-rw-r--r--Article-Internationalization/how2I18n.html1255
-rw-r--r--Article-Internationalization/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Internationalization/images/envelope.jpgbin0 -> 999 bytes
-rw-r--r--Article-Internationalization/images/fraggen1.jpgbin0 -> 27285 bytes
-rw-r--r--Article-Internationalization/images/fraggen2.jpgbin0 -> 25323 bytes
-rw-r--r--Article-Internationalization/images/fraggen3.jpgbin0 -> 27675 bytes
-rw-r--r--Article-Internationalization/images/image2.jpgbin0 -> 42281 bytes
-rw-r--r--Article-Internationalization/images/image20.jpgbin0 -> 35533 bytes
-rw-r--r--Article-Internationalization/images/image23.jpgbin0 -> 30548 bytes
-rw-r--r--Article-Internationalization/images/image24.jpgbin0 -> 62704 bytes
-rw-r--r--Article-Internationalization/images/image25.jpgbin0 -> 29541 bytes
-rw-r--r--Article-Internationalization/images/image26.jpgbin0 -> 43230 bytes
-rw-r--r--Article-Internationalization/images/image28.jpgbin0 -> 15963 bytes
-rw-r--r--Article-Internationalization/images/image6.jpgbin0 -> 44859 bytes
-rw-r--r--Article-Internationalization/images/image7.jpgbin0 -> 37554 bytes
-rw-r--r--Article-Internationalization/images/image8.jpgbin0 -> 26117 bytes
-rw-r--r--Article-Internationalization/images/image9.jpgbin0 -> 57819 bytes
-rw-r--r--Article-Internationalization/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Internationalization/images/mailbox.jpgbin0 -> 3692 bytes
-rw-r--r--Article-Internationalization/images/nav3.jpgbin0 -> 22540 bytes
-rw-r--r--Article-Internationalization/images/never.jpgbin0 -> 787 bytes
-rw-r--r--Article-Internationalization/images/route66.jpgbin0 -> 1895 bytes
-rw-r--r--Article-Internationalization/images/skip.jpgbin0 -> 781 bytes
-rw-r--r--Article-Internationalization/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Internationalization/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Internationalization/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Internationalization/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Internationalization/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Internationalization/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Internationalization/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Internationalization/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Internationalization/images/translate.jpgbin0 -> 753 bytes
-rw-r--r--Article-Internationalization/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Internationalization/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-JET/default_style.css24
-rw-r--r--Article-JET/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-JET/images/addJetNaturePopup.gifbin0 -> 4234 bytes
-rw-r--r--Article-JET/images/compiledTemplate.gifbin0 -> 3686 bytes
-rw-r--r--Article-JET/images/generator_skeleton.gifbin0 -> 6127 bytes
-rw-r--r--Article-JET/images/jetWizard.gifbin0 -> 12761 bytes
-rw-r--r--Article-JET/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-JET/images/missing_jet_directive.gifbin0 -> 6048 bytes
-rw-r--r--Article-JET/images/newproject.gifbin0 -> 2533 bytes
-rw-r--r--Article-JET/images/projectProperties.gifbin0 -> 8401 bytes
-rw-r--r--Article-JET/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-JET/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-JET/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-JET/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-JET/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-JET/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-JET/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-JET/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-JET/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-JET/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-JET/jet_tutorial1.html644
-rw-r--r--Article-JET/jet_tutorial1.html_old574
-rw-r--r--Article-JET/untitled.htm11
-rw-r--r--Article-JET2/JETCTask.java155
-rw-r--r--Article-JET2/default_style.css22
-rw-r--r--Article-JET2/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-JET2/images/enum_gui_page1.gifbin0 -> 9502 bytes
-rw-r--r--Article-JET2/images/enum_gui_page2.gifbin0 -> 11229 bytes
-rw-r--r--Article-JET2/images/enum_gui_page3.gifbin0 -> 13076 bytes
-rw-r--r--Article-JET2/images/jetemitter.gifbin0 -> 3439 bytes
-rw-r--r--Article-JET2/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-JET2/images/new_creation_wizard.gifbin0 -> 10466 bytes
-rw-r--r--Article-JET2/images/new_toolbar.gifbin0 -> 2030 bytes
-rw-r--r--Article-JET2/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-JET2/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-JET2/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-JET2/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-JET2/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-JET2/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-JET2/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-JET2/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-JET2/images/translate_action.gifbin0 -> 6703 bytes
-rw-r--r--Article-JET2/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-JET2/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-JET2/jet_tutorial2.html1033
-rw-r--r--Article-JET2/jet_tutorial2.html_old979
-rw-r--r--Article-JET2/jetc-task.jarbin0 -> 3823 bytes
-rw-r--r--Article-JET2/jp.azzurri.jet.article2.typesafe_enum_1.0.0.zipbin0 -> 93213 bytes
-rw-r--r--Article-JET2/org.eclipse.emf.examples.jet.article2_2.0.0.zipbin0 -> 88206 bytes
-rw-r--r--Article-JFace Wizards/wizardArticle.html484
-rw-r--r--Article-JFace Wizards/wizardsPlugin.jarbin0 -> 26922 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/car.gifbin0 -> 10787 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/error.gifbin0 -> 12420 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/mainPage.gifbin0 -> 12028 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/newWizard.gifbin0 -> 25239 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/plane.gifbin0 -> 11621 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/popup.gifbin0 -> 57598 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-JFace Wizards/wizards_files/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Java-launch/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Java-launch/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Java-launch/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Java-launch/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Java-launch/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Java-launch/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Java-launch/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Java-launch/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Java-launch/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Java-launch/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Java-launch/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Java-launch/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Java-launch/launching-java.html444
-rw-r--r--Article-Java-launch/org.eclipse.jdt.launching.examples.tomcat.zipbin0 -> 16961 bytes
-rw-r--r--Article-Launch-Framework/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Launch-Framework/images/Screenshot1.gifbin0 -> 31894 bytes
-rw-r--r--Article-Launch-Framework/images/Screenshot2.gifbin0 -> 31575 bytes
-rw-r--r--Article-Launch-Framework/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Launch-Framework/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Launch-Framework/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Launch-Framework/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Launch-Framework/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Launch-Framework/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Launch-Framework/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Launch-Framework/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Launch-Framework/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Launch-Framework/launch.html1151
-rw-r--r--Article-Levels-Of-Integration/Levels Of Integration.html251
-rw-r--r--Article-Levels-Of-Integration/images/idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Mark My Words/Mark My Words.html375
-rw-r--r--Article-Mark My Words/images/bkmrk_tsk.gifbin0 -> 104 bytes
-rw-r--r--Article-Mark My Words/images/error_tsk.gifbin0 -> 903 bytes
-rw-r--r--Article-Mark My Words/images/idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Mark My Words/images/info_tsk.gifbin0 -> 94 bytes
-rw-r--r--Article-Mark My Words/images/markers.jpgbin0 -> 128954 bytes
-rw-r--r--Article-Mark My Words/images/task_tsk.gifbin0 -> 170 bytes
-rw-r--r--Article-Mark My Words/images/warn_tsk.gifbin0 -> 146 bytes
-rw-r--r--Article-Monitor/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Monitor/images/classDiagramDetail.gifbin0 -> 4504 bytes
-rw-r--r--Article-Monitor/images/classDiagramMain.gifbin0 -> 3565 bytes
-rw-r--r--Article-Monitor/images/logView.jpgbin0 -> 43111 bytes
-rw-r--r--Article-Monitor/images/monitoring.gifbin0 -> 2966 bytes
-rw-r--r--Article-Monitor/images/newServerWizard.gifbin0 -> 10946 bytes
-rw-r--r--Article-Monitor/images/preferences.gifbin0 -> 16925 bytes
-rw-r--r--Article-Monitor/images/sample1.gifbin0 -> 1358550 bytes
-rw-r--r--Article-Monitor/images/sample1.jpgbin0 -> 72435 bytes
-rw-r--r--Article-Monitor/images/serverOperations.jpgbin0 -> 88178 bytes
-rw-r--r--Article-Monitor/images/servers.gifbin0 -> 5957 bytes
-rw-r--r--Article-Monitor/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Monitor/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Monitor/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Monitor/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Monitor/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Monitor/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Monitor/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Monitor/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Monitor/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Monitor/monitorArticle.html430
-rw-r--r--Article-Monitor/monitorPlugin.jarbin0 -> 95489 bytes
-rw-r--r--Article-Mutatis-mutandis/images/FieldEditorPreferenceHierarchy.GIFbin0 -> 2639 bytes
-rw-r--r--Article-Mutatis-mutandis/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Mutatis-mutandis/images/PreferencePage.GIFbin0 -> 47738 bytes
-rw-r--r--Article-Mutatis-mutandis/images/PropertyHierarchy.GIFbin0 -> 2689 bytes
-rw-r--r--Article-Mutatis-mutandis/images/PropertyPage.GIFbin0 -> 42026 bytes
-rw-r--r--Article-Mutatis-mutandis/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Mutatis-mutandis/images/spellPreferences.GIFbin0 -> 37080 bytes
-rw-r--r--Article-Mutatis-mutandis/images/spellProperties.GIFbin0 -> 34058 bytes
-rw-r--r--Article-Mutatis-mutandis/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Mutatis-mutandis/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Mutatis-mutandis/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Mutatis-mutandis/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Mutatis-mutandis/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Mutatis-mutandis/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Mutatis-mutandis/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Mutatis-mutandis/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Mutatis-mutandis/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Mutatis-mutandis/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Mutatis-mutandis/overlay-pages.html812
-rw-r--r--Article-Mutatis-mutandis/overlayPages.zipbin0 -> 8986 bytes
-rw-r--r--Article-Online Help for 1_0/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Online Help for 1_0/final.jpgbin0 -> 46096 bytes
-rw-r--r--Article-Online Help for 1_0/final.zipbin0 -> 6894 bytes
-rw-r--r--Article-Online Help for 1_0/help1.htm475
-rw-r--r--Article-Online Help for 1_0/initialstructure.zipbin0 -> 6894 bytes
-rw-r--r--Article-Online Help for 1_0/toplevel.jpgbin0 -> 5456 bytes
-rw-r--r--Article-Online Help for 2_0/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Online Help for 2_0/book.jpgbin0 -> 29016 bytes
-rw-r--r--Article-Online Help for 2_0/books.jpgbin0 -> 72224 bytes
-rw-r--r--Article-Online Help for 2_0/expanded_book.jpgbin0 -> 44433 bytes
-rw-r--r--Article-Online Help for 2_0/final.zipbin0 -> 8839 bytes
-rw-r--r--Article-Online Help for 2_0/final_ja_JP.zipbin0 -> 18607 bytes
-rw-r--r--Article-Online Help for 2_0/help1.htm358
-rw-r--r--Article-Online Help for 2_0/initialstructure.zipbin0 -> 7094 bytes
-rw-r--r--Article-Online Help for 2_0/zipped_plugin.zipbin0 -> 8392 bytes
-rw-r--r--Article-PDE-Automation/NoCVSConnStackTrace.txt243
-rw-r--r--Article-PDE-Automation/automation.html1568
-rw-r--r--Article-PDE-Automation/automation_style.css25
-rw-r--r--Article-PDE-Automation/buildInteractionDiagram.pngbin0 -> 11611 bytes
-rw-r--r--Article-PDE-Automation/buildRunConfiguration.pngbin0 -> 28029 bytes
-rw-r--r--Article-PDE-Automation/createAntBuildFile.pngbin0 -> 4569 bytes
-rw-r--r--Article-PDE-Automation/exportFeaturesDialog.pngbin0 -> 14125 bytes
-rw-r--r--Article-PDE-Automation/featureManifestEditor.pngbin0 -> 11712 bytes
-rw-r--r--Article-PDE-Automation/fetchProcessActivity.pngbin0 -> 9240 bytes
-rw-r--r--Article-PDE-Automation/figureOrdering.rb51
-rw-r--r--Article-PDE-Automation/runTestsInteractionDiagram.pngbin0 -> 7932 bytes
-rw-r--r--Article-PDE-Automation/runTestsRdtInteractionDiagram.pngbin0 -> 2695 bytes
-rw-r--r--Article-PDE-does-plugins/PDE-intro.html359
-rw-r--r--Article-PDE-does-plugins/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-PDE-does-plugins/images/compilers.gifbin0 -> 41136 bytes
-rw-r--r--Article-PDE-does-plugins/images/dependencies_page.gifbin0 -> 12575 bytes
-rw-r--r--Article-PDE-does-plugins/images/deploy.gifbin0 -> 30888 bytes
-rw-r--r--Article-PDE-does-plugins/images/dialog.gifbin0 -> 18771 bytes
-rw-r--r--Article-PDE-does-plugins/images/directory.gifbin0 -> 37900 bytes
-rw-r--r--Article-PDE-does-plugins/images/export_wizard.gifbin0 -> 37655 bytes
-rw-r--r--Article-PDE-does-plugins/images/extensions.gifbin0 -> 12391 bytes
-rw-r--r--Article-PDE-does-plugins/images/extensions2.gifbin0 -> 14141 bytes
-rw-r--r--Article-PDE-does-plugins/images/extensions3.gifbin0 -> 13207 bytes
-rw-r--r--Article-PDE-does-plugins/images/extensions4.gifbin0 -> 22002 bytes
-rw-r--r--Article-PDE-does-plugins/images/launcher_1.gifbin0 -> 44026 bytes
-rw-r--r--Article-PDE-does-plugins/images/plugin_project_1.gifbin0 -> 21656 bytes
-rw-r--r--Article-PDE-does-plugins/images/plugin_project_2.gifbin0 -> 57464 bytes
-rw-r--r--Article-PDE-does-plugins/images/project.gifbin0 -> 5137 bytes
-rw-r--r--Article-PDE-does-plugins/images/runtime_page.gifbin0 -> 17305 bytes
-rw-r--r--Article-PDE-does-plugins/images/sample_action_code.gifbin0 -> 7890 bytes
-rw-r--r--Article-PDE-does-plugins/images/target_platform.gifbin0 -> 49455 bytes
-rw-r--r--Article-PDE-does-plugins/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Plug-in-architecture/doc/allclasses-frame.html61
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/IProcessMember.html181
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/PrintMemberIdentity.html258
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html280
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/ProcessExtensions.html219
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/IProcessMember.html150
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/PrintMemberIdentity.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/PrintMemberMenuAction.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/ProcessExtensions.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-frame.html41
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-summary.html164
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-tree.html111
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-use.html123
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html216
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html216
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/class-use/ListenerX.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/class-use/ListenerY.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-frame.html28
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-summary.html130
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-tree.html106
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-use.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html216
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html216
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/class-use/ListenerX.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/class-use/ListenerY.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-frame.html28
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-summary.html130
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-tree.html106
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-use.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/IListener.html175
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/Subject.html248
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html276
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/IListener.html140
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/Subject.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/UpdateMenuAction.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-frame.html39
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-summary.html146
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-tree.html112
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-use.html122
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/Echo.html224
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/class-use/Echo.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-frame.html26
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-summary.html128
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-tree.html105
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-use.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/Dummy.html184
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/class-use/Dummy.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-frame.html26
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-summary.html128
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-tree.html104
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-use.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html271
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/class-use/Exponentiation.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-frame.html26
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-summary.html128
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-tree.html105
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-use.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/Multiplication.html269
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/class-use/Multiplication.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-frame.html26
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-summary.html128
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-tree.html105
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-use.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/FunctionsGrid.html229
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html306
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/IFunction.html179
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html228
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/FunctionsGrid.html133
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/FunctionsViewPart.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/IFunction.html225
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/ProcessServiceMembers.html95
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-frame.html41
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-summary.html155
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-tree.html115
-rw-r--r--Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-use.html188
-rw-r--r--Article-Plug-in-architecture/doc/com_bolour_sample_eclipse_listener_subject_listeners.html63
-rw-r--r--Article-Plug-in-architecture/doc/com_bolour_sample_eclipse_service_ui_functions.html74
-rw-r--r--Article-Plug-in-architecture/doc/deprecated-list.html93
-rw-r--r--Article-Plug-in-architecture/doc/help-doc.html152
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-1.html96
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-10.html99
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-11.html111
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-12.html97
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-13.html99
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-2.html117
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-3.html105
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-4.html99
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-5.html99
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-6.html100
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-7.html120
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-8.html96
-rw-r--r--Article-Plug-in-architecture/doc/index-files/index-9.html120
-rw-r--r--Article-Plug-in-architecture/doc/index.html25
-rw-r--r--Article-Plug-in-architecture/doc/overview-frame.html52
-rw-r--r--Article-Plug-in-architecture/doc/overview-summary.html147
-rw-r--r--Article-Plug-in-architecture/doc/overview-tree.html126
-rw-r--r--Article-Plug-in-architecture/doc/package-list9
-rw-r--r--Article-Plug-in-architecture/doc/packages.html26
-rw-r--r--Article-Plug-in-architecture/doc/serialized-form.html93
-rw-r--r--Article-Plug-in-architecture/doc/stylesheet.css29
-rw-r--r--Article-Plug-in-architecture/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Plug-in-architecture/images/eclipse_extensions.jpgbin0 -> 63296 bytes
-rw-r--r--Article-Plug-in-architecture/images/functions_grid_view.jpgbin0 -> 61446 bytes
-rw-r--r--Article-Plug-in-architecture/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Plug-in-architecture/images/listeners_extensions.jpgbin0 -> 69632 bytes
-rw-r--r--Article-Plug-in-architecture/images/services_extensions.jpgbin0 -> 67156 bytes
-rw-r--r--Article-Plug-in-architecture/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Plug-in-architecture/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Plug-in-architecture/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Plug-in-architecture/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Plug-in-architecture/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Plug-in-architecture/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Plug-in-architecture/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Plug-in-architecture/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Plug-in-architecture/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Plug-in-architecture/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Plug-in-architecture/plugin_architecture.html2574
-rw-r--r--Article-Plug-in-architecture/samples.zipbin0 -> 63041 bytes
-rw-r--r--Article-Plug-in-architecture/specific_style.css4
-rw-r--r--Article-Plugging-into-SourceForge/images/SourceForge.net.pngbin0 -> 15619 bytes
-rw-r--r--Article-Plugging-into-SourceForge/images/WinSCP.pngbin0 -> 84258 bytes
-rw-r--r--Article-Plugging-into-SourceForge/images/cvs-view.pngbin0 -> 8128 bytes
-rw-r--r--Article-Plugging-into-SourceForge/images/frs.pngbin0 -> 4798 bytes
-rw-r--r--Article-Plugging-into-SourceForge/images/new-cvs.pngbin0 -> 10188 bytes
-rw-r--r--Article-Plugging-into-SourceForge/images/sfpde-med.pngbin0 -> 82321 bytes
-rw-r--r--Article-Plugging-into-SourceForge/images/working-set.pngbin0 -> 43281 bytes
-rw-r--r--Article-Plugging-into-SourceForge/sourceforge.html935
-rw-r--r--Article-Preferences/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Preferences/images/badwordpreference.gifbin0 -> 13269 bytes
-rw-r--r--Article-Preferences/images/colorpreference.gifbin0 -> 12515 bytes
-rw-r--r--Article-Preferences/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Preferences/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Preferences/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Preferences/images/tree.gifbin0 -> 4415 bytes
-rw-r--r--Article-Preferences/preferences.htm414
-rw-r--r--Article-Preferences/preferences.zipbin0 -> 7985 bytes
-rw-r--r--Article-Properties-View/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Properties-View/images/default.jpgbin0 -> 3135 bytes
-rw-r--r--Article-Properties-View/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Properties-View/images/properties.jpgbin0 -> 65343 bytes
-rw-r--r--Article-Properties-View/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Properties-View/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Properties-View/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Properties-View/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Properties-View/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Properties-View/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Properties-View/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Properties-View/images/tag_a.jpgbin0 -> 916 bytes
-rw-r--r--Article-Properties-View/images/tag_b.jpgbin0 -> 924 bytes
-rw-r--r--Article-Properties-View/images/tag_c.jpgbin0 -> 913 bytes
-rw-r--r--Article-Properties-View/images/tag_d.jpgbin0 -> 914 bytes
-rw-r--r--Article-Properties-View/images/tag_e.jpgbin0 -> 909 bytes
-rw-r--r--Article-Properties-View/images/tag_f.jpgbin0 -> 893 bytes
-rw-r--r--Article-Properties-View/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Properties-View/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Properties-View/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Properties-View/properties-view.html412
-rw-r--r--Article-Properties-View/properties-view.jpgbin0 -> 14902 bytes
-rw-r--r--Article-Properties-View/propertyviewsample.zipbin0 -> 20637 bytes
-rw-r--r--Article-RCP-1/images/spin.pngbin0 -> 6441 bytes
-rw-r--r--Article-RCP-1/part1.zipbin0 -> 11867 bytes
-rw-r--r--Article-RCP-1/tutorial1.html382
-rw-r--r--Article-RCP-2/images/manifest-editor-overview.pngbin0 -> 38290 bytes
-rw-r--r--Article-RCP-2/part2.zipbin0 -> 11870 bytes
-rw-r--r--Article-RCP-2/tutorial2.html918
-rw-r--r--Article-RCP-3/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-RCP-3/images/complete.pngbin0 -> 10185 bytes
-rw-r--r--Article-RCP-3/images/help.pngbin0 -> 16221 bytes
-rw-r--r--Article-RCP-3/images/note.gifbin0 -> 1014 bytes
-rw-r--r--Article-RCP-3/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-RCP-3/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-RCP-3/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-RCP-3/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-RCP-3/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-RCP-3/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-RCP-3/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-RCP-3/tutorial3.html518
-rw-r--r--Article-Resource-deltas/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Resource-deltas/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Resource-deltas/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Resource-deltas/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Resource-deltas/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Resource-deltas/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Resource-deltas/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Resource-deltas/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Resource-deltas/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Resource-deltas/images/tree-before.jpgbin0 -> 6139 bytes
-rw-r--r--Article-Resource-deltas/images/tree-delta.jpgbin0 -> 7446 bytes
-rw-r--r--Article-Resource-deltas/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Resource-deltas/resource-deltas.html597
-rw-r--r--Article-Rule Modeling With EMF/BallPlacementRuleModel.zipbin0 -> 1343 bytes
-rw-r--r--Article-Rule Modeling With EMF/RuleMetaModel.zipbin0 -> 257182 bytes
-rw-r--r--Article-Rule Modeling With EMF/article.html614
-rw-r--r--Article-Rule Modeling With EMF/images/BallPlacementResult.gifbin0 -> 11574 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/ClassDiagram1.gifbin0 -> 11136 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/ClassDiagram2.gifbin0 -> 3985 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/Overall.gifbin0 -> 15095 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/RuleMetaModel.gifbin0 -> 21962 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/RuleModel.gifbin0 -> 16945 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Rule Modeling With EMF/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-SWT-Color-Model/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-SWT-Color-Model/about.xml24
-rw-r--r--Article-SWT-Color-Model/swt-color-model.htm346
-rw-r--r--Article-SWT-DND/DND-in-SWT.html1739
-rw-r--r--Article-SWT-DND/about.xml26
-rw-r--r--Article-SWT-DND/images/dnd1.gifbin0 -> 12482 bytes
-rw-r--r--Article-SWT-DND/images/idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-SWT-DND/images/image001.gifbin0 -> 12482 bytes
-rw-r--r--Article-SWT-DND/images/image002.gifbin0 -> 31216 bytes
-rw-r--r--Article-SWT-DND/images/image002.jpgbin0 -> 25326 bytes
-rw-r--r--Article-SWT-DND/images/image003.pngbin0 -> 290 bytes
-rw-r--r--Article-SWT-DND/images/image004.jpgbin0 -> 527 bytes
-rw-r--r--Article-SWT-DND/images/image005.GIFbin0 -> 947 bytes
-rw-r--r--Article-SWT-DND/images/image005.pngbin0 -> 351 bytes
-rw-r--r--Article-SWT-DND/images/image006.jpgbin0 -> 622 bytes
-rw-r--r--Article-SWT-DND/images/image007.pngbin0 -> 349 bytes
-rw-r--r--Article-SWT-DND/images/image008.jpgbin0 -> 632 bytes
-rw-r--r--Article-SWT-DND/images/image009.pngbin0 -> 244 bytes
-rw-r--r--Article-SWT-DND/images/image010.jpgbin0 -> 526 bytes
-rw-r--r--Article-SWT-Design-1/SWT-Design-1.html310
-rw-r--r--Article-SWT-Design-1/about.xml38
-rw-r--r--Article-SWT-Design-1/default_style.css11
-rw-r--r--Article-SWT-Design-1/idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-SWT-OpenGL/images/1W08-2.pngbin0 -> 70250 bytes
-rw-r--r--Article-SWT-OpenGL/images/3dchart4.pngbin0 -> 67234 bytes
-rw-r--r--Article-SWT-OpenGL/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-SWT-OpenGL/images/cylinder.pngbin0 -> 1724 bytes
-rw-r--r--Article-SWT-OpenGL/images/gl_command.pngbin0 -> 5495 bytes
-rw-r--r--Article-SWT-OpenGL/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-SWT-OpenGL/images/rotation.xcfbin0 -> 19216 bytes
-rw-r--r--Article-SWT-OpenGL/images/rotation3.pngbin0 -> 11484 bytes
-rw-r--r--Article-SWT-OpenGL/images/rotation4.pngbin0 -> 14316 bytes
-rw-r--r--Article-SWT-OpenGL/images/rotation5.pngbin0 -> 6899 bytes
-rw-r--r--Article-SWT-OpenGL/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-SWT-OpenGL/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-SWT-OpenGL/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-SWT-OpenGL/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-SWT-OpenGL/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-SWT-OpenGL/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-SWT-OpenGL/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-SWT-OpenGL/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-SWT-OpenGL/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-SWT-OpenGL/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-SWT-OpenGL/images/workbench2.pngbin0 -> 68746 bytes
-rw-r--r--Article-SWT-OpenGL/images/workbench3.pngbin0 -> 46790 bytes
-rw-r--r--Article-SWT-OpenGL/lib/demo_plugin.zipbin0 -> 34535 bytes
-rw-r--r--Article-SWT-OpenGL/opengl.css201
-rw-r--r--Article-SWT-OpenGL/opengl.html1248
-rw-r--r--Article-SWT-browser-widget/DocumentationViewer.java152
-rw-r--r--Article-SWT-browser-widget/about.xml15
-rw-r--r--Article-SWT-browser-widget/browser.html191
-rw-r--r--Article-SWT-browser-widget/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-SWT-browser-widget/images/help_browser.pngbin0 -> 45474 bytes
-rw-r--r--Article-SWT-browser-widget/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-SWT-browser-widget/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-SWT-browser-widget/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-SWT-browser-widget/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-SWT-browser-widget/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-SWT-browser-widget/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-SWT-browser-widget/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-SWT-browser-widget/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-SWT-browser-widget/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-SWT-browser-widget/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-SWT-browser-widget/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-SWT-graphics/SWT_graphics.html629
-rw-r--r--Article-SWT-graphics/about.xml33
-rw-r--r--Article-SWT-graphics/images/ArcClient.gifbin0 -> 1553 bytes
-rw-r--r--Article-SWT-graphics/images/ArcFilledClient.gifbin0 -> 1525 bytes
-rw-r--r--Article-SWT-graphics/images/Cheese_Complete.gifbin0 -> 29459 bytes
-rw-r--r--Article-SWT-graphics/images/ClippedTriangles.gifbin0 -> 14407 bytes
-rw-r--r--Article-SWT-graphics/images/GradientFillFalse.gifbin0 -> 2527 bytes
-rw-r--r--Article-SWT-graphics/images/GradientFillTrue.gifbin0 -> 2518 bytes
-rw-r--r--Article-SWT-graphics/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-SWT-graphics/images/ImageClient.jpgbin0 -> 6114 bytes
-rw-r--r--Article-SWT-graphics/images/ImageClientStretched.jpgbin0 -> 6476 bytes
-rw-r--r--Article-SWT-graphics/images/ImageClipped.jpgbin0 -> 9555 bytes
-rw-r--r--Article-SWT-graphics/images/LINE_DASH.gifbin0 -> 945 bytes
-rw-r--r--Article-SWT-graphics/images/LINE_DASHDOT.gifbin0 -> 957 bytes
-rw-r--r--Article-SWT-graphics/images/LINE_DASHDOTDOT.gifbin0 -> 967 bytes
-rw-r--r--Article-SWT-graphics/images/LINE_DOT.gifbin0 -> 962 bytes
-rw-r--r--Article-SWT-graphics/images/LineShapes.gifbin0 -> 1730 bytes
-rw-r--r--Article-SWT-graphics/images/Line_SOLID.gifbin0 -> 930 bytes
-rw-r--r--Article-SWT-graphics/images/OvalClient.gifbin0 -> 1495 bytes
-rw-r--r--Article-SWT-graphics/images/OvalFilledClient.gifbin0 -> 1476 bytes
-rw-r--r--Article-SWT-graphics/images/PolygonClient.gifbin0 -> 1487 bytes
-rw-r--r--Article-SWT-graphics/images/PolygonFillClient.gifbin0 -> 1501 bytes
-rw-r--r--Article-SWT-graphics/images/RectangleClient.gifbin0 -> 1567 bytes
-rw-r--r--Article-SWT-graphics/images/RectangleFillClient.gifbin0 -> 1483 bytes
-rw-r--r--Article-SWT-graphics/images/RectangleStrokeFill.gifbin0 -> 1586 bytes
-rw-r--r--Article-SWT-graphics/images/RoundedRectangleClient.gifbin0 -> 3059 bytes
-rw-r--r--Article-SWT-graphics/images/RoundedRectangleFilledClient.gifbin0 -> 1486 bytes
-rw-r--r--Article-SWT-graphics/images/ShellDrawnLine.gifbin0 -> 5034 bytes
-rw-r--r--Article-SWT-graphics/images/StringHelloWorld.gifbin0 -> 1952 bytes
-rw-r--r--Article-SWT-graphics/images/TextFlags.gifbin0 -> 13430 bytes
-rw-r--r--Article-SWT-graphics/images/TextHelloWorld.gifbin0 -> 1974 bytes
-rw-r--r--Article-SWT-graphics/images/TextHelloWorldTransparent.gifbin0 -> 13722 bytes
-rw-r--r--Article-SWT-graphics/images/Width_2.gifbin0 -> 940 bytes
-rw-r--r--Article-SWT-graphics/images/Width_4.gifbin0 -> 952 bytes
-rw-r--r--Article-SWT-graphics/images/XORFills.gifbin0 -> 2258 bytes
-rw-r--r--Article-SWT-graphics/images/default_style.css11
-rw-r--r--Article-SWT-graphics/images/image_lg_lines.gifbin0 -> 13615 bytes
-rw-r--r--Article-SWT-graphics/images/image_lg_orig.gifbin0 -> 13359 bytes
-rw-r--r--Article-SWT-graphics/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-SWT-graphics/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-SWT-graphics/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-SWT-graphics/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-SWT-graphics/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-SWT-graphics/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-SWT-graphics/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-SWT-graphics/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-SWT-graphics/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-SWT-graphics/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-SWT-graphics/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-SWT-images/graphics-resources.html1050
-rw-r--r--Article-SWT-images/images/AlphaImages.gifbin0 -> 12092 bytes
-rw-r--r--Article-SWT-images/images/AnimationFrames.gifbin0 -> 79733 bytes
-rw-r--r--Article-SWT-images/images/BlendedImage.gifbin0 -> 7884 bytes
-rw-r--r--Article-SWT-images/images/BlendedImageOnSplash.gifbin0 -> 90231 bytes
-rw-r--r--Article-SWT-images/images/ButonLogo.gifbin0 -> 20478 bytes
-rw-r--r--Article-SWT-images/images/CustomCursor.gifbin0 -> 5195 bytes
-rw-r--r--Article-SWT-images/images/DirectPalette.gifbin0 -> 3030 bytes
-rw-r--r--Article-SWT-images/images/DirectPalette_01.gifbin0 -> 3750 bytes
-rw-r--r--Article-SWT-images/images/DirectPalette_02.gifbin0 -> 3751 bytes
-rw-r--r--Article-SWT-images/images/EclipseBannerPic.gifbin0 -> 3674 bytes
-rw-r--r--Article-SWT-images/images/EclipseBannerPic.jpgbin0 -> 2011 bytes
-rw-r--r--Article-SWT-images/images/Fonts.gifbin0 -> 9579 bytes
-rw-r--r--Article-SWT-images/images/GraphicsEffects_01.JPGbin0 -> 48865 bytes
-rw-r--r--Article-SWT-images/images/Idea.gifbin0 -> 6842 bytes
-rw-r--r--Article-SWT-images/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-SWT-images/images/IdeaTransparency.gifbin0 -> 19778 bytes
-rw-r--r--Article-SWT-images/images/Idea_AndSWTText.gifbin0 -> 1189 bytes
-rw-r--r--Article-SWT-images/images/Idea_EclipseText.gifbin0 -> 1142 bytes
-rw-r--r--Article-SWT-images/images/Idea_HalfSize.gifbin0 -> 1533 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original.gifbin0 -> 7667 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_01.gifbin0 -> 5816 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_A.gifbin0 -> 7023 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_B.gifbin0 -> 6456 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_C.gifbin0 -> 6461 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_D.gifbin0 -> 6543 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_E.gifbin0 -> 6839 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_F.gifbin0 -> 6543 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_G.gifbin0 -> 7562 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_H.gifbin0 -> 6569 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_I.gifbin0 -> 6707 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_J.gifbin0 -> 6548 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_K.gifbin0 -> 6720 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_L.gifbin0 -> 6544 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_M.gifbin0 -> 6715 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_N.gifbin0 -> 6844 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_O.gifbin0 -> 6755 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_P.gifbin0 -> 7638 bytes
-rw-r--r--Article-SWT-images/images/Idea_Original_Q.gifbin0 -> 6053 bytes
-rw-r--r--Article-SWT-images/images/Idea_Pen.gifbin0 -> 3202 bytes
-rw-r--r--Article-SWT-images/images/Idea_SWT_Animation.gifbin0 -> 70705 bytes
-rw-r--r--Article-SWT-images/images/Idea_Transparent_DrawnOnCanvas.gifbin0 -> 11461 bytes
-rw-r--r--Article-SWT-images/images/Idea_animated.gifbin0 -> 11920 bytes
-rw-r--r--Article-SWT-images/images/Idea_transparent.jpgbin0 -> 2931 bytes
-rw-r--r--Article-SWT-images/images/ImageBlended.gifbin0 -> 13511 bytes
-rw-r--r--Article-SWT-images/images/ImageEffects.jpgbin0 -> 7281 bytes
-rw-r--r--Article-SWT-images/images/Image_NS.gifbin0 -> 882 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_E.gifbin0 -> 878 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_N.gifbin0 -> 882 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_NESW.gifbin0 -> 876 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_NW.gifbin0 -> 878 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_S.gifbin0 -> 882 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_SE.gifbin0 -> 879 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_SW.gifbin0 -> 878 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_W.gifbin0 -> 879 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_appstarting.gifbin0 -> 930 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_arrow.gifbin0 -> 905 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_busy.gifbin0 -> 918 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_cross.gifbin0 -> 880 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_hand.gifbin0 -> 914 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_help.gifbin0 -> 926 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_ibeam.gifbin0 -> 881 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_not.gifbin0 -> 917 bytes
-rw-r--r--Article-SWT-images/images/Image_cursor_sizeall.gifbin0 -> 892 bytes
-rw-r--r--Article-SWT-images/images/Image_size_NE.gifbin0 -> 879 bytes
-rw-r--r--Article-SWT-images/images/Imagecursor_uparrow.gifbin0 -> 878 bytes
-rw-r--r--Article-SWT-images/images/IntroductionRelativeIcon.gifbin0 -> 7815 bytes
-rw-r--r--Article-SWT-images/images/IveBeenDrawnOn.gifbin0 -> 20743 bytes
-rw-r--r--Article-SWT-images/images/LabelCanvasTransparent.gifbin0 -> 9121 bytes
-rw-r--r--Article-SWT-images/images/Note.gifbin0 -> 1014 bytes
-rw-r--r--Article-SWT-images/images/RedGreenImage.gifbin0 -> 930 bytes
-rw-r--r--Article-SWT-images/images/RelativeLogo.gifbin0 -> 8395 bytes
-rw-r--r--Article-SWT-images/images/ScaledGraphics.gifbin0 -> 34718 bytes
-rw-r--r--Article-SWT-images/images/ScaledImages.gifbin0 -> 134937 bytes
-rw-r--r--Article-SWT-images/images/ScaledImages_01.gifbin0 -> 38796 bytes
-rw-r--r--Article-SWT-images/images/ShellCursors.gifbin0 -> 10915 bytes
-rw-r--r--Article-SWT-images/images/SingleAlphaChannel.gifbin0 -> 27167 bytes
-rw-r--r--Article-SWT-images/images/TimesFont.gifbin0 -> 7050 bytes
-rw-r--r--Article-SWT-images/images/TransparentIdea.gifbin0 -> 17441 bytes
-rw-r--r--Article-SWT-images/images/javalogo.gifbin0 -> 2260 bytes
-rw-r--r--Article-SWT-images/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-SWT-images/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-SWT-images/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-SWT-images/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-SWT-images/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-SWT-images/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-SWT-images/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-TVT/eclipse_tvt.zipbin0 -> 46145 bytes
-rw-r--r--Article-TVT/how2TestI18n.html493
-rw-r--r--Article-TVT/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-TVT/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-TVT/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-TVT/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-TVT/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-TVT/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-TVT/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-TVT/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-TVT/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-TVT/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-TVT/images/tool.jpgbin0 -> 126083 bytes
-rw-r--r--Article-TVT/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-TVT/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Table-viewer/TableViewerExamplePlugin.zipbin0 -> 25942 bytes
-rw-r--r--Article-Table-viewer/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Table-viewer/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Table-viewer/images/tableViewer.gifbin0 -> 11232 bytes
-rw-r--r--Article-Table-viewer/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Table-viewer/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Table-viewer/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Table-viewer/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Table-viewer/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Table-viewer/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Table-viewer/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Table-viewer/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Table-viewer/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Table-viewer/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Table-viewer/table_viewer.html500
-rw-r--r--Article-UI-Guidelines/Contents.html5839
-rw-r--r--Article-UI-Guidelines/Index.html8
-rw-r--r--Article-UI-Guidelines/Toc.html218
-rw-r--r--Article-UI-Guidelines/default_style.css17
-rw-r--r--Article-UI-Guidelines/images/256palette.gifbin0 -> 11287 bytes
-rw-r--r--Article-UI-Guidelines/images/Idea.gifbin0 -> 7163 bytes
-rw-r--r--Article-UI-Guidelines/images/actionExamples.gifbin0 -> 80129 bytes
-rw-r--r--Article-UI-Guidelines/images/badHilight.gifbin0 -> 38153 bytes
-rw-r--r--Article-UI-Guidelines/images/badTooltips.gifbin0 -> 16492 bytes
-rw-r--r--Article-UI-Guidelines/images/badWizardInit.gifbin0 -> 12402 bytes
-rw-r--r--Article-UI-Guidelines/images/bp1.gifbin0 -> 41874 bytes
-rw-r--r--Article-UI-Guidelines/images/bp2.gifbin0 -> 43970 bytes
-rw-r--r--Article-UI-Guidelines/images/bp3.gifbin0 -> 42378 bytes
-rw-r--r--Article-UI-Guidelines/images/bp4.gifbin0 -> 47214 bytes
-rw-r--r--Article-UI-Guidelines/images/bp5.gifbin0 -> 44818 bytes
-rw-r--r--Article-UI-Guidelines/images/bp6.gifbin0 -> 48929 bytes
-rw-r--r--Article-UI-Guidelines/images/cell1.gifbin0 -> 288 bytes
-rw-r--r--Article-UI-Guidelines/images/cell2.gifbin0 -> 3412 bytes
-rw-r--r--Article-UI-Guidelines/images/cell3.gifbin0 -> 276 bytes
-rw-r--r--Article-UI-Guidelines/images/cellTableEditor.gifbin0 -> 31810 bytes
-rw-r--r--Article-UI-Guidelines/images/dirtyEditor.gifbin0 -> 20561 bytes
-rw-r--r--Article-UI-Guidelines/images/disabledcolors.gifbin0 -> 1124 bytes
-rw-r--r--Article-UI-Guidelines/images/editorTitles.gifbin0 -> 7770 bytes
-rw-r--r--Article-UI-Guidelines/images/enabledcolors.gifbin0 -> 4475 bytes
-rw-r--r--Article-UI-Guidelines/images/errorsInOutline.gifbin0 -> 14744 bytes
-rw-r--r--Article-UI-Guidelines/images/fileDeletedDialog.gifbin0 -> 16401 bytes
-rw-r--r--Article-UI-Guidelines/images/flatlook1.gifbin0 -> 64142 bytes
-rw-r--r--Article-UI-Guidelines/images/flatlook2.gifbin0 -> 4244 bytes
-rw-r--r--Article-UI-Guidelines/images/flatlook3.gifbin0 -> 28337 bytes
-rw-r--r--Article-UI-Guidelines/images/flatlook4.gifbin0 -> 15874 bytes
-rw-r--r--Article-UI-Guidelines/images/flatlook5.gifbin0 -> 17162 bytes
-rw-r--r--Article-UI-Guidelines/images/flatlook6.gifbin0 -> 41600 bytes
-rw-r--r--Article-UI-Guidelines/images/flatlook7.gifbin0 -> 10090 bytes
-rw-r--r--Article-UI-Guidelines/images/flatlook8.gifbin0 -> 5954 bytes
-rw-r--r--Article-UI-Guidelines/images/flatlook9.gifbin0 -> 16190 bytes
-rw-r--r--Article-UI-Guidelines/images/folderSelection.gifbin0 -> 93567 bytes
-rw-r--r--Article-UI-Guidelines/images/goodParentCreation.gifbin0 -> 12741 bytes
-rw-r--r--Article-UI-Guidelines/images/goodTooltips.gifbin0 -> 7981 bytes
-rw-r--r--Article-UI-Guidelines/images/goodWizardInit.gifbin0 -> 10768 bytes
-rw-r--r--Article-UI-Guidelines/images/guidelineCheckbox.gifbin0 -> 87 bytes
-rw-r--r--Article-UI-Guidelines/images/guidelineIndicator.gifbin0 -> 83 bytes
-rw-r--r--Article-UI-Guidelines/images/icon_types.gifbin0 -> 19275 bytes
-rw-r--r--Article-UI-Guidelines/images/iconposition_main.gifbin0 -> 20302 bytes
-rw-r--r--Article-UI-Guidelines/images/impready_folderstructure.gifbin0 -> 5504 bytes
-rw-r--r--Article-UI-Guidelines/images/metaphor_concepts.gifbin0 -> 21137 bytes
-rw-r--r--Article-UI-Guidelines/images/overlay_realestate.gifbin0 -> 1035 bytes
-rw-r--r--Article-UI-Guidelines/images/ovr_auxiliary.gifbin0 -> 2237 bytes
-rw-r--r--Article-UI-Guidelines/images/ovr_java.gifbin0 -> 3997 bytes
-rw-r--r--Article-UI-Guidelines/images/ovr_java_sample1.gifbin0 -> 5389 bytes
-rw-r--r--Article-UI-Guidelines/images/ovr_projectnature.gifbin0 -> 2276 bytes
-rw-r--r--Article-UI-Guidelines/images/ovr_projectnature_sample.gifbin0 -> 3758 bytes
-rw-r--r--Article-UI-Guidelines/images/ovr_versioncontrol.gifbin0 -> 2547 bytes
-rw-r--r--Article-UI-Guidelines/images/ovr_versioncontrol_cvs.gifbin0 -> 3267 bytes
-rw-r--r--Article-UI-Guidelines/images/ovr_versioncontrol_cvs_samp.gifbin0 -> 5630 bytes
-rw-r--r--Article-UI-Guidelines/images/perspective_realestate.gifbin0 -> 1516 bytes
-rw-r--r--Article-UI-Guidelines/images/perspective_specs.gifbin0 -> 7436 bytes
-rw-r--r--Article-UI-Guidelines/images/run_co.gifbin0 -> 116 bytes
-rw-r--r--Article-UI-Guidelines/images/showViewMenu.gifbin0 -> 29710 bytes
-rw-r--r--Article-UI-Guidelines/images/slushBucket.gifbin0 -> 31962 bytes
-rw-r--r--Article-UI-Guidelines/images/synch_co.gifbin0 -> 110 bytes
-rw-r--r--Article-UI-Guidelines/images/titlebar_specs.gifbin0 -> 5262 bytes
-rw-r--r--Article-UI-Guidelines/images/toolbar_realestate.gifbin0 -> 1469 bytes
-rw-r--r--Article-UI-Guidelines/images/toolbar_specs.gifbin0 -> 9769 bytes
-rw-r--r--Article-UI-Guidelines/images/tooltipCaps.gifbin0 -> 11297 bytes
-rw-r--r--Article-UI-Guidelines/images/treeview_specs.gifbin0 -> 5500 bytes
-rw-r--r--Article-UI-Guidelines/images/view_realestate.gifbin0 -> 1492 bytes
-rw-r--r--Article-UI-Guidelines/images/wizardAppearance.gifbin0 -> 16676 bytes
-rw-r--r--Article-UI-Guidelines/images/wizardErrorMsgs.gifbin0 -> 24569 bytes
-rw-r--r--Article-UI-Guidelines/images/wizardErrorMsgs2.gifbin0 -> 11609 bytes
-rw-r--r--Article-UI-Guidelines/images/wizardFieldPopulation.gifbin0 -> 25649 bytes
-rw-r--r--Article-UI-Guidelines/images/wizardMsgs.gifbin0 -> 6705 bytes
-rw-r--r--Article-UI-Guidelines/images/wizban.gifbin0 -> 6613 bytes
-rw-r--r--Article-UI-Guidelines/images/wizban183.gifbin0 -> 8274 bytes
-rw-r--r--Article-UI-Guidelines/images/wizbans.gifbin0 -> 8575 bytes
-rw-r--r--Article-UI-Guidelines/images/workbench_decomposed.gifbin0 -> 65302 bytes
-rw-r--r--Article-UI-Guidelines/v200202/Contents.html3887
-rw-r--r--Article-UI-Guidelines/v200202/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-UI-Guidelines/v200202/Index.html10
-rw-r--r--Article-UI-Guidelines/v200202/Toc.html162
-rw-r--r--Article-UI-Guidelines/v200202/actionExamples.jpgbin0 -> 58510 bytes
-rw-r--r--Article-UI-Guidelines/v200202/badHilight.jpgbin0 -> 123041 bytes
-rw-r--r--Article-UI-Guidelines/v200202/badTooltips.jpgbin0 -> 42978 bytes
-rw-r--r--Article-UI-Guidelines/v200202/badWizardInit.jpgbin0 -> 36320 bytes
-rw-r--r--Article-UI-Guidelines/v200202/cell1.jpgbin0 -> 1362 bytes
-rw-r--r--Article-UI-Guidelines/v200202/cell2.jpgbin0 -> 2210 bytes
-rw-r--r--Article-UI-Guidelines/v200202/cell3.jpgbin0 -> 1301 bytes
-rw-r--r--Article-UI-Guidelines/v200202/cellTableEditor.jpgbin0 -> 21858 bytes
-rw-r--r--Article-UI-Guidelines/v200202/default_style.css11
-rw-r--r--Article-UI-Guidelines/v200202/dirtyEditor.jpgbin0 -> 72691 bytes
-rw-r--r--Article-UI-Guidelines/v200202/editorTitles.jpgbin0 -> 22301 bytes
-rw-r--r--Article-UI-Guidelines/v200202/errorsInOutline.jpgbin0 -> 53089 bytes
-rw-r--r--Article-UI-Guidelines/v200202/fileDeletedDialog.jpgbin0 -> 39046 bytes
-rw-r--r--Article-UI-Guidelines/v200202/folderSelection.jpgbin0 -> 279122 bytes
-rw-r--r--Article-UI-Guidelines/v200202/goodParentCreation.jpgbin0 -> 50982 bytes
-rw-r--r--Article-UI-Guidelines/v200202/goodTooltips.jpgbin0 -> 57201 bytes
-rw-r--r--Article-UI-Guidelines/v200202/goodWizardInit.jpgbin0 -> 33050 bytes
-rw-r--r--Article-UI-Guidelines/v200202/guidelineCheckbox.jpgbin0 -> 2654 bytes
-rw-r--r--Article-UI-Guidelines/v200202/guidelineIndicator.gifbin0 -> 83 bytes
-rw-r--r--Article-UI-Guidelines/v200202/showViewMenu.jpgbin0 -> 170443 bytes
-rw-r--r--Article-UI-Guidelines/v200202/slushBucket.jpgbin0 -> 28643 bytes
-rw-r--r--Article-UI-Guidelines/v200202/tooltipCaps.jpgbin0 -> 30396 bytes
-rw-r--r--Article-UI-Guidelines/v200202/wizardAppearance.jpgbin0 -> 56185 bytes
-rw-r--r--Article-UI-Guidelines/v200202/wizardErrorMsgs.jpgbin0 -> 120906 bytes
-rw-r--r--Article-UI-Guidelines/v200202/wizardErrorMsgs2.jpgbin0 -> 56330 bytes
-rw-r--r--Article-UI-Guidelines/v200202/wizardFieldPopulation.jpgbin0 -> 88886 bytes
-rw-r--r--Article-UI-Guidelines/v200202/wizardMsgs.jpgbin0 -> 22518 bytes
-rw-r--r--Article-UI-Guidelines/v200202/workbench_decomposed.jpgbin0 -> 55919 bytes
-rw-r--r--Article-UI-Workbench/images/LayoutPart_hierarchy.pngbin0 -> 7493 bytes
-rw-r--r--Article-UI-Workbench/images/PartSashContainer.pngbin0 -> 7006 bytes
-rw-r--r--Article-UI-Workbench/images/PartStack.pngbin0 -> 4800 bytes
-rw-r--r--Article-UI-Workbench/images/action_bar_flow.pngbin0 -> 21585 bytes
-rw-r--r--Article-UI-Workbench/images/action_set_formula.pngbin0 -> 807 bytes
-rw-r--r--Article-UI-Workbench/images/anatomy_of_a_part.pngbin0 -> 6203 bytes
-rw-r--r--Article-UI-Workbench/images/drag_regions.pngbin0 -> 119057 bytes
-rw-r--r--Article-UI-Workbench/images/example_LayoutTree.pngbin0 -> 12016 bytes
-rw-r--r--Article-UI-Workbench/images/left_arrow.pngbin0 -> 248 bytes
-rw-r--r--Article-UI-Workbench/images/part_creation_msc.pngbin0 -> 28578 bytes
-rw-r--r--Article-UI-Workbench/images/part_states.pngbin0 -> 13834 bytes
-rw-r--r--Article-UI-Workbench/images/perspective1.pngbin0 -> 44076 bytes
-rw-r--r--Article-UI-Workbench/images/perspective1_2_instances.pngbin0 -> 23547 bytes
-rw-r--r--Article-UI-Workbench/images/perspective2.pngbin0 -> 37110 bytes
-rw-r--r--Article-UI-Workbench/images/right_arrow.pngbin0 -> 245 bytes
-rw-r--r--Article-UI-Workbench/images/what_you_see.pngbin0 -> 81123 bytes
-rw-r--r--Article-UI-Workbench/images/workbench_high_level.pngbin0 -> 9113 bytes
-rw-r--r--Article-UI-Workbench/workbench.html1112
-rw-r--r--Article-Understanding Layouts/Understanding Layouts.htm3882
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/default_style.css11
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/filelist.xml84
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/header.htm69
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image001.pngbin0 -> 9166 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image002.jpgbin0 -> 21962 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image003.pngbin0 -> 978 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image004.jpgbin0 -> 3305 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image005.pngbin0 -> 1081 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image006.jpgbin0 -> 3285 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image007.pngbin0 -> 888 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image008.jpgbin0 -> 2836 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image009.pngbin0 -> 1004 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image010.jpgbin0 -> 3614 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image011.pngbin0 -> 985 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image012.jpgbin0 -> 3024 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image013.pngbin0 -> 1030 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image014.jpgbin0 -> 4298 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image015.pngbin0 -> 2084 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image016.jpgbin0 -> 7423 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image017.pngbin0 -> 957 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image018.jpgbin0 -> 3305 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image019.pngbin0 -> 1062 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image020.jpgbin0 -> 3344 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image021.jpgbin0 -> 3305 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image022.pngbin0 -> 982 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image023.jpgbin0 -> 3083 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image024.pngbin0 -> 1018 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image025.jpgbin0 -> 3003 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image026.pngbin0 -> 1131 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image027.jpgbin0 -> 4046 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image028.pngbin0 -> 956 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image029.jpgbin0 -> 3266 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image030.pngbin0 -> 991 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image031.jpgbin0 -> 3104 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image032.pngbin0 -> 1039 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image033.jpgbin0 -> 3750 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image034.pngbin0 -> 1335 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image035.jpgbin0 -> 4284 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image036.pngbin0 -> 1260 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image037.jpgbin0 -> 4396 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image038.pngbin0 -> 1214 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image039.jpgbin0 -> 4450 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image040.pngbin0 -> 3220 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image041.jpgbin0 -> 8370 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image042.pngbin0 -> 1352 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image043.jpgbin0 -> 4587 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image044.pngbin0 -> 1369 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image045.jpgbin0 -> 4559 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image046.pngbin0 -> 1368 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image047.jpgbin0 -> 4570 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image048.pngbin0 -> 1366 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image049.jpgbin0 -> 4651 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image050.pngbin0 -> 1799 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image051.jpgbin0 -> 4570 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image052.pngbin0 -> 1776 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image053.jpgbin0 -> 4805 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image054.pngbin0 -> 1648 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image055.jpgbin0 -> 4459 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image056.pngbin0 -> 1832 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image057.jpgbin0 -> 4693 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image058.jpgbin0 -> 4693 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image059.pngbin0 -> 1992 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image060.jpgbin0 -> 4944 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image061.pngbin0 -> 1399 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image062.jpgbin0 -> 5285 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image063.pngbin0 -> 785 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image064.jpgbin0 -> 2317 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image065.pngbin0 -> 883 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image066.jpgbin0 -> 3643 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image067.jpgbin0 -> 4450 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image068.pngbin0 -> 1308 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image069.jpgbin0 -> 4635 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image070.gifbin0 -> 7016 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image071.pngbin0 -> 11638 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image072.jpgbin0 -> 21205 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image073.pngbin0 -> 12303 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image074.jpgbin0 -> 23383 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image075.pngbin0 -> 1510 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image076.jpgbin0 -> 5694 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image077.pngbin0 -> 1743 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/image078.jpgbin0 -> 6677 bytes
-rw-r--r--Article-Understanding Layouts/Understanding Layouts_files/oledata.msobin0 -> 18944 bytes
-rw-r--r--Article-Update/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Update/images/category-def.jpgbin0 -> 32256 bytes
-rw-r--r--Article-Update/images/copyright.jpgbin0 -> 29913 bytes
-rw-r--r--Article-Update/images/explorer.jpgbin0 -> 23642 bytes
-rw-r--r--Article-Update/images/feature-desc.jpgbin0 -> 33357 bytes
-rw-r--r--Article-Update/images/feature-preview.jpgbin0 -> 49991 bytes
-rw-r--r--Article-Update/images/feature-refs.jpgbin0 -> 37022 bytes
-rw-r--r--Article-Update/images/history.jpgbin0 -> 96358 bytes
-rw-r--r--Article-Update/images/license.jpgbin0 -> 31735 bytes
-rw-r--r--Article-Update/images/one-click2.jpgbin0 -> 81816 bytes
-rw-r--r--Article-Update/images/propsheet.jpgbin0 -> 15098 bytes
-rw-r--r--Article-Update/images/site_obj.gifbin0 -> 162 bytes
-rw-r--r--Article-Update/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Update/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Update/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Update/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Update/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Update/images/url.jpgbin0 -> 58005 bytes
-rw-r--r--Article-Update/keeping-up-to-date.html707
-rw-r--r--Article-Using EMF/Test.familytree19
-rw-r--r--Article-Using EMF/family.mdl583
-rw-r--r--Article-Using EMF/family1.zipbin0 -> 1931 bytes
-rw-r--r--Article-Using EMF/family2.zipbin0 -> 137884 bytes
-rw-r--r--Article-Using EMF/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Using EMF/images/customized.JPGbin0 -> 85585 bytes
-rw-r--r--Article-Using EMF/images/customized.bmpbin0 -> 1213686 bytes
-rw-r--r--Article-Using EMF/images/familytree.JPGbin0 -> 18805 bytes
-rw-r--r--Article-Using EMF/images/labels.JPGbin0 -> 10500 bytes
-rw-r--r--Article-Using EMF/images/labels.bmpbin0 -> 109030 bytes
-rw-r--r--Article-Using EMF/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-Using EMF/images/model.bmpbin0 -> 450522 bytes
-rw-r--r--Article-Using EMF/images/sample.JPGbin0 -> 95228 bytes
-rw-r--r--Article-Using EMF/images/sample.bmpbin0 -> 1449670 bytes
-rw-r--r--Article-Using EMF/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-Using EMF/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-Using EMF/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-Using EMF/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-Using EMF/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-Using EMF/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-Using EMF/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-Using EMF/images/testdata.JPGbin0 -> 83820 bytes
-rw-r--r--Article-Using EMF/images/testdata.bmpbin0 -> 1113334 bytes
-rw-r--r--Article-Using EMF/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Using EMF/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Using EMF/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-Using EMF/using-emf.html504
-rw-r--r--Article-Using Images In Eclipse/Using Images In Eclipse.html355
-rw-r--r--Article-Using Images In Eclipse/history/Using Images In Eclipse_v1.0.htm363
-rw-r--r--Article-VE-Custom-Widget/customwidget.html2724
-rw-r--r--Article-VE-Custom-Widget/customwidgetexample.zipbin0 -> 869556 bytes
-rw-r--r--Article-VE-Custom-Widget/images/CheckOutAsProject.pngbin0 -> 13697 bytes
-rw-r--r--Article-VE-Custom-Widget/images/CreatePluginWizard.pngbin0 -> 19251 bytes
-rw-r--r--Article-VE-Custom-Widget/images/CustomPalette.pngbin0 -> 32059 bytes
-rw-r--r--Article-VE-Custom-Widget/images/CustomPrompterContainer.pngbin0 -> 41902 bytes
-rw-r--r--Article-VE-Custom-Widget/images/CustomTextEditorDialog.pngbin0 -> 78604 bytes
-rw-r--r--Article-VE-Custom-Widget/images/CustomWidget.pngbin0 -> 3606 bytes
-rw-r--r--Article-VE-Custom-Widget/images/CustomWidgetPackage.pngbin0 -> 49671 bytes
-rw-r--r--Article-VE-Custom-Widget/images/EventsMenuAfter.pngbin0 -> 19060 bytes
-rw-r--r--Article-VE-Custom-Widget/images/GraphicalEditPart.pngbin0 -> 7069 bytes
-rw-r--r--Article-VE-Custom-Widget/images/IconsFolder.pngbin0 -> 8455 bytes
-rw-r--r--Article-VE-Custom-Widget/images/JARExport.pngbin0 -> 20347 bytes
-rw-r--r--Article-VE-Custom-Widget/images/JARdiagram.pngbin0 -> 126242 bytes
-rw-r--r--Article-VE-Custom-Widget/images/LaunchConfig.pngbin0 -> 16257 bytes
-rw-r--r--Article-VE-Custom-Widget/images/NewPalette.pngbin0 -> 8151 bytes
-rw-r--r--Article-VE-Custom-Widget/images/OriginalEventsMenu.pngbin0 -> 17561 bytes
-rw-r--r--Article-VE-Custom-Widget/images/OriginalGraphicalEditPart.pngbin0 -> 5996 bytes
-rw-r--r--Article-VE-Custom-Widget/images/OriginalPalette.pngbin0 -> 6685 bytes
-rw-r--r--Article-VE-Custom-Widget/images/OriginalTextProperty.pngbin0 -> 2062 bytes
-rw-r--r--Article-VE-Custom-Widget/images/OriginalTypeProperty.pngbin0 -> 2292 bytes
-rw-r--r--Article-VE-Custom-Widget/images/OverrideFileStructure.pngbin0 -> 13565 bytes
-rw-r--r--Article-VE-Custom-Widget/images/PreReqPlugins.pngbin0 -> 9211 bytes
-rw-r--r--Article-VE-Custom-Widget/images/RepositoriesView.pngbin0 -> 9131 bytes
-rw-r--r--Article-VE-Custom-Widget/images/RuintimeLibraryPluginName.pngbin0 -> 6019 bytes
-rw-r--r--Article-VE-Custom-Widget/images/RuntimeLibraryPluginName.jpgbin0 -> 12875 bytes
-rw-r--r--Article-VE-Custom-Widget/images/TestProjectBuildPath.pngbin0 -> 9323 bytes
-rw-r--r--Article-VE-Custom-Widget/images/TextCurrentValue.pngbin0 -> 2754 bytes
-rw-r--r--Article-VE-Custom-Widget/images/TextPropertyCellEditor.pngbin0 -> 1849 bytes
-rw-r--r--Article-VE-Custom-Widget/images/TextPropertyDisplayed.pngbin0 -> 2196 bytes
-rw-r--r--Article-VE-Custom-Widget/images/TypeCodeGeneration.pngbin0 -> 32670 bytes
-rw-r--r--Article-VE-Custom-Widget/images/TypePropertyCellEditor.pngbin0 -> 3494 bytes
-rw-r--r--Article-VE-Custom-Widget/images/TypePropertyLabelProvider.pngbin0 -> 2397 bytes
-rw-r--r--Article-VE-Custom-Widget/images/custom.gifbin0 -> 582 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/editor_extension.jpgbin0 -> 176281 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/struts-config_1_0.pngbin0 -> 12275 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/struts-config_1_1.pngbin0 -> 18766 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/struts-config_1_2.pngbin0 -> 19341 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/strutsconfig.pngbin0 -> 58540 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/thumb-editor_extension.jpgbin0 -> 111708 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/thumb-struts-config_1_0.pngbin0 -> 4960 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/thumb-struts-config_1_1.pngbin0 -> 7957 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/thumb-struts-config_1_2.pngbin0 -> 8183 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/thumb-strutsconfig.pngbin0 -> 27061 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-WTP-Persisting-EMF/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-WTP-Persisting-EMF/persisting.html475
-rw-r--r--Article-WTP-Persisting-EMF/strutsbox.strutsconfig.zipbin0 -> 337572 bytes
-rw-r--r--Article-Workbench-DND/drag_drop.html620
-rw-r--r--Article-Workbench-DND/gadgetsrc.zipbin0 -> 13411 bytes
-rw-r--r--Article-Workbench-DND/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Workbench-DND/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-Workbench-DND/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget.htm6632
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixA.htm10017
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixB.htm198
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixC.htm313
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixD.htm317
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE.htm1517
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE_files/filelist.xml5
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE_files/header.htm66
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/default_style.css11
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/filelist.xml14
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/header.htm69
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/image001.pngbin0 -> 581 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/image002.jpgbin0 -> 1069 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/image003.pngbin0 -> 894 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/image004.jpgbin0 -> 2562 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/image005.pngbin0 -> 4119 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/image006.jpgbin0 -> 21138 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/image007.pngbin0 -> 2611 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/image008.jpgbin0 -> 2930 bytes
-rw-r--r--Article-Writing Your Own Widget/Writing Your Own Widget_files/oledata.msobin0 -> 5120 bytes
-rw-r--r--Article-Your First Plug-in/YourFirstPlugin.html425
-rw-r--r--Article-Your First Plug-in/history/Your First Plug-in.html423
-rw-r--r--Article-small-cup-of-swt/FileDialogMain.java24
-rw-r--r--Article-small-cup-of-swt/HelloWorld.java35
-rw-r--r--Article-small-cup-of-swt/OkButton.java27
-rw-r--r--Article-small-cup-of-swt/SipResize.java28
-rw-r--r--Article-small-cup-of-swt/SmallDialog.java30
-rw-r--r--Article-small-cup-of-swt/SmartMinimize.java22
-rw-r--r--Article-small-cup-of-swt/StylusHold.java28
-rw-r--r--Article-small-cup-of-swt/class_load_j2me_cldc.txt89
-rw-r--r--Article-small-cup-of-swt/class_load_j2se.txt240
-rw-r--r--Article-small-cup-of-swt/images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Article-small-cup-of-swt/images/ant_script.pngbin0 -> 33833 bytes
-rw-r--r--Article-small-cup-of-swt/images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--Article-small-cup-of-swt/images/ppc01.pngbin0 -> 7676 bytes
-rw-r--r--Article-small-cup-of-swt/images/ppc02.pngbin0 -> 3425 bytes
-rw-r--r--Article-small-cup-of-swt/images/ppc03.pngbin0 -> 5004 bytes
-rw-r--r--Article-small-cup-of-swt/images/ppc04.pngbin0 -> 6219 bytes
-rw-r--r--Article-small-cup-of-swt/images/ppc05.pngbin0 -> 3415 bytes
-rw-r--r--Article-small-cup-of-swt/images/ppc06.pngbin0 -> 3491 bytes
-rw-r--r--Article-small-cup-of-swt/images/ppc07.pngbin0 -> 1863 bytes
-rw-r--r--Article-small-cup-of-swt/images/ppc08.pngbin0 -> 1872 bytes
-rw-r--r--Article-small-cup-of-swt/images/profiles.gifbin0 -> 3396 bytes
-rw-r--r--Article-small-cup-of-swt/images/profiles.pngbin0 -> 2752 bytes
-rw-r--r--Article-small-cup-of-swt/images/swtjar.pngbin0 -> 5527 bytes
-rw-r--r--Article-small-cup-of-swt/images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--Article-small-cup-of-swt/images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--Article-small-cup-of-swt/images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--Article-small-cup-of-swt/images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--Article-small-cup-of-swt/images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--Article-small-cup-of-swt/images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--Article-small-cup-of-swt/images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--Article-small-cup-of-swt/images/tip.gifbin0 -> 406 bytes
-rw-r--r--Article-small-cup-of-swt/images/tryit.gifbin0 -> 309 bytes
-rw-r--r--Article-small-cup-of-swt/images/win_only.gifbin0 -> 221 bytes
-rw-r--r--Article-small-cup-of-swt/pocket-PC.html799
-rw-r--r--GettingStartedWithSWT/swt-getting-started.html117
-rw-r--r--GettingStartedWithSWT/swt-style-bits.html1302
-rw-r--r--GettingStartedWithSWT/swt-widget-hierarchy.html800
-rw-r--r--Online Help/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--Online Help/final.jpgbin0 -> 46096 bytes
-rw-r--r--Online Help/final.zipbin0 -> 6894 bytes
-rw-r--r--Online Help/help1.htm470
-rw-r--r--Online Help/initialstructure.zipbin0 -> 6894 bytes
-rw-r--r--Online Help/readme.txt12
-rw-r--r--Online Help/toplevel.jpgbin0 -> 5456 bytes
-rw-r--r--PropertyContribution.html52
-rw-r--r--SolvingTheSoftwareParadox.html296
-rw-r--r--StyledText 1/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--StyledText 1/Image0.gifbin0 -> 1996 bytes
-rw-r--r--StyledText 1/Image1.gifbin0 -> 2010 bytes
-rw-r--r--StyledText 1/Image2.gifbin0 -> 1886 bytes
-rw-r--r--StyledText 1/Image3.gifbin0 -> 2066 bytes
-rw-r--r--StyledText 1/Image4.gifbin0 -> 2019 bytes
-rw-r--r--StyledText 1/Image5.gifbin0 -> 2037 bytes
-rw-r--r--StyledText 1/Image6.gifbin0 -> 2002 bytes
-rw-r--r--StyledText 1/TextChanges.gifbin0 -> 13592 bytes
-rw-r--r--StyledText 1/article1.html957
-rw-r--r--StyledText 2/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--StyledText 2/Image8.gifbin0 -> 7728 bytes
-rw-r--r--StyledText 2/StyledTextContentSpec.java976
-rw-r--r--StyledText 2/TextChanges.gifbin0 -> 13029 bytes
-rw-r--r--StyledText 2/TextUpdate.gifbin0 -> 11618 bytes
-rw-r--r--StyledText 2/article2.html829
-rw-r--r--ToolIntegration/ToolIntegration.html417
-rw-r--r--ToolIntegration/images/currentToolIntegration.gifbin0 -> 58682 bytes
-rw-r--r--ToolIntegration/images/eclipseOverview.gifbin0 -> 84809 bytes
-rw-r--r--ToolIntegration/images/image004.gifbin0 -> 62093 bytes
-rw-r--r--ToolIntegration/images/image007.gifbin0 -> 213 bytes
-rw-r--r--ToolIntegration/images/image008.gifbin0 -> 260 bytes
-rw-r--r--ToolIntegration/images/image009.gifbin0 -> 276 bytes
-rw-r--r--ToolIntegration/images/image010.gifbin0 -> 276 bytes
-rw-r--r--ToolIntegration/images/pressures.gifbin0 -> 119772 bytes
-rw-r--r--ToolIntegration/images/problemSpace.gifbin0 -> 46649 bytes
-rw-r--r--ToolIntegration/images/webTransaction.gifbin0 -> 41119 bytes
-rw-r--r--ToolIntegration/images/workbenchIntegration.gifbin0 -> 68188 bytes
-rw-r--r--article-template.zipbin0 -> 12649 bytes
-rw-r--r--contributing.html127
-rw-r--r--images/Adarrow.gifbin0 -> 857 bytes
-rw-r--r--images/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--images/howto_banner.jpgbin0 -> 9877 bytes
-rw-r--r--images/htmltoolbar.jpgbin0 -> 39205 bytes
-rw-r--r--images/linux_only.gifbin0 -> 174 bytes
-rw-r--r--images/markers.jpgbin0 -> 190691 bytes
-rw-r--r--images/normaltoolbar.jpgbin0 -> 24853 bytes
-rw-r--r--images/note.gifbin0 -> 1014 bytes
-rw-r--r--images/notifiers.gifbin0 -> 7404 bytes
-rw-r--r--images/srctoolbar.jpgbin0 -> 38142 bytes
-rw-r--r--images/tag_1.gifbin0 -> 150 bytes
-rw-r--r--images/tag_2.gifbin0 -> 165 bytes
-rw-r--r--images/tag_3.gifbin0 -> 166 bytes
-rw-r--r--images/tag_4.gifbin0 -> 159 bytes
-rw-r--r--images/tag_5.gifbin0 -> 166 bytes
-rw-r--r--images/tag_6.gifbin0 -> 168 bytes
-rw-r--r--images/tag_7.gifbin0 -> 160 bytes
-rw-r--r--images/tip.gifbin0 -> 406 bytes
-rw-r--r--images/tryit.gifbin0 -> 309 bytes
-rw-r--r--images/win_only.gifbin0 -> 221 bytes
-rw-r--r--index.html21
-rw-r--r--index.php2
-rw-r--r--main.html1015
-rw-r--r--preferences/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--preferences/badwordpreference.jpgbin0 -> 35650 bytes
-rw-r--r--preferences/colorpreference.jpgbin0 -> 33397 bytes
-rw-r--r--preferences/default_style.css11
-rw-r--r--preferences/preferences.htm345
-rw-r--r--preferences/preferences.zipbin0 -> 4575 bytes
-rw-r--r--preferences/readme.txt12
-rw-r--r--preferences/tag_1.gifbin0 -> 150 bytes
-rw-r--r--preferences/tag_2.gifbin0 -> 165 bytes
-rw-r--r--preferences/tag_3.gifbin0 -> 166 bytes
-rw-r--r--preferences/tree.jpgbin0 -> 38331 bytes
-rw-r--r--product-guide/TryIt.gifbin0 -> 309 bytes
-rw-r--r--product-guide/default_style.css12
-rw-r--r--product-guide/final.jpgbin0 -> 153566 bytes
-rw-r--r--product-guide/guide.html854
-rw-r--r--product-guide/idea.jpgbin0 -> 5102 bytes
-rw-r--r--product-guide/linux_only.gifbin0 -> 174 bytes
-rw-r--r--product-guide/tip.gifbin0 -> 406 bytes
-rw-r--r--product-guide/win_only.gifbin0 -> 221 bytes
-rw-r--r--swt-design-2/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--swt-design-2/LeakExample.java.htm130
-rw-r--r--swt-design-2/Sleak.java.htm274
-rw-r--r--swt-design-2/default_style.css11
-rw-r--r--swt-design-2/sleak.1.gifbin0 -> 3479 bytes
-rw-r--r--swt-design-2/sleak.2.gifbin0 -> 2949 bytes
-rw-r--r--swt-design-2/sleak.3.gifbin0 -> 3283 bytes
-rw-r--r--swt-design-2/sleak.4.gifbin0 -> 3388 bytes
-rw-r--r--swt-design-2/sleak.5.gifbin0 -> 3461 bytes
-rw-r--r--swt-design-2/sleak.6.gifbin0 -> 3554 bytes
-rw-r--r--swt-design-2/sleak.7.gifbin0 -> 8657 bytes
-rw-r--r--swt-design-2/sleak.8.gifbin0 -> 3548 bytes
-rw-r--r--swt-design-2/sleak.htm225
-rw-r--r--swt-design-2/swt-design-2.html526
-rw-r--r--update_landing_page.php42
-rw-r--r--using-perspectives/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--using-perspectives/PerspectiveArticle.html822
-rw-r--r--using-perspectives/TestPerspective.jpgbin0 -> 92348 bytes
-rw-r--r--using-perspectives/TestPerspectiveSketch.jpgbin0 -> 83475 bytes
-rw-r--r--using-perspectives/default_style.css11
-rw-r--r--using-perspectives/workbench_decomposed.jpgbin0 -> 66773 bytes
-rw-r--r--viewArticle/Idea.jpgbin0 -> 5102 bytes
-rw-r--r--viewArticle/LabelView.jpgbin0 -> 57258 bytes
-rw-r--r--viewArticle/ListenerView.jpgbin0 -> 68794 bytes
-rw-r--r--viewArticle/ViewArticle2.html1212
-rw-r--r--viewArticle/WordView.jpgbin0 -> 59500 bytes
-rw-r--r--viewArticle/arrow.gifbin0 -> 87 bytes
-rw-r--r--viewArticle/default_style.css11
-rw-r--r--viewArticle/menus.jpgbin0 -> 27564 bytes
-rw-r--r--viewArticle/tag_a.jpgbin0 -> 916 bytes
-rw-r--r--viewArticle/tag_b.jpgbin0 -> 924 bytes
-rw-r--r--viewArticle/tag_c.jpgbin0 -> 913 bytes
-rw-r--r--viewArticle/tag_d.jpgbin0 -> 914 bytes
-rw-r--r--viewArticle/tag_e.jpgbin0 -> 909 bytes
-rw-r--r--viewArticle/tag_f.jpgbin0 -> 893 bytes
-rw-r--r--viewArticle/tag_g.jpgbin0 -> 923 bytes
-rw-r--r--viewArticle/viewArticleSrc.zipbin0 -> 240382 bytes
1317 files changed, 98557 insertions, 43 deletions
diff --git a/Article-EditorContributor/EditorContributor.html b/Article-EditorContributor/EditorContributor.html
new file mode 100644
index 0000000..608435f
--- /dev/null
+++ b/Article-EditorContributor/EditorContributor.html
@@ -0,0 +1,235 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="Author" content="Dejan Glozic">
+<meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+<title>Writing Error Report</title>
+</head>
+<body>
+&nbsp;
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+</table>
+<h1> <img SRC="../images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+<center>
+ <h1> Editor Contributors - A Distinct Species</h1>
+</center>
+<center>
+ <h3> Why are Eclipse desktop editors using a distinct contribution mechanism
+ instead of simply doing it directly from editors</h3>
+</center>
+<blockquote><b>Summary</b> <br>
+ Eclipse platform desktop offers various ways a plugin can contribute to menus
+ and tool bars. The most natural way for views is to contribute directly (if
+ you own the view, that is). However, editors are somewhat special - their contributors
+ are registered alongside editors and contribution from editor instances is not
+ allowed. This article explains why the difference and how editor contributors
+ prevent renegade runtime footprint and improve user experience. We will also
+ take a look at handling editor contributors in multi-page editors.</blockquote>
+<b>By <a href="mailto:dejan@ca.ibm.com">Dejan Glozic</a></b>
+<p>
+<hr WIDTH="100%">
+<br>
+One of the primary mechanisms of interaction with an Eclipse platform application
+is by performing actions in the given context. Whether you use menus, tool bars,
+accelerator keys etc. to perform an action is less important. Consequently, one
+of the most important considerations for Eclipse plugins is how to expose these
+actions to the user.
+<p>A standalone application developer has a relatively easy task since he owns
+ all of the action vectors (menu bars, tool bars, pop-up menus etc.). A plugin
+ developer must view its task as a contribution to the whole. Its contribution
+ will 'rub elbows' with those from other plugins, and seamless integration becomes
+ very important.
+<p>Desktop integration of actions is relatively easy for view developers. Eclipse
+ views are fairly encapsulated desktop parts. They have a local tool bar and
+ a pull-down menu. Because of this encapsulation, adding a view to the desktop
+ is a relatively easy affair.
+<p>Content editor is a completely different animal. Editors normally require a
+ large number of actions that are applicable in their context. Embedding these
+ actions into the desktop part is not possible in all but a very few simple cases.
+ Instead, editors add their actions to the shared desktop areas: the main menu
+ and tool bars. This creates a few problems. There can be potentially many editors
+ opened at once. They cannot all add their menus and tool bars into the shared
+ area - it would be a disaster. It would not be right either, because only one
+ editor can be active at a time. A context switching mechanism is needed to make
+ sure that only actions of the active editor are visible at any given point in
+ time.
+<p>Context switching ensures that visibility of the editor and its actions in
+ the desktop's shared areas are in sync. This requirement cannot be left to editor
+ developers - it is too important. Instead, editors are asked to create a contribution
+ and this contribution is used to add and remove actions on active editor switching.
+<h3> Contribution Memento</h3>
+The desktop implements context switching by using a feature of JFace contribution
+managers called <b>modification bracketing</b>. If you add actions into a contribution
+manager in its normal state, they will end up in its managed shared area of the
+desktop. However, it is possible to go into <b>recording mode</b> by calling a
+method <b>beginModification</b>. From that moment on, all contributions made to
+this manager are going into a separate record called <b>contribution memento</b>.
+Once we are done contributing, we call <b>endModification</b>. This method will
+restore the normal state of the manager and also return an <tt>ContributionMemento</tt>
+object. We can use this object to activate or deactivate it when needed. Activating
+a memento means adding all of the recorded actions to the originating manager.
+Similarly, deactivation of the memento removes the actions.
+<p>Usage of mementos is transparent to editor developers. Eclipse desktop employs
+ mementos to implement context switching, and ISVs are only required to do the
+ contribution part. The only thing for developers to remember is that some kind
+ of recording takes place, and that it is done on editor creation. Editors will
+ not be able to modify their contribution afterwards - it will simply be switched
+ in and out, as shown in Figure 1. <br>
+ &nbsp; <br>
+ &nbsp;
+<center>
+ <table BORDER=0 CELLSPACING=5 CELLPADDING=0 WIDTH="48%" >
+ <tr>
+ <td ALIGN=CENTER VALIGN=CENTER><img SRC="images/normaltoolbar.jpg" height=132 width=615></td>
+ </tr>
+ <tr>
+ <td ALIGN=CENTER VALIGN=CENTER><b><font size=-1>(a)&nbsp;</font></b></td>
+ </tr>
+ <tr>
+ <td ALIGN=CENTER VALIGN=CENTER><img SRC="images/htmltoolbar.jpg" height=132 width=615></td>
+ </tr>
+ <tr>
+ <td ALIGN=CENTER VALIGN=CENTER><b><font size=-1>(b)</font></b></td>
+ </tr>
+ <tr>
+ <td><b><font size=-1>Figure 1: Eclipse desktop menu and tool bar with no
+ editors (a) and with HTML editor opened (b). Note how there are more menus
+ and buttons in picture (b). These additions are coming from the contribution
+ associated with the editor.</font></b></td>
+ </tr>
+ </table>
+</center>
+<h3> The problem of flashing and run-time memory waste</h3>
+If you are writing a desktop view, contributing to the local tool bar is fairly
+simple - you simply ask for the local tool bar manager and add your actions. Similar
+scenario could be envisioned for contributing from the content editors, but it
+is not used, and for a reason. Consider the following: desktop views are unique.
+There cannot be multiple instances of the same view showing up in the desktop
+(if you try to reopen a view, the currently opened instance simply pops up and
+regains focus). However, there can be many instances of the same editor type opened
+at the same time, one for each file. If we contribute actions from the editor
+instance itself, that would mean a huge waste of time and memory.
+<p>For example: if we open 10 HTML files with a Web Tooling editor, and it has
+ 40 actions to contribute, we will have 400 action instances in memory. Only
+ 10% of these instances will be used at any point in time because only one of
+ these editors can be active. The remaining 90% will be switched out.
+<p>There is also a problem of menu and tool bar updates. In a naive implementation,
+ every editor switch would mean context switching for these shared areas: actions
+ of the deactivating editor will be removed, while those of the activating editor
+ will be added. But switching between editors of the same type means that we
+ are removing and adding instances of the same actions. Nothing will change in
+ the desktop except the unavoidable pause and flashing.
+<h3> The Eclipse solution</h3>
+The Eclipse desktop solution for this problem is to move editor contribution from
+editor <i>instances</i> to editor <i>types</i>. The desktop extension point for
+registering new editors accepts not only the Java class name for the editor, but
+also an optional class name for the <b>editor contributor</b>:
+<p><tt>interface IEditorActionBarContributor extends IActionBarContributor {</tt>
+ <br>
+ <tt>&nbsp;&nbsp; public void editorChanged(IEditorPart editor);</tt> <br>
+ <tt>}</tt>
+<p>This contributor extends action bar contributor interface and adds a method
+ to inform you about the editor change. This method is called only when editors
+ of your editor type are switched, so you can safely cast it into your editor
+ class. The implementors of this interface would use its required methods (<tt>contributeToMenu</tt>,
+ <tt>contributeToToolBar</tt> etc.) to add actions, submenus etc. in the usual
+ way. The key difference here is that these actions must be designed without
+ any specific editor instance in mind. They have to work on the currently active
+ instance, which means that they need to recalculate their enable state every
+ time there is editor change.
+<p>When a file is opened for editing, and the editor instance is the first of
+ that editor type to be opened, the contributor will be created as well. The
+ contributor will create a memento and keep it. When editors are switched, it
+ will use the memento to switch actions in or out. When another editor instance
+ of the same type is opened, no new actions will be created. The running contributor
+ will call <tt>editorChanged</tt> to allow actions to update. Contributor and
+ its actions will be removed and disposed only when the last instance of this
+ editor type is closed.
+<p>The key difference here is that context switching will occur only when two
+ editors of the <i>different</i> type are switched. On switching editors of the
+ same type, only <tt>editorChanged</tt> will be called in the contributor. This
+ means that editor changes will be smooth, with no flashes and pauses.
+<h3> Multi-page editors</h3>
+The situation complicates somewhat if the content editor if of a multi-page variety
+(for example, Web tooling HTML editor with its Design, Source and Preview pages).
+In this case, actions need to update their availability not only on an editor-to-editor
+basis, but also on page switches within the same editor, as shown in Figure 2.
+Since editor instance do not have access to editor actions (actions are normally
+created as fields of the class that implements contributor interface), the following
+solution may work well.
+<p>First, create a page listener interface:
+<blockquote><tt>interface IEditorPageListener {</tt> <br>
+ <tt>&nbsp;&nbsp; public void pageChanged(WorkbookPage page);</tt> <br>
+ <tt>}</tt></blockquote>
+In your multi-page editor class, add two methods to register the listener:
+<blockquote><tt>public void addEditorPageListener(IEditorPageListener listener);</tt>
+ <br>
+ <tt>public void removeEditorPageListener(IEditorPageListener listener);</tt></blockquote>
+When page within the editor changes, notify the listeners by calling <tt>pageChanged</tt>
+with the newly active page.
+<p>In the implementation of editor contributor, connect on each editor switch:
+<p><tt>public MultiPageContributor implements IEditorActionBarContributor,</tt>
+ <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ IEditorPageListener {</tt> <br>
+ <tt>&nbsp;&nbsp; MyMultiPageEditor currentEditor=null;</tt><tt></tt>
+<p><tt>&nbsp;&nbsp; public void editorChanged(IEditorPart part) {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyMyltiPageEditor editor = (MyMultiPageEditor)part;</tt>
+ <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (currentEditor!=null) currentEditor.removeEditorPageListener(this);</tt>
+ <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentEditor = editor;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentEditor.addEditorPageListener(this);</tt>
+ <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateActions();</tt> <br>
+ <tt>&nbsp;&nbsp; }</tt> <br>
+ <tt>&nbsp;&nbsp; public void pageChanged(WorkbookPage page) {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateActions(page);</tt> <br>
+ <tt>&nbsp;&nbsp; }</tt> <br>
+ <tt>}</tt>
+<p>The behavior of this class is straightforward: when editor becomes active,
+ the contributor disconnects from the old editor and connects to the new one.
+ While the current editor is active, page changes within it will cause the contributor
+ to update the action state. The two overloaded methods for updating actions
+ not shown here simply update the state of the actions according to the state
+ of the current editor and the currently selected page in the editor. <br>
+ &nbsp; <br>
+ &nbsp; <br>
+ &nbsp;
+<center>
+ <table BORDER=0 CELLSPACING=5 CELLPADDING=0 WIDTH="48%" >
+ <tr>
+ <td ALIGN=CENTER VALIGN=CENTER><img SRC="images/htmltoolbar.jpg" BORDER=0 height=132 width=615></td>
+ </tr>
+ <tr>
+ <td ALIGN=CENTER VALIGN=CENTER><b><font size=-1>(a)&nbsp;</font></b></td>
+ </tr>
+ <tr>
+ <td ALIGN=CENTER VALIGN=CENTER><img SRC="images/srctoolbar.jpg" height=132 width=615></td>
+ </tr>
+ <tr>
+ <td ALIGN=CENTER VALIGN=CENTER><b><font size=-1>(b)</font></b></td>
+ </tr>
+ <tr>
+ <td><b><font size=-1>Figure 2: Eclipse desktop menu and tool bar for the
+ Source (a) and Design view&nbsp; (b) of the HTML editor. The same actions
+ are present for&nbsp; both pages, but some of them are disabled for the
+ Source view.</font></b></td>
+ </tr>
+ </table>
+</center>
+<br>
+&nbsp;
+<h3> Conclusion</h3>
+This article has shown how contribution to menus and tool bars is 'special' in
+Eclipse desktop. We described the use of JFace contribution mementos. The article
+has also shown how the problem of tool bar flashing and action duplication is
+solved by removing contributors from editor instances. Finally, a tip on handling
+multi-page editors is presented.
+</body>
+</html>
diff --git a/Article-EditorContributor/images/Adarrow.gif b/Article-EditorContributor/images/Adarrow.gif
new file mode 100644
index 0000000..1848247
--- /dev/null
+++ b/Article-EditorContributor/images/Adarrow.gif
Binary files differ
diff --git a/Article-EditorContributor/images/Idea.jpg b/Article-EditorContributor/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-EditorContributor/images/Idea.jpg
Binary files differ
diff --git a/Article-EditorContributor/images/articles.gif b/Article-EditorContributor/images/articles.gif
new file mode 100644
index 0000000..47d972c
--- /dev/null
+++ b/Article-EditorContributor/images/articles.gif
Binary files differ
diff --git a/Article-EditorContributor/images/howto_banner.jpg b/Article-EditorContributor/images/howto_banner.jpg
new file mode 100644
index 0000000..f2e2d42
--- /dev/null
+++ b/Article-EditorContributor/images/howto_banner.jpg
Binary files differ
diff --git a/Article-EditorContributor/images/htmltoolbar.jpg b/Article-EditorContributor/images/htmltoolbar.jpg
new file mode 100644
index 0000000..86b105c
--- /dev/null
+++ b/Article-EditorContributor/images/htmltoolbar.jpg
Binary files differ
diff --git a/Article-EditorContributor/images/linux_only.gif b/Article-EditorContributor/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-EditorContributor/images/linux_only.gif
Binary files differ
diff --git a/Article-EditorContributor/images/markers.jpg b/Article-EditorContributor/images/markers.jpg
new file mode 100644
index 0000000..85195e6
--- /dev/null
+++ b/Article-EditorContributor/images/markers.jpg
Binary files differ
diff --git a/Article-EditorContributor/images/normaltoolbar.jpg b/Article-EditorContributor/images/normaltoolbar.jpg
new file mode 100644
index 0000000..b05173c
--- /dev/null
+++ b/Article-EditorContributor/images/normaltoolbar.jpg
Binary files differ
diff --git a/Article-EditorContributor/images/note.gif b/Article-EditorContributor/images/note.gif
new file mode 100644
index 0000000..f6260db
--- /dev/null
+++ b/Article-EditorContributor/images/note.gif
Binary files differ
diff --git a/Article-EditorContributor/images/notifiers.gif b/Article-EditorContributor/images/notifiers.gif
new file mode 100644
index 0000000..aefc75d
--- /dev/null
+++ b/Article-EditorContributor/images/notifiers.gif
Binary files differ
diff --git a/Article-EditorContributor/images/srctoolbar.jpg b/Article-EditorContributor/images/srctoolbar.jpg
new file mode 100644
index 0000000..2042b12
--- /dev/null
+++ b/Article-EditorContributor/images/srctoolbar.jpg
Binary files differ
diff --git a/Article-EditorContributor/images/tag_1.gif b/Article-EditorContributor/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-EditorContributor/images/tag_1.gif
Binary files differ
diff --git a/Article-EditorContributor/images/tag_2.gif b/Article-EditorContributor/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-EditorContributor/images/tag_2.gif
Binary files differ
diff --git a/Article-EditorContributor/images/tag_3.gif b/Article-EditorContributor/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-EditorContributor/images/tag_3.gif
Binary files differ
diff --git a/Article-EditorContributor/images/tag_4.gif b/Article-EditorContributor/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-EditorContributor/images/tag_4.gif
Binary files differ
diff --git a/Article-EditorContributor/images/tag_5.gif b/Article-EditorContributor/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-EditorContributor/images/tag_5.gif
Binary files differ
diff --git a/Article-EditorContributor/images/tag_6.gif b/Article-EditorContributor/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-EditorContributor/images/tag_6.gif
Binary files differ
diff --git a/Article-EditorContributor/images/tag_7.gif b/Article-EditorContributor/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-EditorContributor/images/tag_7.gif
Binary files differ
diff --git a/Article-EditorContributor/images/tip.gif b/Article-EditorContributor/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-EditorContributor/images/tip.gif
Binary files differ
diff --git a/Article-EditorContributor/images/tryit.gif b/Article-EditorContributor/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-EditorContributor/images/tryit.gif
Binary files differ
diff --git a/Article-EditorContributor/images/win_only.gif b/Article-EditorContributor/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-EditorContributor/images/win_only.gif
Binary files differ
diff --git a/Article-EditorContributor/images/write.png b/Article-EditorContributor/images/write.png
new file mode 100644
index 0000000..1e68ddd
--- /dev/null
+++ b/Article-EditorContributor/images/write.png
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/default_style.css b/Article-Folding-in-Eclipse-Text-Editors/default_style.css
new file mode 100644
index 0000000..d725483
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/default_style.css
@@ -0,0 +1,11 @@
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
diff --git a/Article-Folding-in-Eclipse-Text-Editors/folding.html b/Article-Folding-in-Eclipse-Text-Editors/folding.html
new file mode 100644
index 0000000..6439a0a
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/folding.html
@@ -0,0 +1,395 @@
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<title>Folding in Eclipse Text Editors</title>
+<link rel="stylesheet" href="default_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2005 Prashant Deva</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">Folding in Eclipse Text Editors</h1>
+
+<blockquote>
+<b>Summary</b>
+
+<br>
+ Starting with release 3.0, Eclipse allows folding in its text editor. In this
+ article, I explain the new projection infrastructure introduced in
+ the JFace Text framework
+ and show how to extend the XML Editor example provided
+ with Eclipse to allow folding of text.
+ <p><b> By Prashant Deva</b> (<a href="mailto:prashant.deva@gmail.com">prashant.deva@gmail.com</a>)<br>
+ March 11, 2005</p>
+</blockquote>
+
+<hr width="100%">
+<p>Starting with Eclipse 3.0 the JFace Text framework has been extended with a
+ feature to allow for collapsing and expanding of text. This can be noticed in
+ the JDT text editor, which allows you to fold individual methods and classes.
+ You can implement folding in your plug-in too, to allow the users to fold text
+ according the structure of your plug-in's documents.</p>
+<p>You will notice that 2 new packages have been added to the framework: </p>
+<ul>
+ <li><b>org.eclipse.jface.text.projection</b><br>
+ Implements the infrastructure for folding in a UI independent manner. <br>
+ This package resides in the plug-in <code>org.eclipse.text</code>.</li>
+ <li><b>org.eclipse.jface.text.source.projection</b><br>
+ Uses the class in <code>org.eclipse.jface.text.projection</code> to implement
+ folding in a UI dependent manner.<br>
+ This package resides in the plug-in <code>org.eclipse.jface.text</code>. </li>
+</ul>
+<h2>Basic Concept</h2>
+<p>Now let's look at the basic idea in the framework that allows it to just show portions
+ of the actual text. Although these concepts have been in the framework
+ since 2.1, a whole new implementation was added in 3.0 to support the additional
+ requirements of text folding.</p>
+<p><img src="images/withoutFolding.png" width="284" height="172"> &nbsp;&nbsp;&nbsp;&nbsp;<img src="images/withFolding.png" width="364" height="174"></p>
+<p>As you can see in the figure (a) above, without folding things were very simple.
+ We had a document to hold the text and a corresponding view to provide the UI
+ for the text. Now things are a little bit more complicated. We have a <strong>Master
+ Document</strong>, which is like the document we used to use previously.
+ It contains the entire text. However, there is also an additional <strong>Projection
+ Document</strong> attached to a Master Document. The contents of a projection
+ document are a subset of the contents of the Master Document. In other words,
+ the content of a projection document consists of portions of the Master Document.</p>
+<p> As you probabably guessed, when you collapse the text in the editor you see
+ the contents of a projection document containing only the expanded sections.</p>
+ <h2>Behind the scenes</h2>
+<h4>UI Independent Infrastructure </h4>
+<p>Now let’s take a look at the <code>org.eclipse.jface.text.projection</code> package.
+ Keep in mind that you don't actually have to use this package in order to implement
+ folding in your text editor. The following description is just
+ to help you understand the concepts behind the folding infrastructure.<br>
+ <br>
+ The classes we need to concentrate on are:
+<ul>
+ <li><code>ProjectionDocument</code>: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Represents
+ a portion of the content of a Master Document.</li>
+ <li><code>ProjectionDocumentEvent</code>: &nbsp;&nbsp;&nbsp;&nbsp;The event object
+ sent out by ProjectionDocument</li>
+ <li><code>ProjectionDocumentManager</code>: Maintains the association between
+ a Master Document and its Projection Documents.</li>
+ </ul>
+<p>The rest of the classes in the package are for internal use only and we need
+ not bother with them.</p>
+<p>The class <code>ProjectionDocumentManager</code> acts as glue between the master
+ document and its child projection documents, connecting them together. Thus
+ any change made to the projection document causes a corresponding change
+ to the master document and vice versa.</p>
+<p>Here is an example of using ProjectionDocumentManager:</p>
+
+<pre> Document masterDocument = <font color="#0000FF">new</font> Document();
+ ProjectionDocumentManager manager = <font color="#0000FF">new</font> ProjectionDocumentManager();
+<img src="images/tag_1.gif" CENTER>ProjectionDocument projectionDocument = (ProjectionDocument)
+ manager.createSlaveDocument(masterDocument);
+</pre>
+<p>In the above example we first create a <strong>Master Document</strong> and
+ then create a <strong>Projection Document</strong> off of it by using the <code>ProjectionDocumentManager</code>.
+ Instances of the class <code>ProjectionDocument</code>
+ (<img src="images/tag_1.gif" width="24" height="13">)
+ should be created only
+ by using the ‘factory method’ <code>createSlaveDocument()</code> of <code>ProjectionDocumentManager</code>
+ and not instantiated through its constructor. </p>
+<p>A Projection Document has two methods to define its content from the master
+ document:</p>
+<ul>
+ <li><code><font color="#0000FF">public void</font> addMasterDocumentRange(<font color="#0000FF">int</font>
+ offsetInMasterDocument,<font color="#0000FF">int</font> lengthInMasterDocument)</code>
+ <br>
+ Adds a range of text from the Master Document to the Projection Document.
+ <br>&nbsp;</li>
+ <li> <code><font color="#0000FF">public void</font> removeMasterDocumentRange(<font color="#0000FF">int</font>
+ offsetInMasterDocument,<font color="#0000FF">int</font> lengthInMasterDocument)</code><br>
+ Removes a range of text corresponding to the Master Document from the Projection
+ Document.</li>
+</ul>
+<p>Adding more to the previous lines of code: </p>
+<pre>
+masterDocument.set("one two");
+
+<font color="#009900">//removes "one t" from projection document</font>
+projectionDocument.removeMasterDocumentRange(0,5);
+
+<font color="#009900">//adds "ne " to projection document</font>
+projectionDocument.addMasterDocumentRange(1,3);
+
+System.out.println(masterDocument.get()); <font color="#009900">//prints 'one two'</font>
+System.out.println(projectionDocument.get());<font color="#009900">//prints 'ne wo'</font>
+</pre>
+<p>Above, we set the contents of the master document to a string.
+ Doing so
+ automatically sets the contents of the projection document to the same value. Then
+ we modify the projection document to contain only certain portions of the master
+ document. Finally we output the contents of both the documents and see that
+ the portion of master document which we removed from the projection document
+ is not printed out but the contents of the master document remain the same.</p>
+<h2>The Stage</h2>
+<h4>UI Dependent Infrastructure</h4>
+<p>To actually implement folding in your editor, you don't really need to be concerned
+ with the details above.
+ The Eclipse developers have provided a nice package
+ named <code><strong>org.eclipse.jface.text.source.projection</strong></code>
+ that takes care of all the details and makes your job far easier.</p>
+<p>The centerpiece of this package is the <code>ProjectionViewer</code> class,
+ which you must use in your plug-in instead of the usual <code>TextViewer</code>
+ class, to implement folding. A <code>ProjectionViewer</code> internally uses
+ a <code>ProjectionDocumentManager</code> to manage the display of Projection
+ Documents, so we don't have to worry about that. It implements the <code>ITextViewerExtension5</code>
+ interface which is a central part of the UI dependent infrastructure. </p>
+<p><code>ITextViewerExtension5</code> introduces the concept of
+ <em>widget coordinates</em> and <em>model coordinates</em>.
+ A widget coordinate corresponds
+ to a position on the text viewer while a model coordinate corresponds to a position
+ on the document. A widget range always has a corresponding model range which
+ maps to the viewer’s document, while on the other hand a model range can be
+ either ‘exposed’ or ‘unexposed’. An exposed model range is visible on the viewer
+ and can thus be mapped to a widget range. Thus when you expand the text in the
+ viewer, that model range is ‘exposed’ and vice versa. <code>ITextViewerExtension5</code>
+ contains methods to do the conversion from widget to model coordinates and vice
+ versa, and to expose model ranges.</p>
+<h4>Projection Support</h4>
+<p>Another important class in this package is <code>ProjectionSupport</code>.
+ This class controls the display and configuration of all the UI elements related
+ to folding, for example, the painting of those elipsis icons when
+ you collapse a region, and the vertical column that contains the triangle icons
+ to expand/collapse text. A <code>ProjectionSupport</code> instance needs to be installed
+ on a viewer. The XML Editor example shown <a href="#projectionSupport">below</a> demonstrates how to do this
+ in code.</p>
+<p><code>ProjectionSupport</code>
+ allows you to specify <em>summarizable annotation types</em>. Basically,
+ these are the annotations that will appear in the vertical column on the left
+ when you fold the text that contains them. For example, JDT specifies the ‘error’
+ and ‘warning’ annotation types as summarizable, so that when you fold the text
+ that contains a warning or an error, its icon appears on the vertical column
+ besides the folding arrow, as shown below.</p>
+<p><img src="images/annotationSummary.png" width="282" height="129"></p>
+<p>Here is how it is implemented:</p>
+<pre>fProjectionSupport.addSummarizableAnnotationType(
+ "org.eclipse.ui.workbench.texteditor.error");
+fProjectionSupport.addSummarizableAnnotationType(
+ "org.eclipse.ui.workbench.texteditor.warning");
+</pre>
+<p>The <code>setHoverControlCreator()</code> method
+ allows you to set up a hover control to display the collapsed text
+ in a tooltip style box when the use moves the cursor over the arrow.
+ For example:</p>
+<p><img src="images/hover.png" width="223" height="136"></p>
+<p>The constructor takes an <code>IInformationControlCreator</code> as the argument. You usually
+ create an anonymous class here. Here is how JDT does it: </p>
+<pre>fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() {
+ <font color="#0000FF">public</font> IInformationControl createInformationControl(Shell shell) {
+ <font color="#0000FF">return new</font> CustomSourceInformationControl(shell, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+});
+</pre>
+<h4>Projection Annotations</h4>
+<p>To enable folding, we have to specify which regions of the text are collapsible.
+ We do this by
+ calling <code>addAnnotation()</code>
+ adding <code>ProjectionAnnotations</code> to the ProjectionViewer's
+ <code>ProjectionAnnotationModel</code>. The position allows the annotation to
+ be attached to certain text in the editor. </p>
+
+<p>The methods of ProjectionAnnotationModel are pretty self-explanatory: </p>
+<pre><font color="#0000FF">class</font> ProjectionAnnotationModel{
+
+ <font color="#0000FF"> public void</font> collapse(Annotation annotation)
+ <font color="#0000FF"> public void</font> expand(Annotation annotation)
+ <font color="#0000FF"> public boolean</font> expandAll(int offset,int length)
+
+ <font color="#0000FF"> public void</font> toggleExpansionState(Annotation annotation)
+
+ <font color="#0000FF"> public void</font> modifyAnnotations(Annotation[] deletions,Map additions,
+ Annotation[] modifications)
+}
+</pre>
+<p>These methods toggle the annotations to expand/collapse states.
+ The only method which may be confusing is: <code>modifyAnnotations()</code>.
+ This basically does several deletions, additions, and modifications at once.
+ The additions
+ parameter is a Map with Annotation as the key and Position as the value. Executing
+ the method generates a single change event rather than a series of them when
+ you would add and remove annotations one after the other.
+</p>
+<p>A <code>ProjectionAnnotation</code> has the following methods to collapse/expands
+ the text region it is associated with:</p>
+<pre> <font color="#0000FF">public void</font> markCollapsed() <font color="#009933"> //marks the annotation as collapsed</font>
+ <font color="#0000FF">public void</font> markExpanded() <font color="#009933">//marks the annotation as expanded</font>
+ <font color="#0000FF">public boolean</font> isCollapsed() <font color="#009933">//tells whether the annotation is collapsed or expanded</font>
+</pre>
+<p>Thus, when you are working in JDT and you click the arrow on the left side
+ column of the text to collapse it, the method <code>isCollapsed()</code> is
+ called to check whether the text is collapsed or not and then
+ <code>markCollapsed()</code> is called
+ if <code>isCollapsed()</code> returns false. For example,</p>
+<pre> <font color="#0000FF">if</font>(!annotation.isCollapsed())
+ annotation.markCollapsed();
+</pre>
+<p><img src="images/note.gif"> Manipulating ProjectionAnnotations is the only
+ supported way to control folding. Even if you were to get a hold of a Projection
+ Document, its projection behavior should never be manipulated directly. </p>
+<h4>Painting the Annotations...</h4>
+<p>Folding in the editor would be quite useless without the user interface
+ that allowed us to collapse and expand the text.
+ Here's what it looks like in the editor:</p>
+<p><img src="images/projectionAnnotation.png" width="226" height="214"></p>
+<p>ProjectionAnnotation has a method which actually paints those triangles you see
+ on the left.</p>
+<p><code><font color="#0000FF">public void</font> paint(GC gc, Canvas canvas,
+ Rectangle rectangle)</code></p>
+<p>You can override this method in your plug-in if you want to draw something other
+ than an triangle on the left side, for example a plus/minus sign.</p>
+<p>There is one more method you should know about:</p>
+<p><code><font color="#0000FF">public void</font> setRangeIndication(<font color="#0000FF">boolean</font>
+ rangeIndication)</code></p>
+<p>A <em>range indication</em>
+ is that line you see when you move your cursor to an triangle indicating
+ that the text is expanded. The line signifies the range of
+ text that will be collapsed when you click the triangle, and thus the name.
+ Passing true or false to this method controls whether
+ that line is drawn or not.</p>
+
+<h2>The Show</h2>
+<h4>XML Editor plug-in</h4>
+<p>I can hear you saying “Yeah, all this is fine, but how do I actually use this
+ stuff in my plug-in?” Well to show you how to do that I will walk you through
+ a little example. We will extend the XML editor plug-in example provided with
+ Eclipse to allow folding of XML elements. My aim is just to demonstrate the
+ basics of implementing folding here, so I have tried to keep the code as simple
+ as possible. If you want to add any advanced functionality you should be able
+ to do so yourself by now (hopefully) ;-) </p>
+<p>Let's look at the steps involved in supporting folding.
+ Note that all the methods shown below are defined in the class
+ <code>XMLEditor</code> which extends the <code>TextEditor</code> class.</p>
+
+
+<ol>
+ <li>Override <code>createPartControl </code> method of <code>TextEditor</code>
+ to configure and install <code>ProjectionSupport</code></li>
+ <li>Override <code>createSourceViewer</code> method of <code>AbstractTextEditor</code>
+ to return a <code>ProjectionViewer</code></li>
+ <li>Provide some functionality to define collapsible regions</li>
+ </ol>
+ Now lets see how to implement this in our plug-in.
+<p><img src="images/tryit.gif" width="61" height="13">Create a new Plug-in project.
+ At the end of the Project Wizard there will be an option to Create a
+ plug-in using one of the templates. Check it and select Plug-in with an editor.
+ This will create a plug-in with an editor for XML files. Now we will extend
+ this editor to allow the folding of XML elements.</p>
+<p><strong>1)</strong> First, we override the <code> createPartControl</code>
+ method of the <code>TextEditor</code> class. To keep things simple
+ I haven't provided any code for summarizable annotation types or hover controls,
+ but you are free to do so in your own plug-in.</p>
+<a name="projectionSupport"></a><pre><font color="#0000FF">public void</font> createPartControl(Composite parent)
+{
+ <font color="#0000FF">super</font>.createPartControl(parent);
+ ProjectionViewer viewer =(ProjectionViewer)getSourceViewer();
+
+ projectionSupport = new ProjectionSupport(viewer,getAnnotationAccess(),getSharedColors());
+ projectionSupport.install();
+
+ <font color="#009933">//turn projection mode on</font>
+ viewer.doOperation(ProjectionViewer.TOGGLE);
+
+ annotationModel = viewer.getProjectionAnnotationModel();
+
+}</pre>
+<p><strong>2)</strong> Next, we tell <code>createSourceViewer</code> to return
+ a <code>ProjectionViewer</code> instead of a <code>SourceViewer</code>. </p>
+<pre><font color="#0000FF">protected</font> ISourceViewer createSourceViewer(Composite parent,
+ IVerticalRuler ruler, <font color="#0000FF">int</font> styles)
+{
+ ISourceViewer viewer = <font color="#0000FF">new</font> ProjectionViewer(parent, ruler,
+ getOverviewRuler(), isOverviewRulerVisible(), styles);
+
+ <font color="#009933">// ensure decoration support has been created and configured.</font>
+ getSourceViewerDecorationSupport(viewer);
+
+ <font color="#0000FF">return</font> viewer;
+}
+</pre>
+
+<p><strong>3)</strong> Finally, we need some mechanism to tell the editor which
+ regions are collapsible. For that I have written a (very) small parser for XML
+ (which is very buggy and doesn't support nested elements). The parser runs as
+ a reconciling strategy and parses the entire document every time it is modified.
+ The parser then passes the range of every XML element to the editor, which then
+ in turn adds Projection Annotations to define collapsible regions.</p>
+ <p>
+ The source code for my simple parser is too large to show here, however, those
+ interested can take a look at the <code>XmlReconcilingStrategy.java</code>
+ file in the provided source code. </p>
+<p>Below is the code that does all this:</p>
+<pre><font color="#0000FF">private</font> Annotation[] oldAnnotations;
+<font color="#0000FF">public void</font> updateFoldingStructure(ArrayList positions)
+{
+ Annotation[] annotations = new Annotation[positions.size()];
+
+ <font color="#009933">//this will hold the new annotations along
+ //with their corresponding positions</font>
+ HashMap newAnnotations = new HashMap();
+
+ <font color="#0000FF">for</font>(<font color="#0000FF">int</font> i = 0; i < positions.size();i++)
+ {
+ ProjectionAnnotation annotation = <font color="#0000FF">new</font> ProjectionAnnotation();
+
+ newAnnotations.put(annotation, positions.get(i));
+
+ annotations[i] = annotation;
+ }
+
+ annotationModel.modifyAnnotations(oldAnnotations, newAnnotations,null);
+
+ oldAnnotations = annotations;
+}
+</pre>
+<p>Here is our completed editor with folding:</p>
+<p><img src="images/xmlEditor.png" width="331" height="203"></p>
+<h1>Source Code</h1>
+<p>All the source code that accompanies this article
+ may be found in the <a href="xmlEditorPlugin.zip">xmlEditorPlugin.zip file</a>.</p>
+<p><b>Update (19April2005):</b> My (buggy) xml parser has been replaced by a better one from
+Gerd Castan which supports nested xml elements.
+</p>
+<h1>Conclusion</h1>
+<p>By now, you should have understood the UI independent and dependent infrastructure
+ used in JFace Text to implement the folding capability. You should also have
+ understood how to implement folding in the text editor of your eclipse plug-in.
+ Plus you even got a free XML editor for Eclipse with folding support ;-).</p>
+<h1>References</h1>
+<ul>
+ <li><a href="http://devresource.hp.com/drc/technical_white_papers/eclipeditor/index.jsp" target="_blank">Creating a text-based editor for Eclipse</a></li>
+ <li>Articles in the Eclipse 3.0 Faqs book on text editors:
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq262.html" target="_blank">[FAQ262]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq263.html" target="_blank">[FAQ263]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq264.html" target="_blank">[FAQ264]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq265.html" target="_blank">[FAQ265]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq266.html" target="_blank">[FAQ266]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq267.html" target="_blank">[FAQ267]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq268.html" target="_blank">[FAQ268]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq269.html" target="_blank">[FAQ269]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq270.html" target="_blank">[FAQ270]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq271.html" target="_blank">[FAQ271]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq272.html" target="_blank">[FAQ272]</a>
+ <a href="http://www.eclipsefaq.org/chris/faq/html/faq273.html" target="_blank">[FAQ273]</a>
+ </li>
+ <li><a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/guide/editors.htm" target="_blank">Online help for Editors</a></li>
+ <li><a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/samples/org.eclipse.ui.examples.javaeditor/doc-html/ui_javaeditor_ex.html" target="_blank">Online help for the Java editor example</a></li>
+</ul>
+<small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>
+</body>
+</html>
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/Idea.jpg b/Article-Folding-in-Eclipse-Text-Editors/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/Idea.jpg
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/Thumbs.db b/Article-Folding-in-Eclipse-Text-Editors/images/Thumbs.db
new file mode 100644
index 0000000..a4624d8
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/Thumbs.db
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/annotationSummary.png b/Article-Folding-in-Eclipse-Text-Editors/images/annotationSummary.png
new file mode 100644
index 0000000..1f05d49
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/annotationSummary.png
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/hover.png b/Article-Folding-in-Eclipse-Text-Editors/images/hover.png
new file mode 100644
index 0000000..450a1dd
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/hover.png
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/linux_only.gif b/Article-Folding-in-Eclipse-Text-Editors/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/linux_only.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/note.gif b/Article-Folding-in-Eclipse-Text-Editors/images/note.gif
new file mode 100644
index 0000000..f6260db
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/note.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/projectionAnnotation.png b/Article-Folding-in-Eclipse-Text-Editors/images/projectionAnnotation.png
new file mode 100644
index 0000000..20b2253
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/projectionAnnotation.png
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/tag_1.gif b/Article-Folding-in-Eclipse-Text-Editors/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/tag_1.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/tag_2.gif b/Article-Folding-in-Eclipse-Text-Editors/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/tag_2.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/tag_3.gif b/Article-Folding-in-Eclipse-Text-Editors/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/tag_3.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/tag_4.gif b/Article-Folding-in-Eclipse-Text-Editors/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/tag_4.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/tag_5.gif b/Article-Folding-in-Eclipse-Text-Editors/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/tag_5.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/tag_6.gif b/Article-Folding-in-Eclipse-Text-Editors/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/tag_6.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/tag_7.gif b/Article-Folding-in-Eclipse-Text-Editors/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/tag_7.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/tip.gif b/Article-Folding-in-Eclipse-Text-Editors/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/tip.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/tryit.gif b/Article-Folding-in-Eclipse-Text-Editors/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/tryit.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/win_only.gif b/Article-Folding-in-Eclipse-Text-Editors/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/win_only.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/withFolding.png b/Article-Folding-in-Eclipse-Text-Editors/images/withFolding.png
new file mode 100644
index 0000000..b3a624b
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/withFolding.png
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/withoutFolding.png b/Article-Folding-in-Eclipse-Text-Editors/images/withoutFolding.png
new file mode 100644
index 0000000..48173ca
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/withoutFolding.png
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/xmlEditor.png b/Article-Folding-in-Eclipse-Text-Editors/images/xmlEditor.png
new file mode 100644
index 0000000..d10a481
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/xmlEditor.png
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/images/xmlEditor1.gif b/Article-Folding-in-Eclipse-Text-Editors/images/xmlEditor1.gif
new file mode 100644
index 0000000..8bc86c2
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/images/xmlEditor1.gif
Binary files differ
diff --git a/Article-Folding-in-Eclipse-Text-Editors/xmlEditorPlugin.zip b/Article-Folding-in-Eclipse-Text-Editors/xmlEditorPlugin.zip
new file mode 100644
index 0000000..3f528f8
--- /dev/null
+++ b/Article-Folding-in-Eclipse-Text-Editors/xmlEditorPlugin.zip
Binary files differ
diff --git a/Article-GEF-Draw2d/GEF-Draw2d.html b/Article-GEF-Draw2d/GEF-Draw2d.html
new file mode 100644
index 0000000..a600125
--- /dev/null
+++ b/Article-GEF-Draw2d/GEF-Draw2d.html
@@ -0,0 +1,379 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+<TITLE>Displaying a UML Diagram with Draw2D</TITLE>
+<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<META content="Microsoft FrontPage 5.0" name=GENERATOR>
+<LINK href="../default_style.css" rel=stylesheet>
+</HEAD>
+<BODY vLink=#800080 link=#0000FF>
+<DIV align=right>&nbsp; <FONT face="Times New Roman, Times, serif"><FONT
+ size=-1>Copyright © 2003 International Business Machines Corp.</FONT></FONT></DIV>
+&nbsp;
+<DIV align=right>
+<TABLE cellSpacing=0 cellPadding=2 width="100%" border=0>
+ <TBODY>
+ <TR>
+ <TD vAlign=top align=left bgColor=#0080c0 colSpan=2><B><FONT
+ face=Arial,Helvetica><FONT color=#ffffff>&nbsp;Eclipse Corner
+ Article</FONT></FONT></B></TD>
+ </TR>
+ </TBODY>
+</TABLE>
+</DIV>
+<H1><IMG border="0" src="images/Idea.jpg" width="120" height="86"></H1>
+<CENTER>
+<H1>Display a UML Diagram using Draw2D</H1>
+</CENTER>
+<BLOCKQUOTE><B>Summary</B><BR>
+ The Graphical Editing Framework (GEF) ships with a painting and layout plug-in
+ called <b>Draw2D</b>. Draw2D provides figures and layout managers which form
+ the graphical layer of a GEF application. This article focuses only on the use
+ of Draw2D to render a simple UML class diagram.&nbsp; While Draw2D can be used
+ for standalone purposes, it is not an editing framework.&nbsp; Most applications
+ will use the GEF plug-in as the editing layer.
+ <P><B>By Daniel Lee, IBM</B><BR>
+ <FONT size=-1>August 25, 2003</FONT></P>
+</BLOCKQUOTE>
+<HR width="100%">
+
+<H1>Introduction</H1>
+<P>Draw2d provides lightweight rendering and layout capabilities on an SWT Canvas.
+ Figures, Layout Managers, and Borders can be combined and nested to create more
+ complex figures to suit just about any application. Choosing the right combination
+ of figures and layouts to create the desired effect can be a delicate task.
+ This article will walk you through creating a complex figure. </P>
+<P>Due to the scope of this article, the example code presented uses
+Draw2d in isolation, but most applications will use GEF and Draw2d together.<BR>
+</P>
+
+<H1>Creating the Draw2d Figure</H1>
+<H2>An Example</H2>
+This article will be based upon the creation of the following Draw2d
+Figure, a simplified UML class diagram:
+<BR>
+<BR>
+<DIV align="center"><IMG border="0" src="images/classDiagGIF.gif" width="154"
+ height="91"></DIV>
+<H2>Designing the Figure</H2>
+The first step in the creation of a figure is to decide on the
+components that will comprise the figure, and how they will be
+arranged.
+<P>The example figure is composed of three children figures. The composition itself
+ is named <b>UMLClassFigure</b>. Its first child, a <code>Label</code> figure,
+ will display the class name (&quot;Table&quot; in this example).&nbsp; The next
+ two children are containers for the class' attributes and methods.&nbsp; We
+ will create a figure called <b>CompartmentFigure</b> for this purpose. Both
+ the class and compartment figures will use a <code>ToolbarLayout</code> to place
+ their children. Here is a conceptual diagram of the overall structure:</P>
+<P align="center"><IMG border="0" src="images/UMLDiagGIF.gif" width="536"
+ height="404"></P>
+<H2>Creating the CompartmentFigure Class</H2>
+<P>CompartmentFigure is used to hold both methods and attributes. This class extends
+ org.eclipse.draw2d.Figure, and uses a ToolbarLayout to place its children. In
+ addition, CompartmentFigure uses a custom border. This border simply paints
+ a line 1 pixel in thickness across its top, to serve as the separator between
+ the CompartmentFigures. The code for CompartmentFigure is as follows:</P>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+<td><pre>public class CompartmentFigure extends Figure {
+
+ public CompartmentFigure() {
+ ToolbarLayout layout = new ToolbarLayout();
+ layout.setMinorAlignment(ToolbarLayout.ALIGN_TOPLEFT);
+ layout.setStretchMinorAxis(false);
+ layout.setSpacing(2);
+ setLayoutManager(layout);
+ setBorder(new CompartmentFigureBorder());
+ }
+
+ public class CompartmentFigureBorder extends AbstractBorder {
+ public Insets getInsets(IFigure figure) {
+ return new Insets(1,0,0,0);
+ }
+ public void paint(IFigure figure, Graphics graphics, Insets insets) {
+ graphics.drawLine(getPaintRectangle(figure, insets).getTopLeft(),
+ tempRect.getTopRight());
+ }
+ }
+}</pre></td>
+ </tr>
+</table>
+<H2>Creating the UMLClassFigure Class</H2>
+<P>The UMLClassFigure class is in many ways similar to the
+CompartmentFigure class. It contains three children -- two
+CompartmentFigures for attributes and methods and a Draw2d Label to
+display the class name. It also uses a vertically oriented ToolbarLayout to
+place its children. UMLClassFigure uses Draw2d's
+LineBorder to draw a box around its edges. The
+code for the UMLClassFigure class is as follows:</P>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>public class UMLClassFigure extends Figure {
+ public static Color classColor = new Color(null,255,255,206);
+ private CompartmentFigure attributeFigure = new CompartmentFigure();
+ private CompartmentFigure methodFigure = new CompartmentFigure();
+ public UMLClassFigure(Label name) {
+ ToolbarLayout layout = new ToolbarLayout();
+ setLayoutManager(layout);
+ setBorder(new LineBorder(ColorConstants.black,1));
+ setBackgroundColor(classColor);
+ setOpaque(true);
+
+ add(name);
+ add(attributeFigure);
+ add(methodFigure);
+ }
+ public CompartmentFigure getAttributesCompartment() {
+ return attributeFigure;
+ }
+ public CompartmentFigure getMethodsCompartment() {
+ return methodFigure;
+ }
+}</pre></td>
+ </tr>
+</table>
+<H2>Adding a Connection</H2>
+<P>Draw2d offers a special type of figure, called a connection, for connecting two figures.
+ To create a
+connection in Draw2d, it is first necessary to establish the two
+endpoints of the connection. These endpoints are called the
+<I>source</I> and the <I>target</I> anchors. Endpoints are created
+using objects that implement the ConnectionAnchor interface. Once these
+anchors are created, they are set as endpoints via calls to the
+connection's setSourceAnchor(ConnectionAnchor) and
+setTargetAnchor(ConnectionAnchor) methods. This is demonstrated below
+using a ChopboxAnchor. This type of anchor places the connection
+endpoint on the edge of the figure and causes it to point towards the figure's
+center.</P>
+
+
+<P>The following code demonstrates the addition of a connection:</P>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>PolylineConnection c = new PolylineConnection();
+ChopboxAnchor sourceAnchor = new ChopboxAnchor(classFigure);
+ChopboxAnchor targetAnchor = new ChopboxAnchor(classFigure2);
+c.setSourceAnchor(sourceAnchor);
+c.setTargetAnchor(targetAnchor);</pre></td>
+</tr>
+</table>
+<P align="center"><IMG border="0" src="images/classDiagConnectionGIF.gif"
+ width="355" height="343"> <B><BR>
+Two UMLClassFigures connected by a PolyLineConnection </B></P>
+<P align="center"><B></B><BR>
+</P>
+<H2>Adding a Decoration to the Connection</H2>
+<P>Draw2d also provides means for endpoint decorations, such as
+arrow-tips. Staying with the UML theme, we will create a decoration that
+represents a composed relationship, which is shown in UML as a filled
+diamond. This is done using a PolygonDecoration. The default shape of a
+PolygonDecoration is a filled arrowhead, but any shape can be used by creating a template for the decoration using a
+PointList, and calling the PolygonDecoration's setTemplate(PointList)
+method.<BR>
+<P>The following code demonstrates the addition of a PolygonDecoration
+to a Connection:</P>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>PolygonDecoration decoration = new PolygonDecoration();
+PointList decorationPointList = new PointList();
+decorationPointList.addPoint(0,0);
+decorationPointList.addPoint(-2,2);
+decorationPointList.addPoint(-4,0);
+decorationPointList.addPoint(-2,-2);
+decoration.setTemplate(decorationPointList);
+c.setSourceDecoration(decoration);</pre></td>
+</tr>
+</table>
+<P align="center"><IMG border="0" src="images/classDiagDecoGIF.gif" width="350"
+ height="335"><B><BR>
+Connection with a PolygonDecoration </B><BR>
+<BR>
+</P>
+<H2>Adding Labels to the Connection Using Locators</H2>
+<P>In addition to decorations, it is possible to add other Draw2d
+figures to the connection itself. This is done by calling the
+connection's add(IFigure figure, Object constraint) method where
+'figure' is the figure that you wish to add, and 'constraint' is an
+object that implements the Locator interface. The Locator places the figure on the connection. We will
+use this technique to add labels to our class diagram.
+The ConnectionEndpointLocator will be used for these labels. This
+locator places its figure relative to the connection's source or target endpoint. It allows the user to define the distance that the figure will appear relative to the end point via its
+setUDistance(int) and setVDistance(int) methods. (uDistance is the distance from the connection's owner to the figure. vDistance is the distance from the figure to the connection itself).</P>
+<P>The following code demonstrates the use of ConnectionEndpointLocators
+to add Labels to a Connection:</P>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>ConnectionEndpointLocator targetEndpointLocator =
+ new ConnectionEndpointLocator(c, true);
+targetEndpointLocator.setVDistance(15);
+Label targetMultiplicityLabel = new Label(&quot;1..*&quot;);
+c.add(targetMultiplicityLabel, targetEndpointLocator);
+ConnectionEndpointLocator sourceEndpointLocator =
+ new ConnectionEndpointLocator(c, false);
+sourceEndpointLocator.setVDistance(15);
+Label sourceMultiplicityLabel = new Label(&quot;1&quot;);
+c.add(sourceMultiplicityLabel, sourceEndpointLocator);
+
+ConnectionEndpointLocator relationshipLocator =
+ new ConnectionEndpointLocator(c,true);
+relationshipLocator.setUDistance(30);
+relationshipLocator.setVDistance(-20);
+Label relationshipLabel = new Label(&quot;contains&quot;);
+c.add(relationshipLabel,relationshipLocator);
+</pre></td>
+</tr>
+</table>
+<P align="center"><IMG border="0" src="images/classDiagLabelsGIF.gif"
+ width="344" height="334"><BR>
+<B>Adding Labels to the Connection </B></P>
+<H1>Creating a Test Class</H1>
+<P>This class contains a main method that creates an SWT shell and
+places a Draw2d LightweightSystem on that shell. The LightweightSystem
+ class provides the link between SWT and Draw2d. The test
+class creates a Draw2d figure to act as the contents of the
+LightweightSystem and adds two UMLClassFigures to this figure. It then
+connects the two class figures with a polyline connection, adds a
+diamond polygon decorator, and adds the UML relationship labels to the
+connection.<BR>
+<BR>
+This class uses the following images: { <IMG border="0"
+ src="images/field_private_obj.gif" width="16" height="16"> <IMG border="0"
+ src="images/methpub_obj.gif" width="16" height="16"> <IMG border="0"
+ src="images/class_obj.gif" width="16" height="16"> }. Download them and place them at
+the root of a Java project directory.<BR>
+</P>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td>
+ <pre>import org.eclipse.draw2d.*;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A test class to display a UMLFigure
+ */
+public class UMLClassFigureTest {
+ public static void main(String args[]){
+ Display d = new Display();
+ final Shell shell = new Shell(d);
+ shell.setSize(400, 400);
+ shell.setText(&quot;UMLClassFigure Test&quot;);
+ LightweightSystem lws = new LightweightSystem(shell);
+ Figure contents = new Figure();
+ XYLayout contentsLayout = new XYLayout();
+ contents.setLayoutManager(contentsLayout);
+
+ Font classFont = new Font(null, &quot;Arial&quot;, 12, SWT.BOLD);
+ Label classLabel1 = new Label(&quot;Table&quot;, new Image(d,
+ UMLClassFigureTest.class.getResourceAsStream(&quot;class_obj.gif&quot;)));
+ classLabel1.setFont(classFont);
+
+ Label classLabel2 = new Label(&quot;Column&quot;, new Image(d,
+ UMLClassFigureTest.class.getResourceAsStream(&quot;class_obj.gif&quot;)));
+ classLabel2.setFont(classFont);
+
+ final UMLClassFigure classFigure = new UMLClassFigure(classLabel1);
+ final UMLClassFigure classFigure2 = new UMLClassFigure(classLabel2);
+
+ Label attribute1 = new Label(&quot;columns: Column[]&quot;, new Image(d,
+ UMLClassFigure.class.getResourceAsStream(&quot;field_private_obj.gif&quot;)));
+ Label attribute2 = new Label(&quot;rows: Row[]&quot;, new Image(d,
+ UMLClassFigure.class.getResourceAsStream(&quot;field_private_obj.gif&quot;)));
+ Label attribute3 = new Label(&quot;columnID: int&quot;, new Image(d,
+ UMLClassFigure.class.getResourceAsStream(&quot;field_private_obj.gif&quot;)));
+ Label attribute4 = new Label(&quot;items: List&quot;, new Image(d,
+ UMLClassFigure.class.getResourceAsStream(&quot;field_private_obj.gif&quot;)));
+
+ classFigure.getAttributesCompartment().add(attribute1);
+ classFigure.getAttributesCompartment().add(attribute2);
+ classFigure2.getAttributesCompartment().add(attribute3);
+ classFigure2.getAttributesCompartment().add(attribute4);
+
+ Label method1 = new Label(&quot;getColumns(): Column[]&quot;, new Image(d,
+ UMLClassFigure.class.getResourceAsStream(&quot;methpub_obj.gif&quot;)));
+ Label method2 = new Label(&quot;getRows(): Row[]&quot;, new Image(d,
+ UMLClassFigure.class.getResourceAsStream(&quot;methpub_obj.gif&quot;)));
+ Label method3 = new Label(&quot;getColumnID(): int&quot;, new Image(d,
+ UMLClassFigure.class.getResourceAsStream(&quot;methpub_obj.gif&quot;)));
+ Label method4 = new Label(&quot;getItems(): List&quot;, new Image(d,
+ UMLClassFigure.class.getResourceAsStream(&quot;methpub_obj.gif&quot;)));
+
+ classFigure.getMethodsCompartment().add(method1);
+ classFigure.getMethodsCompartment().add(method2);
+ classFigure2.getMethodsCompartment().add(method3);
+ classFigure2.getMethodsCompartment().add(method4);
+
+ contentsLayout.setConstraint(classFigure, new Rectangle(10,10,-1,-1));
+ contentsLayout.setConstraint(classFigure2, new Rectangle(200, 200, -1, -1));
+
+ /* Creating the connection */
+ PolylineConnection c = new PolylineConnection();
+ ChopboxAnchor sourceAnchor = new ChopboxAnchor(classFigure);
+ ChopboxAnchor targetAnchor = new ChopboxAnchor(classFigure2);
+ c.setSourceAnchor(sourceAnchor);
+ c.setTargetAnchor(targetAnchor);
+
+ /* Creating the decoration */
+ PolygonDecoration decoration = new PolygonDecoration();
+ PointList decorationPointList = new PointList();
+ decorationPointList.addPoint(0,0);
+ decorationPointList.addPoint(-2,2);
+ decorationPointList.addPoint(-4,0);
+ decorationPointList.addPoint(-2,-2);
+ decoration.setTemplate(decorationPointList);
+ c.setSourceDecoration(decoration);
+
+ /* Adding labels to the connection */
+ ConnectionEndpointLocator targetEndpointLocator =
+ new ConnectionEndpointLocator(c, true);
+ targetEndpointLocator.setVDistance(15);
+ Label targetMultiplicityLabel = new Label(&quot;1..*&quot;);
+ c.add(targetMultiplicityLabel, targetEndpointLocator);
+
+ ConnectionEndpointLocator sourceEndpointLocator =
+ new ConnectionEndpointLocator(c, false);
+ sourceEndpointLocator.setVDistance(15);
+ Label sourceMultiplicityLabel = new Label(&quot;1&quot;);
+ c.add(sourceMultiplicityLabel, sourceEndpointLocator);
+
+ ConnectionEndpointLocator relationshipLocator =
+ new ConnectionEndpointLocator(c,true);
+ relationshipLocator.setUDistance(10);
+ relationshipLocator.setVDistance(-20);
+ Label relationshipLabel = new Label(&quot;contains&quot;);
+ c.add(relationshipLabel,relationshipLocator);
+
+ contents.add(classFigure);
+ contents.add(classFigure2);
+ contents.add(c);
+
+ lws.setContents(contents);
+ shell.open();
+ while (!shell.isDisposed())
+ while (!d.readAndDispatch())
+ d.sleep();
+ }
+}</pre></td>
+ </tr>
+</table>
+<H1>Conclusions</H1>
+<P>This article has served as an introduction to the customized use of
+the Graphical Editing Framework's visual component, Draw2d figures. The
+concepts of Draw2d connections, decorations, and locators have also been
+introduced. For more information on GEF, see the GEF website. (<A
+ href="http://www.eclipse.org/gef">http://www.eclipse.org/gef</A>).</P>
+<H2><BR>
+Acknowledgements</H2>
+<P>The author would like to thank Randy Hudson and Eric Bordeau for
+providing constructive comments on the article.</P>
+<P><SMALL>Java and all Java-based trademarks and logos are trademarks or
+registered trademarks of Sun Microsystems, Inc. in the United States,
+other countries, or both.</SMALL></P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/Article-GEF-Draw2d/images/Idea.jpg b/Article-GEF-Draw2d/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-GEF-Draw2d/images/Idea.jpg
Binary files differ
diff --git a/Article-GEF-Draw2d/images/UMLDiagGIF.gif b/Article-GEF-Draw2d/images/UMLDiagGIF.gif
new file mode 100644
index 0000000..3c8e9f5
--- /dev/null
+++ b/Article-GEF-Draw2d/images/UMLDiagGIF.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/classDiagConnectionGIF.gif b/Article-GEF-Draw2d/images/classDiagConnectionGIF.gif
new file mode 100644
index 0000000..3e9f5b0
--- /dev/null
+++ b/Article-GEF-Draw2d/images/classDiagConnectionGIF.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/classDiagDecoGIF.gif b/Article-GEF-Draw2d/images/classDiagDecoGIF.gif
new file mode 100644
index 0000000..1dbcae1
--- /dev/null
+++ b/Article-GEF-Draw2d/images/classDiagDecoGIF.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/classDiagGIF.gif b/Article-GEF-Draw2d/images/classDiagGIF.gif
new file mode 100644
index 0000000..b7a9f55
--- /dev/null
+++ b/Article-GEF-Draw2d/images/classDiagGIF.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/classDiagLabelsGIF.gif b/Article-GEF-Draw2d/images/classDiagLabelsGIF.gif
new file mode 100644
index 0000000..bfb9598
--- /dev/null
+++ b/Article-GEF-Draw2d/images/classDiagLabelsGIF.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/class_obj.gif b/Article-GEF-Draw2d/images/class_obj.gif
new file mode 100644
index 0000000..cf33d93
--- /dev/null
+++ b/Article-GEF-Draw2d/images/class_obj.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/field_private_obj.gif b/Article-GEF-Draw2d/images/field_private_obj.gif
new file mode 100644
index 0000000..864feee
--- /dev/null
+++ b/Article-GEF-Draw2d/images/field_private_obj.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/linux_only.gif b/Article-GEF-Draw2d/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-GEF-Draw2d/images/linux_only.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/methpub_obj.gif b/Article-GEF-Draw2d/images/methpub_obj.gif
new file mode 100644
index 0000000..ecf40d2
--- /dev/null
+++ b/Article-GEF-Draw2d/images/methpub_obj.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/tag_1.gif b/Article-GEF-Draw2d/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-GEF-Draw2d/images/tag_1.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/tag_2.gif b/Article-GEF-Draw2d/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-GEF-Draw2d/images/tag_2.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/tag_3.gif b/Article-GEF-Draw2d/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-GEF-Draw2d/images/tag_3.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/tag_4.gif b/Article-GEF-Draw2d/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-GEF-Draw2d/images/tag_4.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/tag_5.gif b/Article-GEF-Draw2d/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-GEF-Draw2d/images/tag_5.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/tag_6.gif b/Article-GEF-Draw2d/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-GEF-Draw2d/images/tag_6.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/tag_7.gif b/Article-GEF-Draw2d/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-GEF-Draw2d/images/tag_7.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/tip.gif b/Article-GEF-Draw2d/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-GEF-Draw2d/images/tip.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/tryit.gif b/Article-GEF-Draw2d/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-GEF-Draw2d/images/tryit.gif
Binary files differ
diff --git a/Article-GEF-Draw2d/images/win_only.gif b/Article-GEF-Draw2d/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-GEF-Draw2d/images/win_only.gif
Binary files differ
diff --git a/Article-GEF-EMF/article_style.css b/Article-GEF-EMF/article_style.css
new file mode 100644
index 0000000..971fa21
--- /dev/null
+++ b/Article-GEF-EMF/article_style.css
@@ -0,0 +1,25 @@
+table.content {
+ background-color: white;
+ text-align: left;
+ margin-left:auto;
+ margin-right:auto;
+ cellpadding: 20;
+}
+div.figure {
+ background-color: white;
+ text-align: center;
+}
+div.fileContent {
+ background-color: white;
+ text-align: left;}
+div.figure-caption {
+ text-align: center;
+ border-top-width: thin;
+ border-right-width: thin;
+ border-bottom-width: thin;
+ border-left-width: thin;
+ border-top-style: solid;
+ border-top-color: #FFFFFF;}
+span.figure-number { font-weight: bold;}
+pre.program { margin-left: 1em; margin-right: 1em; padding: 5px; background-color: whitesmoke;}
+
diff --git a/Article-GEF-EMF/files/shapesemf.zip b/Article-GEF-EMF/files/shapesemf.zip
new file mode 100644
index 0000000..c81fa94
--- /dev/null
+++ b/Article-GEF-EMF/files/shapesemf.zip
Binary files differ
diff --git a/Article-GEF-EMF/files/shapesmerlin.zip b/Article-GEF-EMF/files/shapesmerlin.zip
new file mode 100644
index 0000000..5841eea
--- /dev/null
+++ b/Article-GEF-EMF/files/shapesmerlin.zip
Binary files differ
diff --git a/Article-GEF-EMF/files/shapesrcp.zip b/Article-GEF-EMF/files/shapesrcp.zip
new file mode 100644
index 0000000..2faf727
--- /dev/null
+++ b/Article-GEF-EMF/files/shapesrcp.zip
Binary files differ
diff --git a/Article-GEF-EMF/gef-emf.html b/Article-GEF-EMF/gef-emf.html
new file mode 100644
index 0000000..30aa6f8
--- /dev/null
+++ b/Article-GEF-EMF/gef-emf.html
@@ -0,0 +1,758 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+ <head>
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+ <meta name="author" content="Chris Aniszczyk">
+
+ <title>Using GEF with EMF</title>
+ <link type="text/css" rel="stylesheet" href="../default_style.css">
+ <link type="text/css" rel="stylesheet" href="article_style.css">
+ </head>
+
+ <body>
+ <div align="right">
+ &nbsp; <span class="copy">Copyright &copy; 2005 IBM Corporation</span>
+
+ <table border="0" cellpadding="2" cellspacing="0" width="100%">
+ <tbody>
+ <tr>
+ <td colspan="2" align="left" bgcolor="#0080C0" valign="top"><span
+ class="corner">&nbsp;Eclipse Corner Article</span> </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div align="left">
+ <h1><img src="../images/Idea.jpg" height="86" width="120" align=
+ "middle"></h1>
+ </div>
+
+ <p>&nbsp;</p>
+
+ <h1 align="center">Using GEF with EMF</h1>
+
+ <blockquote>
+ <p><b>Summary</b></p>
+
+ <p>The Graphical Editing Framework (GEF) provides a framework for
+ creating visual editors while being model agnostic. In most cases, people
+ bring their own model which tend to be based on Plain Old Java Objects
+ (POJOs). An alternative using POJOs is the Eclipse Modeling Framework
+ (EMF), which provides many features for manipulating models that aren't
+ found in POJOs. The purpose of this article is to build upon the shapes
+ example provided by GEF using the Eclipse Modeling Framework (EMF) and to
+ provide an introduction using EMF based models in GEF based editors.</p>
+
+ <p><b>Chris Aniszczyk, IBM</b><br>
+ <font size="-1">June 8, 2005</font></p>
+ </blockquote>
+ <hr>
+
+ <h3>Environment</h3>
+
+ <p>The examples in this article were built and tested on:</p>
+
+ <ul>
+ <li><a href=
+ "http://download.eclipse.org/eclipse/downloads/drops/S-3.1RC1-200505271300/index.php">
+ Eclipse 3.1RC1</a></li>
+
+ <li><a href=
+ "http://download.eclipse.org/tools/gef/downloads/drops/S-3.1M7-200505231916/index.php">
+ GEF 3.1M7</a></li>
+
+ <li><a href=
+ "http://download.eclipse.org/tools/emf/scripts/downloads-viewer.php?s=2.1.0/I200505261142">
+ EMF 2.1.0</a></li>
+ </ul>
+
+ <p>There is no guarantee the examples will work with other versions.</p>
+
+
+ <h2>Introduction</h2>
+
+ <p>The <a href="http://www.eclipse.org/gef">Graphical Editing Framework
+ (GEF)</a> assumes that you have a model of some type. The <i>type</i> in
+ most cases, is a set of custom Java classes created to suit the needs of an
+ application. Overlaying the model, users would implement their own observer
+ pattern. For example, when an object changes state, GEF becomes aware of
+ the change, and performs the appropriate action, such as redrawing a figure
+ due to a move request. Users spend time building their own viewers (i.e.
+ properties) and deciding how the model should be persisted. Most novices
+ learning GEF don't realize EMF can help with several modeling issues
+ previously mentioned. The <a href="http://www.eclipse.org/emf">Eclipse
+ Modeling Framework (EMF)</a> is a Java framework and code generation
+ facility for building tools and other applications based on a structured
+ model. EMF consists of two fundamental frameworks: the core framework,
+ responsible for basic code generation, and runtime, responsible for
+ creation of Java implementation classes for a model. The EMF.edit framework
+ builds on the core framework to add support for generating adapter classes
+ that enable viewing and command-based editing of a model. Furthermore, EMF
+ provides a free adapter that listens for model changes, a requirement when
+ building a GEF editor. In addition, EMF includes default support for
+ persistence using XMI or XML (you can write your custom persistence layer
+ by extending a few classes) <a href="#EMFOverview">[1]</a>.</p>
+
+ <p>The purpose of the article is to build upon the shapes example that was
+ extensively evaluated in a previous Eclipse Corner article <a href=
+ "#">[2]</a>. The shapes model currently exists as a custom set of Java
+ objects, this article illustrates how to transform the shapes model into an
+ EMF-based model. The transformation occurs in two major steps: mapping
+ custom Java objects to an EMF model, and modify EditParts to use the new
+ features available in EMF.</p>
+
+ <h2>Shapes Transformation</h2>
+
+ <p>The transformation of the Shapes example will occur in the following
+ order:</p>
+
+ <ul>
+ <li>Map POJOs to an EMF model</li>
+
+ <li>Use PropertySources with your EMF model</li>
+
+ <li>Change EditPart to reflect new behavior of EMF models</li>
+ </ul>
+
+ <h3>Current Model</h3>
+
+ <p>The current shapes model (<b>see Figure 1</b>) was designed for
+ simplicity and for instructional purposes. It consists of the following
+ classes:</p>
+
+ <ul>
+ <li>
+ <i>ModelElement</i>
+
+ <ul>
+ <li>The base class of all shapes model objects. It serves two main
+ purposes: notification and property source support for the Eclipse
+ property viewer. This class will no longer be needed when
+ transitioning to EMF because EMF provides the necessary facilities to
+ listen for model changes and EMF.Edit provides property support.</li>
+ </ul>
+ </li>
+
+ <li>
+ <i>ShapesDiagram</i>
+
+ <ul>
+ <li>A container object to hold a collection of shapes.</li>
+ </ul>
+ </li>
+
+ <li>
+ <i>Connection</i>
+
+ <ul>
+ <li>A connection between two shapes codified into a source and target
+ connection.</li>
+ </ul>
+ </li>
+
+ <li>
+ <i>Shape</i>
+
+ <ul>
+ <li>An abstract class that represents a shape. It includes various
+ information regarding visual representation, including the source and
+ target connections of the object.</li>
+ </ul>
+ </li>
+
+ <li>
+ <i>RectangularShape / EllipticalShape</i>
+
+ <ul>
+ <li>Special classes that represent two types of <i>Shape</i>s:
+ rectangular and elliptical.</li>
+ </ul>
+ </li>
+ </ul>
+
+ <div class="figure">
+ <img src="images/shapesmodel.png"><br>
+
+
+ <div class="figure-caption">
+ <span class="figure-number">Figure 1</span>: Summarized Shapes Model
+ (without ModelElement)
+ </div>
+ </div>
+
+ <h3>Transformed Model</h3>
+
+ <p>To transform the simple shapes model, we must map it an EMF model. This
+ can be accomplished in many ways (i.e. XSD, Java, UML) and is discussed
+ further at the EMF documentation site <a href="#EMFDocumentation">[3]</a>.
+ For simplicity, this article will only focus on using annotated Java as EMF
+ input. Listed below are sketches representing the old shapes model and
+ their corresponding annotated Java models. After we have these models, we
+ can use EMF to generate the rest of the code needed to interact with our
+ models.</p>
+
+ <p><img src="../images/tip.gif">A tutorial is available that describes how
+ to generate an EMF model from annotated Java <a href=
+ "#EMFTutorial">[4]</a>.</p>
+
+ <table class="content" cellspacing="20">
+ <tbody>
+ <tr>
+ <td><img src="images/shapesdiagram.png"> </td>
+
+ <td>
+<pre class="program">
+/** @model */
+public interface ShapesDiagram {
+
+ /** @model type="Shape" containment="true" */
+ public List getShapes();
+
+}
+</pre>
+
+ <center>
+ <b>ShapesDiagram.java</b>
+ </center>
+ </td>
+ </tr>
+
+ <tr>
+ <td><img src="images/connection.png"> </td>
+
+ <td>
+<pre class="program">
+/** @model */
+public interface Connection {
+
+ /** @model */
+ public Shape getSource();
+
+ /** @model */
+ public Shape getTarget();
+
+ /** @model */
+ public boolean isDashed();
+
+ /** @model */
+ public void reconnect();
+
+ /** @model */
+ public void disconnect();
+
+}
+</pre>
+
+ <center>
+ <b>Connection.java</b>
+ </center>
+ </td>
+ </tr>
+
+ <tr>
+ <td><img src="images/shape.png"> </td>
+
+ <td>
+<pre class="program">
+/** @model abstract="true" */
+public interface Shape {
+
+ /** @model */
+ public int getX();
+
+ /** @model */
+ public int getY();
+
+ /** @model */
+ public int getWidth();
+
+ /** @model default="0" */
+ public int getHeight();
+
+ /** @model type="Connection" containment="true" */
+ List getSourceConnections();
+
+ /** @model type="Connection" */
+ List getTargetConnections();
+
+}
+</pre>
+
+ <center>
+ <b>Shape.java</b>
+ </center>
+ </td>
+ </tr>
+
+ <tr>
+ <td><img src="images/shapetypes.png"> </td>
+
+ <td>
+<pre class="program">
+/** @model */
+public interface RectangularShape extends Shape {
+
+}
+</pre>
+
+ <center>
+ <b>RectangularShape.java</b>
+ </center>
+<pre class="program">
+/** @model */
+public interface EllipticalShape extends Shape {
+
+}
+</pre>
+
+ <center>
+ <b>EllipticalShape.java</b>
+ </center>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h3>Properties for your EMF model</h3>
+
+ <p>Before I discuss how to add properties to your EMF model, I would like
+ to bring up the issue of notational model and semantic model separation. It
+ is considered good design to separate visual information from semantic
+ information. In the original shapes example, there was no logical
+ separation of the notational (visual) information, like size and location,
+ from the semantic information. For simplicity, this example will not
+ separate visual information from semantic information. Note the original
+ shapes example didn't have semantic information unless you can imagine the
+ shape model having a name attribute that would specify the name of a shape.
+ If you are curious to see this type of separation, the <a href=
+ "#Future">Looking to the Future</a> section discussed in this article
+ contains information of interest.</p>
+
+ <p>Eclipse provides a properties view that allows for the manipulation of
+ currently selected object properties as long as the object adheres to the
+ <i>IPropertySource</i> interface. In GEF, <i>AbstractEditPart</i> checks if
+ its model implements <i>IPropertySource</i>, if so the model is returned so
+ the Eclipse properties view can take advantage of it.</p>
+
+ <p>For simplicity reasons this example isn't taking advantage of EMF.edit
+ property source generation support. The reason being is that EMF and GEF
+ use different command stacks and command interfaces so they can't be used
+ together easily. In order to take advantage of EMF.edit, the user needs to
+ wrap EMF commands with GEF commands. If you think you are hot stuff, you
+ can further investigate this issue <a href="#CommandStackBug1">[5]</a> <a
+ href="#CommandStackBug2">[6]</a> in a few ways:</p>
+
+ <ul>
+ <li>Eclipse 3.1 features a common command infrastructure <a href=
+ "#CommonCommand">[7]</a> that projects may pick up.</li>
+
+ <li>The Graphical Modeling Framework (GMF) <a href="#GMFWebpage">[8]</a>
+ is an upcoming project and is discussed in <a href="#Future">Looking to
+ the Future</a> section.</li>
+
+ <li>The Merlin Generator Framework <a href="#MerlinWebpage">[9]</a>
+ discussed in <a href="#Future">Looking to the Future</a> contains
+ examples of using EMF.Edit with GEF based editors (there's also an
+ example in this article).</li>
+
+ <li>Examine GEF 3.1 EDiagram example <a href=
+ "#EDiagramCVSOldProperties">[10]</a> (older version used EMF.Edit to
+ display properties).</li>
+ </ul>
+
+ <p>In order to take advantage of Eclipse properties views we create classes
+ that implement the <i>IPropertySource</i> interface. To investigate how
+ this is accomplished, it is recommended to look at
+ <i>AbstractPropertySource</i> and its implementers. Listed below is an
+ example implementation, <i>ConnectionPropertySource</i> which needs to
+ define how a property is <img src="../images/tag_1.gif">retrieved and <img
+ src="../images/tag_2.gif">set.</p>
+<pre class="program">
+public class ConnectionPropertySource extends AbstractPropertySource {
+
+...
+
+ <img src="../images/tag_1.gif">public Object getPropertyValue(Object id) {
+ if(id == ID_STYLE) {
+ return Boolean.toString(getConnectionModel().isDashed());
+ }
+ return null;
+ }
+
+ <img src=
+"../images/tag_2.gif">public void setPropertyValue(Object id, Object value) {
+ if(id == ID_STYLE) {
+ getConnectionModel().setDashed(Boolean.valueOf((String) value));
+ }
+ }
+
+...
+
+}
+</pre>
+
+ <center>
+ <b>ConnectionPropertySource.java</b>
+ </center>
+
+ <h3>Listening to your EMF model</h3>
+
+ <p>In GEF, the EditParts act as controllers and receive notice of input and
+ then properly direct changes to its model and view objects. It also keeps
+ track of connections between the model objects and any other communication.
+ In the original shapes example <a href="#ShapeArticle">[2]</a>, every model
+ object extended the abstract class <i>ModelElement</i> which included
+ support for adding and removing listeners from model objects. This type of
+ behavior is possible with EMF since every EMF Object (<i>EObject</i>) is
+ also a <i>Notifier</i> which supports listening for objects.</p>
+
+ <p>We'll use the EditPart that represents a shape in the new example. In
+ <i>ShapeEditPart</i> we added a convenience method <i>hookIntoModel</i>
+ which provides the ability to pass a model object and <img src=
+ "../images/tag_1.gif">add a listener to the model. In order to add
+ listeners to EMF model objects, our listener (the EditPart) must implement
+ the <i>Adapter</i> interface. An important part of this interface is the
+ <i>notifyChanged</i> method which serves as the point where we will analyze
+ the types of changes that happen to our EMF model and act on them.
+ Furthermore, EMF provides the ability to filter based on the type of
+ notification your listener receives, whether it is a <img src=
+ "../images/tag_2.gif">set, <img src="../images/tag_4.gif">add, remove,
+ etc... (take a peek at the <i>Notification</i> class for what other filters
+ exist). The first case is when a visual value like <img src=
+ "../images/tag_3.gif">x-coordinate, y-coordinate, width or height is set.
+ Once we establish that a set happened on any of these visual elements, we
+ can properly call the <i>refreshVisuals</i> method to redraw the figure.
+ The next case is when a <img src="../images/tag_5.gif">source connection or
+ a target connection is <img src="../images/tag_4.gif">removed or added.
+ Since we know what type of connection is added or removed, we can tell the
+ EditPart which type of connections need to be refreshed.</p>
+
+ <table align="center" cellspacing="20">
+ <tbody>
+ <tr>
+ <td>
+<pre class="program">
+private void hookIntoModel(EObject model) {
+ if(model != null) {
+ <img src="../images/tag_1.gif">model.eAdapters().add(this);
+ }
+}
+</pre>
+
+ <center>
+ <b>ShapeEditPart.java</b>
+ </center>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+<pre class="program">
+public void notifyChanged(Notification notification) {
+ int type = notification.getEventType();
+ int featureId = notification.getFeatureID(ModelPackage.class);
+ switch(type) {
+ <img src="../images/tag_2.gif">case Notification.SET:
+ switch(featureId) {
+ <img src="../images/tag_3.gif">case ModelPackage.SHAPE__X:
+ <img src="../images/tag_3.gif">case ModelPackage.SHAPE__Y:
+ <img src="../images/tag_3.gif">case ModelPackage.SHAPE__WIDTH:
+ <img src="../images/tag_3.gif">case ModelPackage.SHAPE__HEIGHT:
+ refreshVisuals();
+ break;
+ }
+ <img src="../images/tag_4.gif">case Notification.ADD:
+ <img src="../images/tag_4.gif">case Notification.REMOVE:
+ switch(featureId) {
+ <img src=
+"../images/tag_5.gif">case ModelPackage.SHAPE__SOURCE_CONNECTIONS:
+ refreshSourceConnections();
+ break;
+ <img src=
+"../images/tag_5.gif">case ModelPackage.SHAPE__TARGET_CONNECTIONS:
+ refreshTargetConnections();
+ break;
+ }
+ }
+ }
+</pre>
+
+ <center>
+ <b>ShapeEditPart.java</b>
+ </center>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h2 id="Future">Looking to the Future</h2>
+
+ <p>There has been a considerable amount of work done trying to unite two of
+ the most popular Eclipse projects: EMF and GEF. In this section, I will
+ discuss some of that work and where it is headed. Also, this section serves
+ the ancillary purpose of pointing you to more complex examples if you gain
+ mastery of the example discussed in this article.</p>
+
+ <h3>GEF 3.1 EDiagram Example</h3>
+
+ <p>The GEF 3.1 release will include a new example (<b>see Figure 2</b>)
+ that lets you visualize and edit EMF models (Ecore). The source code is
+ available in CVS and is viewable online <a href="#EDiagramCVS">[11]</a>.
+ This example is fairly complex, but it illustrates how to separate
+ notational (diagram) logic from semantic (business) logic. It accomplishes
+ this by creating an EMF model EDiagram that represents the diagram logic.
+ Inside this model is the typical information associated with diagrams:
+ location, size, incoming connections, outgoing connections, etc.... The
+ semantic information is provided in the EMF model (.ecore file). I believe
+ the Shapes EMF example will serve as a good stepping stone in understanding
+ the complexities of the EDiagram example.</p>
+
+ <div class="figure">
+ <img src="images/ediagram.jpg">
+
+ <div class="figure-caption">
+ <span class="figure-number">Figure 2</span>: EDiagram Example (picture
+ shamelessly stolen from Ed Merks)
+ </div>
+ </div>
+
+ <h3>Graphical Modeling Framework (GMF)</h3>
+
+ <p>The GMF <a href="#GMFWebpage">[8]</a> is a new Eclipse project that is
+ currently in validation phase and entering the implementation phase soon.
+ The goal of GMF is to form a generative bridge between EMF and GEF, whereby
+ a diagram definition will be linked to a domain model as input to the
+ generation of a visual editor. The main components of GMF will be a
+ diagramming infrastructure that will provide a set of base diagramming
+ components that serve as a target for the next component, a diagram
+ generation framework. The Diagram Generation framework will use the diagram
+ definition input and generate code that is part of GMF's final component,
+ in addition it will provide exemplary modeling tools <a href=
+ "#GMFRequirements">[12]</a>. I encourage readers to browse the GMF <a href=
+ "news://news.eclipse.org/eclipse.technology.gmf">newsgroup</a> and webpage
+ <a href="#GMFWebpage">[8]</a> for more information. I believe the GMF
+ project will address a lot of the current concerns with building GEF
+ editors based on EMF models and make the process a lot easier.</p>
+
+
+ <h3>Merlin Generator Project</h3>
+
+ <p>Merlin is a free Eclipse plugin (EPL) <a href="#MerlinWebpage">[9]</a>,
+ based on EMF, that provides enhanced code generation and model
+ transformation tools. Also, Merlin comes with a set of wizards and editors
+ for customizing code generation and model transformations (including a JET
+ file editor with syntax coloring, code completion and validation). An
+ interesting subset of Merlin includes a built-in GEF generator (created
+ with Merlin's own mappings and templates) that allows users to generate GEF
+ editors from any EMF based model. Similar to the EDiagram example, this GEF
+ generator produces editors that store semantic and notational information
+ in different files. Additionally, the generator options can be amended so
+ custom figures are used for the EditParts. There are more features
+ contained with Merlin that won't be discussed since I deemed them outside
+ the scope of this article. Note that some of the features of Merlin may end
+ up in the GMF project as Merlin is a possible initial contributor.</p>
+
+ <p>To show the capabilities of Merlin and add some excitement to this
+ article, I used the shapes EMF model as input to Merlin and generated a
+ functional GEF editor (<b>see Figure 3</b>) that uses EMF for its model. It
+ took me all of a few seconds to create a fully functional EMF-based GEF
+ editor. I recommend users to look at Merlin once they are familiar with the
+ basics and look to tackle more complex problems. Note, there are two
+ examples with Merlin: There is a .gefgenmodel included with the shapes EMF
+ example and there is a separate contribution by the author of Merlin that
+ shows off a bit more advanced generation.</p>
+
+ <p><img src="../images/tip.gif">Used <a href=
+ "http://sourceforge.net/project/showfiles.php?group_id=125827&amp;package_id=137615&amp;release_id=330085">
+ Merlin 0.4.9</a> in this article<br>
+ </p>
+
+ <div class="figure">
+ <img src="images/shapesmerlin.png">
+
+ <div class="figure-caption">
+ <span class="figure-number">Figure 3</span>: Merlin based GEF editor using
+ a shapes model as input
+ </div>
+ </div>
+
+ <h2>Bonus: Shapes Example goes RCP!</h2>
+
+ <p>I spend a considerable amount of time browsing the Eclipse newsgroups
+ and one of the questions that comes up frequently in regards to GEF is
+ <i>how to use my GEF editor in an RCP based application</i>. I believe this
+ question is going to get asked more as the Eclipse 3.1 release sufficiently
+ increases the ease in building and deploying RCP-based applications. So,
+ for my last magic trick and to reward readers who got to this point, I'll
+ discuss how to convert the original shapes example into an RCP-based one
+ and provide the code!</p>
+
+ <p><img src="../images/tip.gif">If you are unfamiliar with RCP, the <a
+ href="http://www.eclipse.org/rcp/faq.html">RCP FAQ</a> is a good start.</p>
+
+ <p>The conversion of the shapes example into an RCP-based application is a
+ lot simpler than most people think. The problem stems from the
+ <i>setInput</i> method of <i>ShapesEditor</i> expecting an
+ <i>IEditorInput</i>, but the most familiar editor input people work with is
+ <i>IFileEditorInput</i>. The problem with <i>IFileEditorInput</i> is that
+ it belongs to the pesky <b>org.eclipse.ui.ide</b> plugin which is not an
+ acceptable dependency for an RCP-based application. The solution to this
+ problem is to simply create our own editor input, <i>ShapesEditorInput</i>
+ which implements the <i>IEditorInput</i> interface via
+ <i>IPathEditorInput</i> interface. Once this change is completed and the
+ <i>setInput</i> method is properly changed in <i>ShapesEditor</i> to use
+ <i>ShapesEditorInput</i>, we can now properly open a shapes editor. Note,
+ the sole purpose of this example is to demonstrate how to get a GEF editor
+ inside of an RCP application, it doesn't include support for various
+ actions such as saving or wizards (I leave this for the reader to
+ explore).</p>
+
+ <p><img src="../images/tip.gif">This concept of creating your own
+ <i>IEditorInput</i> can be applied to creating editors that aren't file
+ based (i.e. an editor which is based off of data from a database).</p>
+
+ <table align="center" cellspacing="20">
+ <tbody>
+ <tr>
+ <td>
+ <div class="figure">
+ <img src="images/shapesrcp.png">
+
+ <div class="figure-caption">
+ <span class="figure-number">Figure 4</span>: Shapes RCP Example
+ Product
+ </div>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+<pre class="program">
+/**
+ * Uses a ShapesEditorInput to serve as a dummy editor input
+ * It is up to the editor input to supply the initial shapes diagram
+ *
+ * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
+ */
+protected void setInput(IEditorInput input) {
+ super.setInput(input);
+ ShapesEditorInput shapesInput = ((ShapesEditorInput) input);
+ diagram = shapesInput.getShapesDiagram();
+ setPartName(shapesInput.getName());
+}
+</pre>
+
+ <center>
+ <b>ShapesEditor.java</b>
+ </center>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h2>Summary</h2>
+
+ <p>I made an attempt at giving you a simple example to learn how to
+ integrate EMF with GEF editors. I discussed step-by-step how to transform
+ the original shapes example into a EMF-based one. Also, I included
+ discussion of upcoming work that may yield more complex examples that you
+ may learn from using some of the knowledge gleaned from studying the shapes
+ EMF example. For my more attentive readers, I included an example that
+ ported the original shapes example to an RCP-based one. I understand that
+ there is a high learning curve associated with these two complex frameworks
+ and almost anything Eclipse related, but my hope is you will use the
+ examples illustrated here as stepping stones to build your knowledge base.
+ Happy hacking :)</p>
+
+ <h3>Example Downloads</h3>
+
+ <ul>
+ <li><a href="files/shapesemf.zip">Shapes EMF</a></li>
+
+ <li><a href="files/shapesrcp.zip">Shapes RCP</a></li>
+
+ <li><a href="files/shapesmerlin.zip">Shapes Merlin</a></li>
+ </ul>
+
+
+ <h2>Acknowledgments</h2>
+
+ <p>I'd like to thank:</p>
+
+ <ul>
+ <li>Richard Gronback for information regarding GMF.</li>
+
+ <li>Joel Cheuoua for various corrections regarding Merlin and updating my
+ Merlin example.</li>
+
+ <li>Ed Merks for half the posts on the EMF newsgroup, his screenshot and
+ for his feedback on this article.</li>
+
+ <li>Sushma Patel for reviewing the article and correcting my horrible
+ grammar.</li>
+ </ul>
+
+
+ <h2>Bibliography</h2>
+
+ <p>[1] <a name="EMFOverview" href=
+ "http://eclipse.org/emf/docs.php?doc=references/overview/EMF.html">The
+ Eclipse Modeling Framework (EMF) Overview</a>, EMF Website</p>
+
+ <p>[2] <a name="ShapeArticle" href=
+ "http://www.eclipse.org/articles/Article-GEF-diagram-editor/shape.html">A
+ Shape Diagram Editor</a>, Eclipse Corner Article</p>
+
+ <p>[3] <a name="EMFDocumentation" href=
+ "http://www.eclipse.org/emf/docs.php">EMF Documentation</a>, EMF
+ Website</p>
+
+ <p>[4] <a name="EMFTutorial" href=
+ "http://eclipse.org/emf/docs.php?doc=tutorials/clibmod/clibmod.html">Generating
+ an EMF Model</a>, EMF Website</p>
+
+ <p>[5] <a name="CommandStackBug1" href=
+ "https://bugs.eclipse.org/bugs/show_bug.cgi?id=29939">Eclipse Bug
+ #29939</a>, Eclipse Bugzilla</p>
+
+ <p>[6] <a name="CommandStackBug2" href=
+ "https://bugs.eclipse.org/bugs/show_bug.cgi?id=37716">Eclipse Bug
+ #37716</a>, Eclipse Bugzilla</p>
+
+ <p>[7] <a name="CommonCommand" href=
+ "http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.commands/">org.eclipse.core.commands</a>,
+ Eclipse CVS</p>
+
+ <p>[8] <a name="GMFWebpage" href="http://www.eclipse.org/gmf">GMF
+ Homepage</a>, GMF Website</p>
+
+ <p>[9] <a name="MerlinWebpage" href=
+ "http://sourceforge.net/projects/merlingenerator/">Merlin Homepage</a>,
+ Merlin Website</p>
+
+ <p>[10] <a name="EDiagramCVSOldProperties" href=
+ "http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.gef.examples.ediagram/src/org/eclipse/gef/examples/ediagram/model/properties/emf/?cvsroot=Tools_Project&amp;only_with_tag=oldProperties">
+ EDiagram Old Properties Source</a>, GEF CVS</p>
+
+ <p>[11] <a name="EDiagramCVS" href=
+ "http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.gef.examples.ediagram/?cvsroot=Tools_Project">
+ EDiagram Example Source</a>, GEF CVS</p>
+
+ <p>[12] <a name="GMFRequirements" href=
+ "http://www.eclipse.org/gmf/requirements.html">GMF Requirements</a>, GMF
+ Website</p>
+
+ <p><small>ref: <a href=
+ "https://bugs.eclipse.org/bugs/show_bug.cgi?id=91472">bug
+ 91472</a></small></p>
+
+ <p><small>Java and all Java-based trademarks and logos are trademarks or
+ registered trademarks of Sun Microsystems, Inc. in the United States, other
+ countries, or both.</small></p>
+ </body>
+</html>
+
diff --git a/Article-GEF-EMF/images/connection.png b/Article-GEF-EMF/images/connection.png
new file mode 100644
index 0000000..fd523d7
--- /dev/null
+++ b/Article-GEF-EMF/images/connection.png
Binary files differ
diff --git a/Article-GEF-EMF/images/ediagram.jpg b/Article-GEF-EMF/images/ediagram.jpg
new file mode 100644
index 0000000..9a57270
--- /dev/null
+++ b/Article-GEF-EMF/images/ediagram.jpg
Binary files differ
diff --git a/Article-GEF-EMF/images/shape.png b/Article-GEF-EMF/images/shape.png
new file mode 100644
index 0000000..48e51f4
--- /dev/null
+++ b/Article-GEF-EMF/images/shape.png
Binary files differ
diff --git a/Article-GEF-EMF/images/shapesdiagram.png b/Article-GEF-EMF/images/shapesdiagram.png
new file mode 100644
index 0000000..76ca051
--- /dev/null
+++ b/Article-GEF-EMF/images/shapesdiagram.png
Binary files differ
diff --git a/Article-GEF-EMF/images/shapesmerlin.png b/Article-GEF-EMF/images/shapesmerlin.png
new file mode 100644
index 0000000..3f33c7e
--- /dev/null
+++ b/Article-GEF-EMF/images/shapesmerlin.png
Binary files differ
diff --git a/Article-GEF-EMF/images/shapesmodel.png b/Article-GEF-EMF/images/shapesmodel.png
new file mode 100644
index 0000000..cc3c68a
--- /dev/null
+++ b/Article-GEF-EMF/images/shapesmodel.png
Binary files differ
diff --git a/Article-GEF-EMF/images/shapesrcp.png b/Article-GEF-EMF/images/shapesrcp.png
new file mode 100644
index 0000000..fd845cf
--- /dev/null
+++ b/Article-GEF-EMF/images/shapesrcp.png
Binary files differ
diff --git a/Article-GEF-EMF/images/shapetypes.png b/Article-GEF-EMF/images/shapetypes.png
new file mode 100644
index 0000000..8779a85
--- /dev/null
+++ b/Article-GEF-EMF/images/shapetypes.png
Binary files differ
diff --git a/Article-GEF-diagram-editor/default_style.css b/Article-GEF-diagram-editor/default_style.css
new file mode 100644
index 0000000..1213bf0
--- /dev/null
+++ b/Article-GEF-diagram-editor/default_style.css
@@ -0,0 +1,49 @@
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body {
+ font-family: arial, helvetica, geneva;
+ font-size: 10pt;
+ clip: rect( );
+ margin-top: 5mm;
+ margin-left: 3mm
+}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
+
+div.figure {
+}
+
+div.figure-caption {
+ text-align: center;
+}
+
+span.figure-number {
+ font-weight: bold;
+}
+
+pre.program {
+ margin-left: 1em;
+ margin-right: 1em;
+ padding: 5px;
+ background-color: whitesmoke;
+}
+
+dt {
+ font-weight: bold;
+ margin-left: 2ex;
+}
+
+dd {
+ margin-left: 5ex;
+}
+
+a.cite {
+ text-decoration: none;
+ background-color: whitesmoke;
+}
diff --git a/Article-GEF-diagram-editor/images/Idea.jpg b/Article-GEF-diagram-editor/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/Idea.jpg
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/delete_action3.gif b/Article-GEF-diagram-editor/images/delete_action3.gif
new file mode 100644
index 0000000..3dba96b
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/delete_action3.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/linux_only.gif b/Article-GEF-diagram-editor/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/linux_only.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/shape_screenshot2.jpg b/Article-GEF-diagram-editor/images/shape_screenshot2.jpg
new file mode 100644
index 0000000..b2f423c
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/shape_screenshot2.jpg
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/tag_1.gif b/Article-GEF-diagram-editor/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/tag_1.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/tag_2.gif b/Article-GEF-diagram-editor/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/tag_2.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/tag_3.gif b/Article-GEF-diagram-editor/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/tag_3.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/tag_4.gif b/Article-GEF-diagram-editor/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/tag_4.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/tag_5.gif b/Article-GEF-diagram-editor/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/tag_5.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/tag_6.gif b/Article-GEF-diagram-editor/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/tag_6.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/tag_7.gif b/Article-GEF-diagram-editor/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/tag_7.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/tip.gif b/Article-GEF-diagram-editor/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/tip.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/tryit.gif b/Article-GEF-diagram-editor/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/tryit.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/images/win_only.gif b/Article-GEF-diagram-editor/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-GEF-diagram-editor/images/win_only.gif
Binary files differ
diff --git a/Article-GEF-diagram-editor/shape.html b/Article-GEF-diagram-editor/shape.html
new file mode 100644
index 0000000..4563849
--- /dev/null
+++ b/Article-GEF-diagram-editor/shape.html
@@ -0,0 +1,1289 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+<head>
+ <title>A Shape Diagram Editor</title>
+ <link rel="stylesheet" href="default_style.css">
+ <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+ <meta name="author" content="Bo Majewski">
+</head>
+
+<body>
+<div align="right">
+ &nbsp; <span style="font-family:Times New Roman, Times, serif; font-size: small;">Copyright &copy; 2004 Cisco Systems Inc.</span>
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tbody>
+ <tr>
+ <td align="left" valign="top" colspan="2" bgcolor="#0080C0">
+ <span style="font-family: Arial,Helvetica; font-weight: bold; color: #ffffff;">&nbsp;Eclipse
+ Corner Article</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align="middle" alt="tag"></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 align="center">A Shape Diagram Editor</h1>
+
+<blockquote>
+ <b>Summary</b>
+ <br>
+ <p> Graphical Editing Framework (GEF) provides a powerful foundation for creating
+ editors for visual editing of arbitrary models. Its effectiveness lies in
+ a modular build, fitting use of design patterns, and decoupling of components
+ that comprise a full, working editor. To a newcomer, the sheer number and
+ variety of concepts and techniques present in GEF may feel intimidating. However,
+ once learned and correctly used, they help to develop highly scalable and
+ easy to maintain software. This article aims to provide a gentle yet comprehensive
+ introduction to GEF. It describes a shape diagram editor - a small, fully
+ functional test case of core concepts. </p>
+
+ <p>
+ <b> By Bo Majewski, Cisco Systems, Inc.</b>
+ <br>
+ <font size="-1">December 8, 2004</font> </p>
+</blockquote>
+
+<hr width="100%">
+
+<h2>Introduction</h2>
+
+<p> <a href="http://www.eclipse.org/gef/">Graphical Editing Framework</a> (GEF)
+ has been designed to allow editing of user data, generally referred to as <em>the
+ model</em>, using graphical rather than textual format. It becomes an invaluable
+ tool when dealing with entities that contain many-to-many, one-to-many and other
+ complex relationships. With the popularity of the Eclipse <a href="../Article-RCP-1/tutorial1.html">Rich
+ Client Platform</a>, which leads to development of editors for more than just
+ code, the importance of GEF is certain to increase. A few existing examples,
+ such as database schema editor <a class="cite" href="#zoio">[7]</a>, logical
+ circuits editor, and a task flow manager nicely illustrate both the power and
+ flexibility of the framework that may be applied to such varied and disparate
+ domains. </p>
+
+<p> Yet the trouble with any generic framework, and GEF is no exception, is that
+ its comprehensive design makes it hard to learn. Until recently, the smallest
+ available example came with over 75 classes. Trying to understand nuances of
+ GEF from interaction of that many user defined types and hundreds more native
+ to GEF is certain to test the patience and acumen of even the most diligent
+ developers. To rectify this issue, a new, much smaller example editor has been
+ added and will appear in the upcoming 3.1 release. The shape diagram editor
+ (see <a href="#fig1">Figure&nbsp;1</a>) allows you to create and edit simple
+ diagrams. It manipulates two types of objects, represented by rectangles and
+ ellipses. You may connect any two objects with one of the two connection types.
+ The two connection types are represented by solid and dashed lines. Each connection
+ is directed, in the sense that it starts at a source object and terminates in
+ the target object. The direction of each connection is indicated by an arrow.
+ A connection may be reattached by dragging its source or target to a new object.
+ Objects in the editor may be selected either by clicking on them or by dragging
+ a rubber band around them. Selected objects can be deleted. All model manipulations,
+ such as adding or deleting objects, moving them, resizing them, etc., may be
+ undone or redone. Finally, the editor integrates with the <em>Properties</em>
+ and <em>Outline</em> standard views of Eclipse. The editor's virtue comes not
+ from its usefulness, but rather from the fact its limited number of user defined
+ types serve as examples of a large percentage of concepts and techniques that
+ one could encounter in a mature GEF editor. </p>
+
+<a name="fig1"></a>
+<div class="figure">
+<center style="margin-bottom: 1em;">
+ <img src="images/shape_screenshot2.jpg" alt="Screen shot of the diagram editor" width="673" height="464">
+</center>
+<div class="figure-caption">
+ <span class="figure-number">Fig 1</span>. The shape diagram editor running under Linux
+</div>
+</div>
+
+<p>
+ <img src="images/tryit.gif" alt="Try it!" align="middle"> Download and unzip
+ the latest 3.1 GEF Examples from the
+ <a href="http://download.eclipse.org/tools/gef/downloads/">GEF Project
+ Downloads</a>
+ into your main Eclipse directory. To create
+ a new diagram, launch the wizard by pressing <em>Ctrl-N</em>. Expand the
+ <em>Examples</em> folder and select <em>Shapes Diagram</em>. The following
+ sections give a detailed overview of the shape diagram inner workings. Before
+ we dive into code, let us start with a big picture tour of the main
+ GEF ideas.
+</p>
+
+
+<h2>Core GEF concepts</h2>
+
+<p> GEF assists you in building a visual editor of your data. The data may be
+ as simple as a thermostat with a single temperature knob, or as complex as a
+ virtual private network with hundreds of routers, connections, and quality of
+ service policies. To the credit of the GEF designers, they managed to create
+ a framework that works with any data, or in GEF terminology, with any <b>model</b>.
+ This is achieved by strictly following the Model-View-Controller pattern. The
+ model is your data. To GEF, a model is any plain old Java object. The model
+ should not know anything about either the controller or the view. The <b>view</b>
+ is the visual representation of the model or one of its parts on the screen.
+ It may be as simple as a rectangle, line or ellipse, or as complex as a nested
+ logical circuit. Again, the view should remain ignorant about both the model
+ and the controller. GEF uses Draw2D figures as views, although anything that
+ implements the <code>IFigure</code> interface will do. The controller, known
+ as an <b>edit part</b>, is the one that brings the two together. A top level
+ controller is created when you start editing your model. If the model consists
+ of many fragments, the top level controller informs GEF about that fact. In
+ turn, child controllers for each fragment are created. If those again consists
+ of subparts, the process is repeated until all objects that comprise a model
+ have their controllers built. The other task of the controller is to create
+ a figure representing the model. Once the model has been set on a particular
+ controller, the GEF asks it for the congruous <code>IFigure</code> object. Since
+ neither the model nor the view know about each other, it is the task of the
+ controller to listen to changes in the model and update the visual representation
+ of it. As a result, a common pattern in many GEF editors is a model that posts
+ <code>PropertyChangeEvent</code> notifications. When an edit part receives an
+ event notification it reacts appropriately by adjusting visual or structural
+ representation of the model. </p>
+<p>
+ Another aspect of visual editing is reacting to user actions and mouse
+ or keyboard events. The challenge here is to provide a mechanism that
+ comes with sensible defaults, yet at the same time is flexible enough to
+ allow those defaults to be replaced by interactions appropriate for
+ the edited model. Take a mouse drag event as an example. If we were
+ to assume every time a mouse drag event is detected that all selected
+ objects are moved, we'd limit the freedom of the editor developer. It
+ is quite likely that somebody might wish to provide zoom in or out
+ operations on a mouse being dragged. GEF solves this issue by using
+ tools, requests, and policies.
+</p>
+<p>
+ A <b>tool</b> is a stateful object that translates low level events,
+ such as mouse pressed, mouse dragged, and so on, into high level
+ <b>requests</b>, represented by a <code>Request</code> object.
+ Which request is posted depends on which tool is active. For example,
+ the connection tool, upon receiving a mouse pressed event, posts a
+ connection start or connection end request. If it was a create tool,
+ we'd receive a create request. GEF comes with a number
+ of predefined tools and means of creating application specific
+ tools. Tools may be activated programmatically or as a response to a
+ user action. Most of the time, tools post requests to the <code>EditPart</code>
+ whose figure was underneath the mouse. For example, if you click on a rectangle
+ representing a widget, the edit part associated with it receives a
+ selection or direct edit request. Sometimes, like the <code>MarqueeSelectionTool</code>
+ does, the request
+ is posted to all parts whose figures are contained within a given area. Regardless of
+ how one or more edit parts are chosen as the target of requests,
+ they do not handle requests themselves. Instead, they delegate this
+ task to registered <b>edit policies</b>. Each policy is asked for a command
+ for a given request. A policy not wishing to handle the request may
+ return a <code>null</code>. The mechanism of having policies
+ rather than an edit part respond
+ to requests allows to keep both of them small
+ and highly specialized. This, in turn, means easy to debug and more
+ maintainable code.
+ The final piece of the puzzle is <b>commands</b>. Rather than
+ modifying the model directly, GEF requires that you do it with the help of
+ commands. Each command should implement applying and undoing
+ changes to the model or its part. This way GEF editors automatically
+ support the undo/redo of model alterations.
+</p>
+
+<p>
+ A significant benefit of using GEF, in addition to being able to boast about
+ your skills and design pattern knowledge, is the fact that it fully
+ integrates with the Eclipse platform. Objects selected in the editor
+ may provide properties for the standard <em>Properties</em> view. Eclipse wizards
+ may be used to create and initialize models edited by GEF editors. <em>Undo</em>
+ and <em>Redo</em> items of the <em>Edit</em> menu may trigger undoing or redoing of
+ GEF editing changes. Simply put, GEF editors are first class citizens
+ of the regular Eclipse platform, with the same level of integration as
+ a text editor or any other workbench editor, implementing <code>IEditorPart</code>
+ interface.
+
+
+<h2>The Model</h2>
+
+<p>
+ The first step when building a GEF editor is to create a model. In our case
+ the model consists of four types of objects: a shape diagram, which holds shapes,
+ two shape types, and shape connections.
+ Before we start writing code for those classes, we prepare some
+ basic infrastructure.
+</p>
+
+<h3>Core model classes</h3>
+<p>
+ When creating a model use the following guidelines:
+</p>
+<ul>
+ <li>
+ <b>The model stores all data that may be edited or viewed by
+ the user</b>. In particular, this also means data pertinent to the
+ visual representation, such as bounds. You may not rely on either
+ edit parts or figures to keep such data, as they may be created and
+ discarded at will. If you dislike storing visual data together with
+ your business data, consider the suggestion made in
+ <a class="cite" href="#hudson">[3]</a>.
+ </li>
+ <li>
+ <b>Provide ways of persisting the model</b>. Ensure that when an
+ editor is closed your model is persisted. When the same editor is
+ opened, implement a method for the model to restore its state from
+ permanent storage.
+ </li>
+ <li>
+ <b>The model must remain ignorant of the view or the
+ controller</b>. Never store any references to either the view or
+ the controller. GEF may discard a view or a controller under certain
+ circumstances. If you keep references to them, you are left with
+ an inactive figure or an edit part.
+ </li>
+ <li><b>Provide a way for others to listen to changes in your
+ model</b>. This allows the
+ controller to react to changes and appropriately adjust the
+ view. Since you are not allowed to keep a reference to the controller,
+ the only way to deal with it is to provide a way for a controller to
+ register (and unregister!) with your model as a receiver of events. A
+ good choice is a property change event notification defined in the
+ <code>java.beans</code> package.
+ </li>
+</ul>
+
+<p>
+ As the above outlined rules are common for all models, it is beneficial
+ to create a hierarchy of base classes that enforces them. The
+ <code>ModelElement</code> extends Java's <code>Object</code> class, adding
+ three features: persistence, property change, and property source support.
+ Simple model persistence is guaranteed by implementing
+ <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> the
+ <code>java.io.Serializable</code> interface together with
+ <img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag"> the
+ <code>readObject</code> method. This solution permits one to save the
+ editor's model in a binary
+ format. While it may work for certain applications, it does not provide
+ format portability. In more complex cases, one may implement
+ saving the model in XML or similar format. Model changes are communicated
+ using property change events. The base class allows edit parts to
+ <img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag">
+ register and
+ <img src="images/tag_5.gif" height=13 width=24 align="middle" alt="tag">
+ unregister as receivers of property change notifications.
+ Those are posted by calling
+ <img src="images/tag_6.gif" height=13 width=24 align="middle" alt="tag">
+ the <code>firePropertyChange</code> method.
+ Finally, in order to aid integration with the <em>Properties</em> view of the workbench,
+ <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ the <code>IPropertySource</code> interface is implemented (details of which
+ are omitted in Figure&nbsp;2).
+</p>
+
+<div class="figure">
+<pre class="program">public abstract class ModelElement implements <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> IPropertySource, <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> Serializable {
+
+ private transient PropertyChangeSupport pcsDelegate =
+ new PropertyChangeSupport(this);
+
+<img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag"> public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
+ if (l == null) {
+ throw new IllegalArgumentException();
+ }
+
+ pcsDelegate.addPropertyChangeListener(l);
+ }
+
+<img src="images/tag_6.gif" height=13 width=24 align="middle" alt="tag"> protected void firePropertyChange(String property,
+ Object oldValue,
+ Object newValue) {
+ if (pcsDelegate.hasListeners(property)) {
+ pcsDelegate.firePropertyChange(property, oldValue, newValue);
+ }
+ }
+
+<img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag"> private void readObject(ObjectInputStream in) throws IOException,
+ ClassNotFoundException {
+ in.defaultReadObject();
+ pcsDelegate = new PropertyChangeSupport(this);
+ }
+
+<img src="images/tag_5.gif" height=13 width=24 align="middle" alt="tag"> public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
+ if (l != null) {
+ pcsDelegate.removePropertyChangeListener(l);
+ }
+ }
+
+ ...
+}</pre>
+<div class="figure-caption">
+ <span class="figure-number">Fig 2</span>. The base class of all model objects
+</div>
+</div>
+
+<p>
+ Two types of objects, ellipse and rectangle shapes, share further common
+ functionality that may be factored out into a common class. In particular,
+ both represent objects that occupy certain locations and have a non-zero
+ size. Both may have connections ending or originating at them. Any changes
+ to these properties need to be communicated to all listeners. Furthermore,
+ the location and size property are also exposed through the
+ <code>IPropertySource</code> interface, allowing the user to inspect and
+ modify them via the <em>Properties</em> view.
+</p>
+
+<p>
+ Management of connections between objects is worth a more detailed look.
+ There is no concept of a global store of all connections. Instead, GEF
+ requires model parts to report any connections that start
+ or terminate in them. These must be reported as <code>Lists</code>
+ of objects. The <code>Shape</code> class maintains two array lists
+ of <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ source and
+ <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag">
+ target connections. The source connections are those
+ which have the given shape as the source, and target connections
+ are those in which the given shape is recorded as the target. Two
+ methods
+ (<img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag">,
+ <img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag">),
+ with package level visibility, are added that allow shapes
+ and connections to communicate about their mutual relationship. In
+ addition, two public methods
+ (<img src="images/tag_5.gif" height=13 width=24 align="middle" alt="tag">,
+ <img src="images/tag_6.gif" height=13 width=24 align="middle" alt="tag">)
+ are defined that allow classes external
+ to the <code>model</code> package learn about connectivity of a shape.
+ These are used by shape controllers, explained in the subsequent part
+ of this article.
+</p>
+
+<div class="figure">
+<pre class="program">public abstract class Shape extends ModelElement {
+
+ private Point location = new Point(0, 0);
+ private Dimension size = new Dimension(50, 50);
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> private List sourceConnections = new ArrayList();
+<img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> private List targetConnections = new ArrayList();
+
+ public Point getLocation() {
+ return location.getCopy();
+ }
+
+ public void setLocation(Point newLocation) {
+ if (newLocation == null) {
+ throw new IllegalArgumentException();
+ }
+ location.setLocation(newLocation);
+ firePropertyChange(LOCATION_PROP, null, location);
+ }
+
+<img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag"> void addConnection(Connection conn) {
+ if (conn == null || conn.getSource() == conn.getTarget()) {
+ throw new IllegalArgumentException();
+ }
+ if (conn.getSource() == this) {
+ sourceConnections.add(conn);
+ firePropertyChange(SOURCE_CONNECTIONS_PROP, null, conn);
+ } else if (conn.getTarget() == this) {
+ targetConnections.add(conn);
+ firePropertyChange(TARGET_CONNECTIONS_PROP, null, conn);
+ }
+ }
+
+<img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag"> void removeConnection(Connection conn) {
+ if (conn == null) {
+ throw new IllegalArgumentException();
+ }
+ if (conn.getSource() == this) {
+ sourceConnections.remove(conn);
+ firePropertyChange(SOURCE_CONNECTIONS_PROP, null, conn);
+ } else if (conn.getTarget() == this) {
+ targetConnections.remove(conn);
+ firePropertyChange(TARGET_CONNECTIONS_PROP, null, conn);
+ }
+ }
+
+<img src="images/tag_5.gif" height=13 width=24 align="middle" alt="tag"> public List getSourceConnections() {
+ return new ArrayList(sourceConnections);
+ }
+
+<img src="images/tag_6.gif" height=13 width=24 align="middle" alt="tag"> public List getTargetConnections() {
+ return new ArrayList(targetConnections);
+ }
+
+ ...
+}</pre>
+<div class="figure-caption">
+ <span class="figure-number">Fig 3</span> Shape functionality
+</div>
+</div>
+
+
+<h3>Top level model classes</h3>
+
+<p>
+ With the above preparation we may start coding top level model classes.
+ The <code>Connection</code> class represents a connection between two
+ shapes. It stores the source and target of a connection. Changes in
+ connectivity are effected by invoking <code>disconnect</code> or
+ <code>reconnect</code> methods. Connections maintain a boolean
+ flag indicating if they are currently connected or disconnected.
+ The flag is used by commands to verify legitimacy of certain
+ operations. Both source and target retain
+ references to the original shapes allowing disconnected connections
+ to be easily reconnected. Connections maintain one attribute,
+ the line style. The <code>EllipticalShape</code> and
+ <code>RectangularShape</code> classes
+ provide an extension to the above described <code>Shape</code>
+ class, with a minimum of functionality added.
+</p>
+
+<p>
+ The <code>ShapeDiagram</code> class extends the <code>ModelElement</code>
+ class with the container functionality. It maintains a collection of
+ shapes and notifies listeners about collection changes. The boolean values
+ returned by <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ the <code>addChild</code> and
+ <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag">
+ <code>removeChild</code> methods
+ are used by commands to perform validation of their operations. Public access to all
+ shapes in a diagram is <img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag">
+ provided for the benefit of the controller class.
+</p>
+
+<div class="figure">
+<pre class="program">public class ShapesDiagram extends ModelElement {
+
+ ...
+ private Collection shapes = new Vector();
+
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> public boolean addChild(Shape s) {
+ if (s != null && shapes.add(s)) {
+ firePropertyChange(CHILD_ADDED_PROP, null, s);
+ return true;
+ }
+ return false;
+ }
+
+<img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag"> public List getChildren() {
+ return new Vector(shapes);
+ }
+
+<img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> public boolean removeChild(Shape s) {
+ if (s != null && shapes.remove(s)) {
+ firePropertyChange(CHILD_REMOVED_PROP, null, s);
+ return true;
+ }
+ return false;
+ }
+}</pre>
+<div class="figure-caption">
+ <span class="figure-number">Fig 4</span>. <code>ShapeDiagram</code> - a container
+ of shapes
+</div>
+</div>
+
+<h3>A note on implementation</h3>
+<p>
+ A careful reader is certain to recognize that the model effectively
+ created a specific implementation
+ of a directed graph, with shapes acting as vertices, connections
+ representing edges, and shape diagrams playing the role of the graph. The
+ representation built here is known as adjacency list representation
+ and is suitable for sparse graphs. With minimal effort, one could
+ transform the model's code into a generic graph representation. The only additions to
+ the implementation regularly presented in books on algorithms is the
+ fact that the graph, its nodes, and its edges post events when their
+ states change. Also nodes, unlike in mathematical graphs, rather than
+ being zero-dimensional points, have rectangular bounds. Finally, while
+ regular graphs act as a central global storage of edges, a diagram does not
+ hold connections, as GEF does not require it.
+</p>
+<p>
+ It is worth noting that the solutions employed by the above presented classes
+ are not the only ones possible. Those who developed computer representations
+ of graphs may prefer alternative ways of storing connections
+ or arranging communications between nodes and edges. However, such
+ details are not important. Designers are free to choose their own more
+ generic, faster, or otherwise enhanced model representation. The vital part is
+ event based notification of model changes, maintenance of all, including
+ visual attributes of the model, and support for model persistence.
+ Depending on your experience and needs, the rest are traits which you should
+ feel free to alter.
+</p>
+
+<h2>The Views</h2>
+
+<p>
+ Due to the simplicity of the shape diagram editor, we do not have to create figures
+ representing our model, but use predefined figures instead. A
+ diagram is represented by the <code>Figure</code> class equipped with the
+ <code>FreeformLayout</code> manager. This gives
+ us the freedom to drag and drop objects at any location. Objects
+ are represented either by the <code>RectangleFigure</code> or
+ by <code>Ellipse</code>. Relying on predefined figures to represent parts of
+ the model is uncustomary. Even though your view may not have any
+ references to either the model or the controller, it must have a
+ visual attribute for every important aspect of the model that the
+ user may wish to inspect or change. It is thus much more common
+ to define intricate figures with the number of visual attributes,
+ such as color, text, nested figures, etc., matching the number
+ of attributes of the model they represent. For a more
+ thorough treatment about creating complex figures please see
+ <a class="cite" href="#lee">[4]</a>.
+</p>
+
+<h2>The Parts</h2>
+
+<p>
+ For each independent piece of the model we must define a controller. By
+ "independent" we mean an element that may be subject to user
+ manipulations. A good rule of thumb to follow is that anything that
+ may be selected or deleted should have its own edit part.
+</p>
+<p>
+ The role of edit parts is to understand the model, listen to events about
+ its changes, and update views, correspondingly. Due to the choices made
+ at the model level, all edit parts follow the pattern shown in
+ Figure&nbsp;5. Each part <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ implements the <code>PropertyChangeListener</code>
+ interface. When <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag">
+ activated, it registers with the model as the receiver of
+ the property change events. Upon
+ <img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag">
+ deactivation, it removes itself from the
+ list of listeners. Finally, when it
+ <img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag">
+ receives a property change event, based
+ on the name of the property and the new and old values it refreshes one
+ or more visual aspects of the figure representing the model. In fact, this
+ pattern is so common that in a larger application it would justify creating
+ a base class factoring out this behavior.
+</p>
+<div class="figure">
+<pre class="program">public abstract class SpecificPart extends AbstractGraphicalEditPart
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> implements PropertyChangeListener {
+
+<img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> public void activate() {
+ if (!isActive()) {
+ super.activate();
+ ((PropertyAwareModel) this.getModel()).addPropertyChangeListener(this);
+ }
+ }
+
+<img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag"> public void deactivate() {
+ if (isActive()) {
+ ((PropertyAwareModel) this.getModel()).removePropertyChangeListener(this);
+ super.deactivate();
+ }
+ }
+
+<img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag"> public void propertyChage(PropertyChangeEvent evt) {
+ String prop = evt.getPropertyName();
+ ...
+ }
+}</pre>
+<div class="figure-caption">
+ <span class="figure-number">Fig 5</span>. Property aware part
+</div>
+</div>
+
+<h3>The <tt>DiagramEditPart</tt> class</h3>
+
+<p>
+ When the editor successfully loads and sets a shape diagram object on a
+ graphical viewer, the <code>ShapesEditPartFactory</code> is asked to
+ create a part controlling the diagram. It creates a new <code>DiagramEditPart</code>
+ and sets the diagram as its model. The newly created part is activated,
+ registers itself with the model, and creates a figure, with a free form layout
+ manager that allows positioning of diagram figures based on their constraints
+ (bounds). The <code>DiagramEditPart</code> reports all shapes contained
+ in the diagram via the <code>getModelChildren</code>. As mentioned before,
+ GEF repeats the process of generating parts and figures for all returned
+ model children.
+</p>
+
+<p>
+ The <code>DiagramEditPart</code> class installs three policies. All policies
+ should be installed in the <code>createEditPolicies</code> method that
+ is declared by the <code>AbstractEditPart</code> class, and must be implemented
+ by all concrete classes extending the <code>AbstractGraphicalEditPart</code>.
+ Policies are delegates used by edit parts to handle requests posted by
+ tools. In the simplest cases, policies take care of generating
+ commands. A policy is registered with the <code>String</code> key, referred
+ to as the policy's role.
+ The key has no meaning to edit parts. However, it should have meaning to a software
+ developer, as it allows others, specifically those who extend your
+ controller, to disable or remove the policy by specifying its key. As far
+ as GEF is concerned, your key could be <code>"foobar"</code>. However,
+ you'd better tell your fellow developers that in order to, say, set a new
+ layout policy when the layout manager is changed, they need to
+ install a new <code>"foobar"</code> policy. As this might be amusing, but not
+ obvious, it is recommended that you use keys defined in
+ the <code>EditPolicy</code> interface, whose names
+ try to convey the role the given policy plays in an edit part.
+</p>
+<p>
+ The <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ first policy installed using the <code>EditPolicy.COMPONENT_ROLE</code> key
+ has the task of preventing the root of the model from being deleted. It overrides
+ the <code>createDeleteCommand</code> method to return an unexecutable
+ command. The <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag">
+ second policy, installed with the <code>LAYOUT_ROLE</code>
+ key, handles create and constraint change requests. The first request is
+ posted when a new shape is dropped into a diagram. The layout policy
+ returns a command that adds a new shape to the diagram editor and places
+ it at the drop location. The constraint change request is posted whenever
+ the user resizes or moves shapes already present in the diagram. The
+ <img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag">
+ third call to the <code>installEditPolicy</code> removes rather than
+ installs a policy. This prevents the root part from providing selection
+ feedback when the user clicks on the area of the diagram corresponding
+ to the root of the model. This call also illustrates the importance of
+ meaningful keys used to register part's policies.
+</p>
+
+<div class="figure">
+<pre class="program">protected void createEditPolicies() {
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> installEditPolicy(EditPolicy.COMPONENT_ROLE, new RootComponentEditPolicy());
+ XYLayout layout = (XYLayout) getContentPane().getLayoutManager();
+<img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> installEditPolicy(EditPolicy.LAYOUT_ROLE, new ShapesXYLayoutEditPolicy(layout));
+<img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag"> installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, null);
+}</pre>
+<div class="figure-caption">
+ <span class="figure-number">Fig 6</span>. Policies installed by the diagram
+ edit part.
+</div>
+</div>
+
+<p>
+ The diagram edit part monitors child added and child removed property events.
+ These are posted by the <code>ShapesDiagam</code> class whenever new
+ shapes are added or removed. Upon detecting either type of a property
+ change event, the diagram edit part invokes the <code>refreshChildren</code>
+ method, defined in the <code>AbstractEditPart</code>. This method traverses
+ all model children and creates, removes, or re-orders edit part children
+ appropriately.
+</p>
+
+<h3>The <tt>ShapeEditPart</tt> class</h3>
+
+<p>
+ Diagram shapes are managed by the <code>ShapeEditPart</code>. The part itself
+ is created by the <code>ShapesEditPartFactory</code> in response to
+ <code>DiagramEditPart</code> returning a list of model children. Each
+ part created by the factory is given the child model which it controls.
+ Once the model is set, the part is asked to create a figure representing it.
+ Depending on the type of the model, it returns either an ellipse or a
+ rectangle.
+</p>
+
+<p>
+ Shape edit parts monitor four types of property change events: size,
+ location, source, and target connections. If the shape changes size or location,
+ the <img src="images/tag_6.gif" height=13 width=24 align="middle" alt="tag">
+ <code>refreshVisual</code> method is called. This method is automatically
+ invoked by GEF the first time a figure is created. In it, the visual
+ attributes of the figure should be adjusted based on the state of the
+ model. Reusing the same method for model updates is another frequently
+ encountered pattern in GEF editors. In the case of the shape editor part,
+ the new location and size are fetched and stored with the figure representing
+ the shape. In addition, the new bounds are passed as the constraint to the
+ layout manager of the parent controller. When source or target connections
+ change, the source or target connection edit parts are refreshed by a call
+ to the methods defined in the <code>AbstractGraphicalEditPart</code>.
+ Similarly to the <code>refreshChildren</code> method, these methods go
+ through the list of connections and add, remove, or reposition edit parts
+ corresponding to them.
+</p>
+
+<div class="figure">
+ <pre class="program">class ShapeEditPart extends AbstractGraphicalEditPart
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> implements PropertyChangeListener, NodeEditPart {
+
+<img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> protected List getModelSourceConnections() {
+ return getCastedModel().getSourceConnections();
+ }
+
+<img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag"> protected List getModelTargetConnections() {
+ return getCastedModel().getTargetConnections();
+ }
+
+<img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag"> public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) {
+ return new ChopboxAnchor(getFigure());
+ }
+
+<img src="images/tag_5.gif" height=13 width=24 align="middle" alt="tag"> public ConnectionAnchor getSourceConnectionAnchor(Request request) {
+ return new ChopboxAnchor(getFigure());
+ }
+
+ public void propertyChange(PropertyChangeEvent evt) {
+ String prop = evt.getPropertyName();
+
+ if (Shape.SIZE_PROP.equals(prop) || Shape.LOCATION_PROP.equals(prop)) {
+ refreshVisuals();
+ }
+ if (Shape.SOURCE_CONNECTIONS_PROP.equals(prop)) {
+ refreshSourceConnections();
+ }
+ if (Shape.TARGET_CONNECTIONS_PROP.equals(prop)) {
+ refreshTargetConnections();
+ }
+ }
+
+<img src="images/tag_6.gif" height=13 width=24 align="middle" alt="tag"> protected void refreshVisuals() {
+ Rectangle bounds = new Rectangle(getCastedModel().getLocation(),
+ getCastedModel().getSize());
+ figure.setBounds(bounds);
+ ((GraphicalEditPart) getParent()).setLayoutConstraint(this, figure, bounds);
+ }
+}</pre>
+ <div class="figure-caption">
+ <span class="figure-number">Fig 7</span>. Controller of shapes
+ </div>
+</div>
+
+<p>
+ As shapes may be connected to other shapes, the shape edit part overrides the
+ <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag">
+ <code>getModelSourceConnections</code> and the
+ <img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag">
+ <code>getModelTargetConnections</code> methods. The role of these methods
+ is to inform GEF about connections that originate or terminate at the
+ given shape. In addition, the <code>ShapeEditPart</code> implements
+ the <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ <code>NodeEditPart</code> interface. By implementing it, the edit part is
+ able to define source and target anchors, i.e., points to which connections
+ attach. The logic circuit editor example uses this feature to indicate
+ where a wire would attach to a logical gate. Since shapes do not have
+ any specific connection points, we use a chop box anchor which clips the
+ connection against the rectangular bounds of the figure. If you wish,
+ you can return the <code>EllipseAnchor</code> for ellipse shapes, which
+ returns a point on the ellipse's boundary. For more complex shapes, you should
+ extend the <code>AbstractConnectionAnchor</code> class and implement the
+ <code>getLocation</code> method. Notice that two types of methods are
+ implemented: one taking a <code>ConnectionEditPart</code>, and one
+ taking a <code>Request</code> as the parameter. The
+ <img src="images/tag_5.gif" height=13 width=24 align="middle" alt="tag">
+ second method is invoked to provide a user with feedback while a new
+ connection is being created. The
+ <img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag">
+ first one is used for
+ established connections.
+</p>
+
+<p>
+ Shape edit part installs two policies. The <code>ShapeComponentEditPolicy</code>
+ supplies a command for removing a shape from the diagram. The second policy,
+ installed with the <code>GRAPHICAL_NODE_ROLE</code> key, handles the task of
+ creating and reattaching connections between shapes. A new connection is
+ created in two steps by the connection creation tool. When a user clicks on a
+ figure corresponding to an element of the model, the policy is requested to
+ <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ create a connection command. Returning <code>null</code> from this method
+ indicates that the connection may not originate from the given element of
+ the model. If the connection is possible, a new command should be created and
+ stored in the request as the start command. When another figure is
+ clicked, the policy is required to supply a
+ <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag">
+ connection complete command. This
+ could be a new command built from the start command, or the start command tag
+ supplied with the information about the terminating point of the connection.
+</p>
+
+<div class="figure">
+ <pre class="program">new GraphicalNodeEditPolicy() {
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> protected Command getConnectionCreateCommand(CreateConnectionRequest request) {
+ Shape source = (Shape) getHost().getModel();
+ int style = ((Integer) request.getNewObjectType()).intValue();
+ ConnectionCreateCommand cmd = new ConnectionCreateCommand(source, style);
+ request.setStartCommand(cmd);
+ return cmd;
+ }
+
+<img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> protected Command getConnectionCompleteCommand(CreateConnectionRequest request) {
+ ConnectionCreateCommand cmd =
+ (ConnectionCreateCommand) request.getStartCommand();
+ cmd.setTarget((Shape) getHost().getModel());
+ return cmd;
+ }
+
+ ...
+}</pre>
+ <div class="figure-caption">
+ <span class="figure-number">Fig 8</span>. Graphical node edit policy
+ </div>
+</div>
+
+<p>
+ The other task of the graphical node edit policy is to provide connection
+ reattachment commands. Connection reattachment may change the source or the
+ target of the connection. The same rules apply to these commands as to the
+ connection creation command. In particular, if a given connection should not
+ be reattached, the policy must return null. It is also possible for the policy
+ to return a command that refuses to be executed, by returning false from the
+ <code>canExecute</code> method. Due to space limitation, details of these
+ commands are left out and the reader is referred to the source code.
+</p>
+
+<h3>The <tt>ConnectionEditPart</tt> class</h3>
+
+<p>
+ As connections are user editable parts of the model, they
+ must have their own controller. It is implemented
+ by the <code>ConnectionEditPart</code> class, which extends
+ the <code>AbstractConnectionEditPart</code>
+ class. Similar to other controllers, it implements the
+ <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ <code>PropertyChangeListener</code> interface
+ and registers the part for the events with the model on activation.
+ The connection part
+ <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag">
+ returns a polyline decorated with an arrow as the figure.
+ It installs two edit policies. The
+ first one, the <img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag">
+ <code>ConnectionComponentPolicy</code>, supplies
+ a delete command needed by the action associated with the <em>Delete</em>
+ menu item. The <img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag">
+ second one is of greater interest. It equips
+ a selected connection with handles, placed at the start and the
+ end. Without this policy, reattaching connections
+ is impossible, as the GEF has no handles to grab onto when the
+ end of the connection is being dragged. The authors of the GEF
+ recommend that all <code>ConnectionEditParts</code> should have
+ this policy, even if their ends are not draggable. At minimum this
+ policy provides a visual selection feedback. The
+ <code>propertyChange</code> method watches for
+ <img src="images/tag_5.gif" height=13 width=24 align="middle" alt="tag">
+ changes in the line
+ style property and adjusts the polyline figure appropriately.
+</p>
+
+<div class="figure">
+<pre class="program">class ConnectionEditPart extends AbstractConnectionEditPart
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> implements PropertyChangeListener {
+
+ protected IFigure createFigure() {
+<img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> PolylineConnection connection = (PolylineConnection) super.createFigure();
+ connection.setTargetDecoration(new PolygonDecoration());
+ connection.setLineStyle(getCastedModel().getLineStyle());
+ return connection;
+ }
+
+ protected void createEditPolicies() {
+<img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag"> installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectionEditPolicy() {
+ protected Command getDeleteCommand(GroupRequest request) {
+ return new ConnectionDeleteCommand(getCastedModel());
+ }
+ });
+<img src="images/tag_4.gif" height=13 width=24 align="middle" alt="tag"> installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,
+ new ConnectionEndpointEditPolicy());
+ }
+
+ public void propertyChange(PropertyChangeEvent event) {
+ String property = event.getPropertyName();
+<img src="images/tag_5.gif" height=13 width=24 align="middle" alt="tag"> if (Connection.LINESTYLE_PROP.equals(property)) {
+ ((PolylineConnection) getFigure()).
+ setLineStyle(getCastedModel().getLineStyle());
+ }
+ }
+ ...
+}</pre>
+<div class="figure-caption">
+ <span class="figure-number">Fig 9</span>. Controller of connections
+</div>
+</div>
+
+
+<h2>Shape Editor</h2>
+
+<p>
+ The shape editor extends the <code>GraphicalEditorWithFlyoutPalette</code>
+ class. This class is a specialized form of a graphical editor, a type
+ of an editor part, equipped with a palette hosting tool entries. The
+ extending class must implement two methods, <code>getPaletteRoot</code>
+ and <code>getPalettePreferences</code>. The first method must return a
+ palette root populated with tool entries. Tool entries are specialized
+ types of palette entries capable of installing tools on the edit
+ domain of the editor. They may be hosted in palette drawers, which
+ provide convenient way of grouping them. It is recommended that
+ one tool entry is set as the default entry of the palette root. A typical
+ solution is to use an instance of the <code>SelectionToolEntry</code>
+ class in that role. Palette preferences, returned by the second method,
+ specify whether the palette is visible or collapsed, the location where it
+ is docked, and the palette width. A commonly found solution is to save them
+ to and restore them from the plug-in's preference store.
+</p>
+
+<p>
+ The already mentioned edit domain plays the role of a central controller. It
+ holds a palette of tools, loads the default tool, maintains the active tool
+ to which it forwards mouse and key events, and deals with the command stack.
+ GEF provides the default implementation, the <code>DefaultEditDomain</code>,
+ which you should set on your editor in the constructor.
+</p>
+
+<p>
+ Part of the job that a graphical editor must perform is to create and
+ initialize a graphical viewer. A graphical viewer is a specialized
+ <code>EditPartViewer</code> capable of performing hit testing. Again, we may
+ rely on the default viewer supplied by the
+ <code>GraphicalEditor</code> class. There are, however, a few things that
+ need to be done. In the <code>configureGraphicalViewer</code> method
+ <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ set a factory of edit parts. The factory must implement
+ the sole method of the <code>EditPartFactory</code> interface,
+ <code>createEditPart(EditPart, Object)</code>. The first argument is the
+ edit part that returned the second argument, a (part of your) model, through
+ the <code>getModelChildren</code> method. Other things to do here
+ may include setting up a key handler, context menus, etc.
+</p>
+
+<div class="figure">
+<pre class="program">protected void configureGraphicalViewer() {
+ super.configureGraphicalViewer();
+
+ GraphicalViewer viewer = getGraphicalViewer();
+ viewer.setRootEditPart(new ScalableRootEditPart());
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> viewer.setEditPartFactory(new ShapesEditPartFactory());
+ viewer.setKeyHandler(
+ new GraphicalViewerKeyHandler(viewer).setParent(getCommonKeyHandler()));
+ ContextMenuProvider cmProvider =
+ new ShapesEditorContextMenuProvider(viewer, getActionRegistry());
+ viewer.setContextMenu(cmProvider);
+ getSite().registerContextMenu(cmProvider, viewer);
+}
+
+protected void initializeGraphicalViewer() {
+ super.initializeGraphicalViewer();
+ GraphicalViewer graphicalViewer = getGraphicalViewer();
+<img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> graphicalViewer.setContents(getModel());
+<img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag"> graphicalViewer.addDropTargetListener(createTransferDropTargetListener());
+}</pre>
+<div class="figure-caption">
+ <span class="figure-number">Fig 10</span>. Configuring and initializing a graphic viewer
+</div>
+</div>
+
+<p>
+ Once the factory is set, you should
+ <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag">
+ set the contents on the graphical viewer.
+ The contents naturally should be the object restored from the
+ <code>IEditorInput</code> passed to the editor in the <code>setInput</code>
+ method. The shape example also adds
+ <img src="images/tag_3.gif" height=13 width=24 align="middle" alt="tag">
+ a drop target listener to the graphical
+ viewer. This allows one to use the drag and drop gesture rather than select and
+ click when adding new shapes to the diagram. The drop target listener
+ uses a subclassed <code>TemplateTransferDropTargetListener</code> that
+ uses a <code>CreateRequest</code> to fetch a command for adding an
+ object to the model owned by the edit part above which the drag and
+ drop gesture was finalized.
+</p>
+
+<p>
+ In addition to the described tasks, the editor takes care of reporting
+ the dirty flag by monitoring a command stack. This is a preferred
+ solution, as this keeps the flag in synch with any undo or redo
+ actions that the user may perform. Notice that the command stack
+ has the save location marked in both <code>doSave</code> and
+ <code>doSaveAs</code> methods. Other details of the editor, such
+ as actual saving and restoring of the model, are not discussed here
+ as they tend to be very application specific. The editor's functionality
+ that deals with exposing editor content to other views, connecting
+ menu items to editor actions, and other workbench cooperation techniques
+ is described next.
+</p>
+
+<h2>Integrating with the workbench</h2>
+
+<p>
+ The editor, as presented so far, would be fully operational. However,
+ it would not integrate well with the workbench. For example, the
+ <em>Edit</em> menu actions, such as <em>Delete</em>, <em>Undo</em>, and
+ <em>Redo</em> could not be used. Other views could not show alternative
+ presentations of the editor content. In other words, the editor would
+ not get the benefits of being part of the Eclipse workbench. The task
+ of transforming an isolated editor into a proper participant of the
+ workbench is explained in the following three sections.
+</p>
+
+<h3>Editor Actions</h3>
+
+<p>
+ The <code>ShapesEditor</code> class creates a number of default
+ actions in the <code>createActions</code> method invoked during editor
+ initialization. These are undo, redo, select all, delete, save, and print
+ actions. In order to
+ connect standard menu items to them, you should define an action bar
+ contributor and list it, in the <code>plugin.xml</code> file, as
+ the editor contributor. In the action bar contributor you need to
+ implement two methods. The first one,
+ <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ the <code>buildActions</code> method,
+ should create retargetable actions for undo, redo, and delete. If you
+ wish to enable keyboard selection of all widgets, you need
+ to <img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> add a global
+ action key for the selected action in the second method,
+ <code>declareGlobalActionKeys</code>.
+</p>
+
+<div class="figure">
+ <pre class="program">public class ShapesEditorActionBarContributor extends ActionBarContributor {
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> protected void buildActions() {
+ this.addRetargetAction(new UndoRetargetAction());
+ this.addRetargetAction(new RedoRetargetAction());
+ this.addRetargetAction(new DeleteRetargetAction());
+ }
+
+ public void contributeToToolBar(IToolBarManager toolBarManager) {
+ super.contributeToToolBar(toolBarManager);
+ toolBarManager.add(getAction(ActionFactory.UNDO.getId()));
+ toolBarManager.add(getAction(ActionFactory.REDO.getId()));
+ }
+
+ protected void declareGlobalActionKeys() {
+<img src="images/tag_2.gif" height=13 width=24 align="middle" alt="tag"> this.addGlobalActionKey(ActionFactory.SELECT_ALL.getId());
+ }
+}</pre>
+ <div class="figure-caption">
+ <span class="figure-number">Fig 11</span>. Connecting menu actions
+ </div>
+</div>
+
+<p>
+ It may be illustrative to trace what happens when the user selects
+ the <em>Delete</em> item in the <em>Edit</em> menu (see Figure&nbsp;12). The
+ delete action, which is added to the action registry by the
+ parent class of the <code>ShapesEditor</code> class, traces the
+ current selection. When the delete action is executed, it checks
+ if any of the currently selected objects are instances of the
+ <code>EditPart</code> class. For each such object it requests a command
+ from the edit part. In turn, each edit part checks if any of the
+ edit policies created on it understand and are willing to handle
+ the delete request. For shapes, the <code>ShapeComponentEditPolicy</code>
+ claims it can handle the delete request, and when asked for a command
+ it returns a <code>ShapeDeleteCommand</code> instance. The
+ action executes the command, which removes the shape from
+ the diagram. The diagram fires a property change event that is
+ handled by the <code>DiagramEditPart</code> and ultimately leads to
+ a rectangle or ellipse representing the deleted shape to be removed from the
+ display.
+</p>
+<div class="figure">
+<center>
+ <img src="images/delete_action3.gif" alt="Delete action call sequence" width="575" height="340"/>
+</center>
+<div class="figure-caption">
+ <span class="figure-number">Fig 12</span>. Delete action call sequence
+</div>
+</div>
+
+<h3>Exposing properties</h3>
+
+<p>
+ Every graphical editor is a source of selection events. You can test this
+ by creating a view that registers with the workbench site's page as a selection listener.
+ Every time you select an object in your graphical editor, your view
+ receives a notification in the <code>selectionChanged</code> method. One
+ of Eclipse's standard views, <em>Properties</em> view, listens to
+ selection events, and for every selection checks if its objects implement
+ the <code>IPropertySource</code> interface. If so, it uses the methods of
+ the interface to interrogate the selected object or objects about their
+ properties and displays them in a tabular format.
+</p>
+
+<p>
+ Thanks to the above described infrastructure, exposing properties of objects
+ edited in graphical editor is a matter of implementing methods of the
+ <code>IPropertySource</code> interface. By inspecting the <code>Shape</code>
+ class you can view how position and size of objects are made
+ available to the <em>Properties</em> view.
+</p>
+
+<h3>Providing an Outline</h3>
+
+<p>
+ The <em>Outline</em> view is used to provide an alternative and often more
+ succinct view of edited data. In Java editors it is used to show
+ imports, variables, and methods of the edited class, without going into
+ code details. Graphical editors can also benefit from such a high level
+ view. The shape diagram editor, similarly to the logic circuit editor,
+ exposes the edited contents in the form of a tree (see
+ <a href="#fig1">Figure&nbsp;1</a>). The database schema editor
+ <a class="cite" href="#zoio">[7]</a> provides a view of the entire editor window
+ with a thumb for panning.
+</p>
+
+<p>
+ In order to expose edited content to the <em>Outline</em> view, you need to
+ override the <code>getAdapter</code> method and
+ <img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag">
+ return an outline
+ implementation when the adapter class is the <code>IContentOutlinePage</code>
+ interface. The easiest way to implement an outline is to extend
+ the <code>ContentOutlinePage</code> class by supplying it with an
+ appropriate configured <code>EditPartViewer</code>.
+</p>
+
+<div class="figure">
+ <pre class="program">public Object getAdapter(Class type) {
+ // returns the content outline page for this editor
+<img src="images/tag_1.gif" height=13 width=24 align="middle" alt="tag"> if (type == IContentOutlinePage.class) {
+ if (outlinePage == null) {
+ outlinePage = new ShapesEditorOutlinePage(this, new TreeViewer());
+ }
+ return outlinePage;
+ }
+ return super.getAdapter(type);
+}</pre>
+ <div class="figure-caption">
+ <span class="figure-number">Fig 13</span>. Providing an overview
+ </div>
+</div>
+
+<p>
+ In the case of the shape diagram editor, the edit part view is implemented by
+ a tree viewer. You should supply it with the same edit domain as your
+ main editor. A tree viewer, just like any other <code>EditPartViewer</code>,
+ requires a method for creating child edit parts. The editor uses the same
+ mechanism as that employed with the <code>DiagramEditPart</code>, by
+ setting an edit part factory on it. In addition, the selection of the
+ overview and the main editor window is synchronized using a
+ selection synchronizer, a GEF utility class that reconciles the selection
+ state of two edit parts. The <code>ShapesTreeEditPartFactory</code>
+ returns either a <code>ShapeTreeEditPart</code> or a
+ <code>DiagramTreeEditPart</code> instance, depending on the model type. By
+ inspecting those classes, the reader should have no difficulty recognizing
+ already familiar patterns. Both edit parts implement the
+ <code>PropertyChangeListener</code> interface and react to property changes
+ by adjusting visual representation of the model. Both install edit policies
+ to control types of interactions exposed through them.
+</p>
+
+<h2>Design patterns used by GEF</h2>
+
+<p>
+ GEF attains its flexibility through an extensive use of design patterns. Provided
+ here is a brief summary of those most commonly encountered. For a more
+ detailed treatment on patterns please see <a class="cite" href="#gamma">[2]</a>.
+<p>
+<dl>
+ <dt>Model-View-Controller</dt>
+ <dd>
+ The MVC pattern is used by GEF to decouple user interface, behavior,
+ and presentation. The model is represented by any Java <code>Object</code>.
+ The view must implement the <code>IFigure</code> interface. The controller
+ is a type of an <code>EditPart</code>.
+ </dd>
+ <dt>Command</dt>
+ <dd>
+ Commands encapsulate model changes, therefore providing support for undoable
+ operations.
+ </dd>
+ <dt>Chain of Responsibility</dt>
+ <dd>
+ Decouples senders of requests (tools) from receivers by giving more than
+ one object a chance to handle the request. In the case of GEF, multiple edit
+ policies may respond to a request with <code>Commands</code> which then
+ are chained together.
+ </dd>
+ <dt>State</dt>
+ <dd>
+ Allows editor to alter its behavior when its internal state changes. With
+ GEF editors, this change is implemented by switching tools. For
+ example, a marquee tool causes the editor to respond differently to a
+ mouse down event than when a create tool is active.
+ </dd>
+ <dt>Abstract Factory</dt>
+ <dd>
+ Provides an interface for creating families of related or dependent
+ objects. This pattern is used when creating edit parts controlling
+ given model parts.
+ </dd>
+ <dt>Factory Method</dt>
+ <dd>
+ Defines a method for creating an object, but lets subclasses decide
+ which class to instantiate. While not explicitly discussed, this is
+ an alternative method for creating an edit part. The method
+ <code>createChild</code> allows you to explicitly create child
+ edit parts without using a factory.
+ </dd>
+</dl>
+
+<h2>Summary</h2>
+
+<p>
+ I tried giving a detailed description of most aspects of a very simple
+ graphical editor. Hopefully there is enough information provided to allow
+ anybody patient enough to read this lengthy essay to inspect larger examples,
+ such as the logic circuit editor.
+ By immediately understanding roles of classes such as
+ <code>CircuitEditPart</code>, <code>AndGateFigure</code>, and a few others
+ that directly correspond to classes present in the simple shape editor,
+ you may focus your attention on more complex aspects of larger examples.
+ There exists a plethora of subjects and techniques in GEF whose surface I have not
+ even scratched. However, they should be studied only after the base is
+ well understood. After all, what is the purpose of trying to design
+ a drag feedback, if it takes you a few hours to enable the <em>Select All</em>
+ menu item?
+</p>
+
+<h2>Acknowledgments</h2>
+<p>
+ I would like to thank Randy Hudson for his comments that helped improve
+ the structure and accuracy of this article. My thanks also go to Jill
+ Sueoka for tirelessly reviewing numerous versions that I managed to
+ produce.
+</p>
+
+<h2>Bibliography</h2>
+
+<table>
+<tbody>
+ <tr>
+ <td valign="top"><a name="bordeau"></a>[1]</td>
+ <td> Eric Bordeau, <a href="../Article-GEF-dnd/GEF-dnd.html"><i>Using
+ Native Drag and Drop with GEF</i></a>, Eclipse Corner Article, August
+ 2003 </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="gamma"></a>[2]</td>
+ <td> Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, <i>Design
+ Patterns: Elements of Reusable Object-Oriented Software</i>, Addison Wesley,
+ 1995, ISBN 0-201-63361-2</td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="hudson"></a>[3]</td>
+ <td> Randy Hudson, <a href="http://www-106.ibm.com/developerworks/opensource/library/os-gef/" target="_blank"><i>Create
+ an Eclipse-based application using the Graphical Editing Framework</i></a>,
+ <a href="http://www-136.ibm.com/developerworks/java/">IBM developerWorks</a>,
+ July 2003 </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="lee"></a>[4]</td>
+ <td> Daniel Lee, <a href="../Article-GEF-Draw2d/GEF-Draw2d.html"><i>Display
+ a UML Diagram using Draw2D Diagram</i></a>, Eclipse Corner Article, August
+ 2003 </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="mehaut"></a>[5]</td>
+ <td> Xavier Mehaut et al., <a href="http://eclipsewiki.editme.com/GefDescription" target="_blank"><i>Synthetic
+ GEF description</i></a>, June 2004 </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="moore"></a>[6]</td>
+ <td> William Moore, David Dean, Anna Gerber, Gunnar Wagenknecht and Philippe
+ Vanderheyden, <i><a href="http://www.redbooks.ibm.com/abstracts/sg246302.html" target="_blank">Eclipse
+ Development using the Graphical Editing Framework and the Eclipse Modeling
+ Framework</a></i>, IBM RedBooks, 2004, ISBN 0738453161</td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="zoio"></a>[7]</td>
+ <td> Phil Zoio, <a href="../Article-GEF-editor/gef-schema-editor.html"><i>Building
+ a Database Schema Diagram Editor with GEF</i></a>, Eclipse Corner Article,
+ September 2004 </td>
+ </tr>
+</tbody>
+</table>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the United States, other countries, or both.</small></p>
+</body>
+
+</body>
+</html>
diff --git a/Article-GEF-dnd/DNDExample.java b/Article-GEF-dnd/DNDExample.java
new file mode 100644
index 0000000..ed41293
--- /dev/null
+++ b/Article-GEF-dnd/DNDExample.java
@@ -0,0 +1,57 @@
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.*;
+
+public class DNDExample {
+
+public static void main(String[] args) {
+ Shell shell = new Shell();
+ shell.setLayout(new FillLayout());
+
+ // Create the tree and some tree items
+ final Tree tree = new Tree(shell, SWT.NONE);
+ TreeItem item1 = new TreeItem(tree, SWT.NONE);
+ item1.setText("Item 1");
+ TreeItem item2 = new TreeItem(tree, SWT.NONE);
+ item2.setText("Item 2");
+ TreeItem item3 = new TreeItem(tree, SWT.NONE);
+ item3.setText("Item 3");
+ TreeItem item4 = new TreeItem(tree, SWT.NONE);
+ item4.setText("Item 4");
+
+ // Create the drag source on the tree
+ DragSource ds = new DragSource(tree, DND.DROP_MOVE);
+ ds.setTransfer(new Transfer[] {TextTransfer.getInstance()});
+ ds.addDragListener(new DragSourceAdapter() {
+ public void dragSetData(DragSourceEvent event) {
+ // Set the data to be the first selected item's text
+ event.data = tree.getSelection()[0].getText();
+ }
+ });
+
+ // Create the button
+ final Button button = new Button(shell, SWT.FLAT);
+ button.setText("Button");
+ button.setAlignment(SWT.CENTER);
+
+ // Create the drop target on the button
+ DropTarget dt = new DropTarget(button, DND.DROP_MOVE);
+ dt.setTransfer(new Transfer[] {TextTransfer.getInstance()});
+ dt.addDropListener(new DropTargetAdapter() {
+ public void drop(DropTargetEvent event) {
+ // Set the buttons text to be the text being dropped
+ button.setText((String)event.data);
+ }
+ });
+
+ shell.pack();
+ shell.open();
+ Display display = Display.getDefault();
+ while (!shell.isDisposed())
+ if (!display.readAndDispatch())
+ display.sleep();
+ display.dispose();
+}
+
+}
diff --git a/Article-GEF-dnd/GEF-dnd.html b/Article-GEF-dnd/GEF-dnd.html
new file mode 100644
index 0000000..8fbe48e
--- /dev/null
+++ b/Article-GEF-dnd/GEF-dnd.html
@@ -0,0 +1,321 @@
+<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="Author" content="Eric Bordeau">
+<link rel="stylesheet" href="../default_style.css">
+<title>Using Native Drag and Drop with GEF</title>
+</head>
+
+<body bgcolor="#ffffff" link="#0000ff" vlink="#800080">
+
+<div align="right">
+ <font face="Times New Roman, Times, serif"><font size="-1">Copyright © 2003 International Business
+ Machines Corp.</font></font></div>
+<table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr>
+ <td align="left" valign="top" colspan="2" bgcolor="#0080c0"><b><font face="Arial,Helvetica"
+ color="#ffffff">Eclipse Corner Article</font></b></td>
+ </tr>
+</table>
+<div align="left">
+ <h1><img src="../images/Idea.jpg" height="86" width="120" align="middle"></h1>
+</div>
+<p>&nbsp;</p>
+<h1 align="center">Using Native Drag and Drop with GEF</h1>
+<blockquote>
+ <b>Summary</b> <br>
+ Native drag and drop provides the ability to drag data from one GUI object to another GUI
+ object, which could potentially be in another application. GEF allows access to the operating
+ system's underlying drag and drop infrastructure through SWT. This article will provide an in-depth look at GEF&#39;s drag and drop functionality and show some simple
+ examples of how to take advantage of this API.<p><b>Eric Bordeau, IBM</b> <br>
+ August 25, 2003</p>
+</blockquote>
+<hr width="100%">
+<h2>Introduction</h2>
+<p>Native drag and drop means the operating system&#39;s underlying drag and drop mechanism is used. This is
+different from when you drag EditParts around inside a single viewer. By using native drag and drop,
+you can transfer items between views, editors, windows and even between different applications (providing
+both applications support the transfer of that particular type of object). But not only will you be able to
+utilize other plug-ins&#39; and applications&#39; drag and drop capabilities, the opposite is also true. By using
+native drag and drop, you open the door for other plug-ins and applications to interact with your application
+in ways you may not have envisioned.
+</p>
+<h2>An SWT Example</h2>
+<p>In order to access the operating system&#39;s drag and drop facilities, GEF
+ uses SWT&#39;s DragSource and DropTarget API. (If you would like more information
+ on how SWT's drag and drop mechanism works, see Veronika Irvine's <a href="../Article-SWT-DND/DND-in-SWT.html">SWT
+ drag and drop article</a>.) To use SWT's drag and drop support, you need to
+ create a DragSource and/or DropTarget for your control. Then you can add DragSourceListeners
+ and/or DropTargetListeners to handle the drag and drop events. Here's a simple
+ drag and drop example that allows you to drag from a tree and drop the tree
+ item into a text field, changing the text field's text to that of the tree item.
+</p>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td>
+ <pre>import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+
+public class DNDExample {
+
+ public static void main(String[] args) {
+ Shell shell = new Shell();
+ shell.setBackground(new Color(null, 200, 200, 200));
+ shell.setLayout(new GridLayout(2, false));
+
+ // Create the tree and some tree items
+ final Tree tree = new Tree(shell, SWT.NONE);
+ TreeItem item1 = new TreeItem(tree, SWT.NONE);
+ item1.setText(&quot;Item 1&quot;);
+ TreeItem item2 = new TreeItem(tree, SWT.NONE);
+ item2.setText(&quot;Item 2&quot;);
+
+ // Create the drag source on the tree
+ DragSource ds = new DragSource(tree, DND.DROP_MOVE);
+ ds.setTransfer(new Transfer[] {TextTransfer.getInstance()});
+ ds.addDragListener(new DragSourceAdapter() {
+ public void dragSetData(DragSourceEvent event) {
+ // Set the data to be the first selected item's text
+ event.data = tree.getSelection()[0].getText();
+ }
+ });
+
+ // Create the text field
+ final Text text = new Text(shell, SWT.NONE);
+
+ // Create the drop target on the text field
+ DropTarget dt = new DropTarget(text, DND.DROP_MOVE);
+ dt.setTransfer(new Transfer[] {TextTransfer.getInstance()});
+ dt.addDropListener(new DropTargetAdapter() {
+ public void drop(DropTargetEvent event) {
+ // Set the text field's text to the text being dropped
+ text.setText((String)event.data);
+ }
+ });
+
+ shell.pack();
+ shell.open();
+ Display display = Display.getDefault();
+ while (!shell.isDisposed())
+ if (!display.readAndDispatch())
+ display.sleep();
+ display.dispose();
+ }
+}</pre></td></tr></table>
+<p>The DragSourceListener needs to set the data being dragged during
+the dragSetData event and the DropTargetListener needs to do something with that data during the
+drop event.<p>GEF uses SWT's DragSource and DropTarget to facilitate its drag and drop function. When adding a drag listener to your EditPartViewer, a DragSource gets created and hooked into the
+underlying control. And similarly, a DropTarget gets created when adding a drop listener. But instead
+of adding your listener directly to the DragSource or DropTarget, the viewer creates a DelegatingDragSourceAdapter
+or DelegatingDropTargetAdapter, respectively, and adds them to their corresponding widget. Then, your
+listener gets added to the delegating adapter. When events are dispatched by the DragSource or DropTarget,
+the corresponding delegating adapter gets notified and it in turn delegates the event to the proper
+listener.</p>
+<p>One of the advantages of delegating the drag and drop events in this way is to ease the separation
+of listeners by Transfer type. Code is simpler to read because each listener is only concerned with
+one type of transfer. And extension of drag and drop functionality is simplified since all
+that needs to be done is to add a new listener. Delegation of drag and drop events allows for a
+consensus of all the available listeners -- if one listener can handle the drag, it's allowed to do
+so, instead of letting the last listener determine whether the drag will be aborted or not. SWT lets you add
+multiple listeners but doesn't achieve the same effect. Delegating allows for easier
+maintainability of code and extension by third-party plug-ins.</p>
+<h2>Adding a Listener to a Graphical Editor</h2>
+<p>Let&#39;s just get started with some code. I'll be describing how to add drop functionality to the logic editor
+(available from our <a href="http://download.eclipse.org/tools/gef/downloads/">download page</a>).
+This will
+allow the user to drag files from the Navigator or Package Explorer (or any file explorer that
+supports dragging files) and drop them onto the logic editor.
+The editor will respond by creating a new label with the file name as its text. First off, you need
+a TransferDropTargetListener (GEF provides you with AbstractTransferDropTargetListener for you to subclass).
+Create a subclass called FileTransferDropTargetListener:
+</p>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>package org.eclipse.gef.examples.logicdesigner.dnd;
+
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.dnd.AbstractTransferDropTargetListener;
+
+public class FileTransferDropTargetListener
+ extends AbstractTransferDropTargetListener
+{
+
+ public FileTransferDropTargetListener(EditPartViewer viewer, Transfer xfer) {
+ super(viewer, xfer);
+ }
+
+ public FileTransferDropTargetListener(EditPartViewer viewer) {
+ super(viewer, FileTransfer.getInstance());
+ }
+
+ protected void updateTargetRequest() {}
+
+}</pre></td>
+ </tr>
+</table>
+<p>The first thing you need to do is override createTargetRequest() to create the appropriate request.
+CreateRequest should be used so that a new label will be created when a file is dropped on the editor.
+The CreateRequest needs a CreationFactory to create the new object that will be passed to the command.
+You should implement your own factory that will create a new LogicLabel based on the file name (which you will
+set later during the drop event).</p>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>package org.eclipse.gef.examples.logicdesigner.dnd;
+
+import org.eclipse.gef.requests.CreationFactory;
+import org.eclipse.gef.examples.logicdesigner.model.LogicLabel;
+
+public class FileLabelFactory implements CreationFactory {
+
+ private String text = &quot;&quot;;
+
+ public Object getNewObject() {
+ LogicLabel label = new LogicLabel();
+ label.setLabelContents(text);
+ return label;
+ }
+
+ public Object getObjectType() {
+ return LogicLabel.class;
+ }
+
+ public void setText(String s) {
+ text = s;
+ }
+}</pre></td></tr></table>
+<p>Now that we&#39;ve got our factory, we can add a field to our drop listener to store this factory...</p>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>private FileLabelFactory factory = new FileLabelFactory();</pre></td>
+ </tr>
+</table>
+<p>and set the factory on the CreateRequest during createTargetRequest()...</p>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>protected Request createTargetRequest() {
+ CreateRequest request = new CreateRequest();
+ request.setFactory(factory);
+ return request;
+}</pre></td>
+ </tr>
+</table>
+<p>Next, implement updateTargetRequest() by setting the current drop location on the request.</p>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>protected void updateTargetRequest() {
+ ((CreateRequest)getTargetRequest()).setLocation(getDropLocation());
+}</pre></td>
+ </tr>
+</table>
+<p>
+Now since we&#39;ll be dragging files from the Navigator (or any file explorer), we want to ensure that
+the file won&#39;t be deleted. To do this, override handleDragOver() and set the drop detail to DND.DROP_COPY.
+If we leave it as the default (DND.DROP_MOVE), after the drop the drag source will assume the file
+is somewhere else and remove the original. We want the file to stay right where it is.</p>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>protected void handleDragOver() {
+ getCurrentEvent().detail = DND.DROP_COPY;
+ super.handleDragOver();
+}</pre></td>
+ </tr>
+</table>
+<p>Finally, we need to implement handleDrop() to get the file name from
+the current DropTargetEvent. The data field of the event is typed as Object but
+the actual data type is dependent on the transfer type. For FileTransfers, the
+data is a String array storing the full paths of the files being dragged. To make
+this easier, we&#39;ll only be concerned with the first file in the list and we&#39;ll
+only display the file name, not the full path. Once we extract this information
+from the current event, set the text on the factory and the superclass will do
+the rest.</p>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>protected void handleDrop() {
+ String s = ((String[])getCurrentEvent().data)[0];
+ String separator = System.getProperty("file.separator");
+ s = s.substring(s.lastIndexOf(separator) + 1);
+ factory.setText(s);
+ super.handleDrop();
+}</pre></td>
+ </tr>
+</table>
+<p>
+That&#39;s all we need to do to implement our drop listener. The superclass will take care obtaining a Command from the target edit part and executing it. All that&#39;s left
+is to add the listener to our editor and see what happens. To do this, we need to change initializeGraphicalViewer()
+in the LogicEditor class. Notice there are already 2 drop listeners being added -- a LogicTemplateTransferDropTargetListener,
+which allows for dragging templates from the palette and dropping them onto the editor for creation;
+and a TextTransferDropTargetListener, which allows the user to drag text (such as from a word
+processor) and drop it on an already existing label
+to change the label text to match the text being dragged. We need to add our listener to the viewer by
+adding the following line to this method:</p>
+<table border cols="1" width="100%" bgcolor="#CCCCCC">
+ <tr>
+ <td><pre>getGraphicalViewer().addDropTargetListener(
+ new FileTransferDropTargetListener(getGraphicalViewer()));</pre></td>
+ </tr>
+</table>
+<h2>Behind The Scenes</h2>
+<p>For most people, all you need (or want) to know is that when you add a listener to a viewer, the
+viewer creates a new DragSource or DropTarget, if one has not already been created. The viewer
+also ensures the DragSource/DropTarget is aware of the Transfers from all of the listeners that have
+been added. For those of you interested in a more intricate look at what's happening behind
+the scenes, read on. (I'll be explaining how drop
+listeners are added, but drag listeners work in a similar fashion.)
+</p>
+<p>When you add a TransferDropTargetListener to an EditPartViewer, the viewer adds the listener to the
+DelegatingDropAdapter. Next, the DropTarget is refreshed. During the refresh, the viewer
+checks to see if the DelegatingDropAdapter is empty (i.e. it has no listeners) and if so, sets the
+DropTarget (an SWT widget) to null. This occurs because when there are no listeners to delegate the drop
+events to, there's no reason to be notified of these drop events. When the first listener is
+added to the DelegatingDropAdapter (in other words, the DelegatingDropAdapter is not empty but the
+DropTarget is still null), the viewer creates a new DropTarget for the viewer's control and sets all
+possible styles (DND.DROP_MOVE, DND.DROP_COPY, DND.DROP_LINK). This makes all styles available to
+the delegated listeners, even if they don't use them. Finally, the viewer sets the Transfer types on
+the DropTarget by getting them from the DelegatingDropAdapter. The DelegatingDropAdapter
+obtains these transfer types by querying all of its listeners for their transfer types and adding
+them all to an array. This completes the DropTarget setup and the DelegatingDropAdapter will now be
+notified of DropTargetEvents. WARNING: You can't mix your own DropTarget with the DropTarget created
+by the viewer. This is because, according to the DropTarget javadoc, &quot;there can only be a one
+to one mapping between a Control and a DropTarget.&quot; If you try to create another DropTarget on the
+same control, you'll get an error.</p>
+<p>The DelegatingDropAdapter chooses one listener to be active
+(inactive listeners will not receive events) and refreshes the active listener before each event. To
+be considered active, a listener must satisfy three conditions: 1) The transfer type of the listener
+must match up with the transfer type
+of the data being dragged. 2) There must be an EditPart under the mouse cursor that understands the
+listeners request. 3) The listener must be the first listener in the list to satisfy the first two
+conditions. The active listener could potentially change during each event, based on mouse location,
+modifier keys pressed, etc. In AbstractTransferDropTargetListener.isEnabled(DropTargetEvent), the
+listener tries to match its transfer type with one of the supported transfer types in the event. If
+a match is found, the listener tries to find an EditPart at the current mouse location that
+understands its target request. If a target edit part is found, the listener is enabled and
+the DelegatingDropTargetAdapter stops looking for listeners to handle this event. Then the event is
+actually delegated to the active listener. If the active listener changes, the old listener gets a
+dragLeave() event and the new listener gets a dragEnter() event to ensure proper initialization and
+clean-up is available.</p>
+<h2>Summary</h2>
+<p>Adding drag and drop support to an EditPartViewer is a fairly simple task. And by doing so, your GEF
+application will be able to interact with other views, editors and applications by transferring data
+at the OS level. All that is really needed is a subclass of AbstractTransferDragSourceListener or
+AbstractTransferDropTargetListener added to the viewer with the appropriate Transfer type. In
+this article, I introduced a very simple drop listener to demonstrate how easy it is to implement
+such a feature. Real-world applications would most likely perform a more meaningful task, but
+the overall process is the same.</p>
+<h2>Source Code</h2>
+<p>You can get the source code for the standalone SWT example <a href="DNDExample.java">here</a>.</p>
+<h2>Acknowledgements</h2>
+<p>The author would like to thank Randy Hudson, Daniel Lee, David Williams, and
+ Nitin Dahyabhai for providing constructive comments on the article.</p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the United States, other countries, or both.</small></p>
+
+</body>
+
+</html>
diff --git a/Article-GEF-editor/gef-schema-editor.html b/Article-GEF-editor/gef-schema-editor.html
new file mode 100644
index 0000000..75a83e9
--- /dev/null
+++ b/Article-GEF-editor/gef-schema-editor.html
@@ -0,0 +1,1000 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<title>Building a Database Schema Diagram Editor with GEF</title>
+<link rel="stylesheet" href="../default_style.css"/>
+</head>
+
+<BODY vLink=#800080 link=#0000FF>
+<DIV align=right>&nbsp; <FONT face="Times New Roman, Times, serif"><FONT
+ size=-1>Copyright © 2004 Realsolve Solutions Ltd.</FONT></FONT></DIV>
+&nbsp;
+<DIV align=right>
+ <table cellspacing=0 cellpadding=2 width="100%" border=0>
+ <tbody>
+ <tr>
+ <td valign=top align=left bgcolor=#0080c0 colspan=2><b><font
+ face=Arial,Helvetica><font color=#ffffff>&nbsp;Eclipse Corner
+ Article</font></font></b></td>
+ </tr>
+ </tbody>
+ </table>
+</DIV>
+<H1><IMG border="0" src="images/Idea.jpg" width="120" height="86"></H1>
+<CENTER>
+ <h1>Building a Database Schema Diagram Editor<br>
+ with GEF</h1>
+</CENTER>
+
+<blockquote>
+<b>Summary</b>
+
+<br>
+ GEF is a very powerful framework for visually creating and editing models. With a small initial investment,
+ even the relative Eclipse novice can be quickly up and running, building applications with graphical editing capabilities.
+ To illustrate, this article uses a relational database schema diagram editor with a deliberately
+ simplified underlying model, but with enough bells and whistles to show some of the interesting features of GEF at work.
+ <p><b> Phil Zoio, Realsolve Solutions Ltd.</b> <br>
+ <font size="-1">September 27, 2004</font> </p>
+</blockquote>
+
+<hr width="100%">
+
+<h2>Introduction</h2>
+<p>
+Having graphical editing capabilities can be a real asset, if not an essential feature, for many tools and applications. Examples are not
+hard to think of: UML tools, GUI builders, in fact, any application which comprises a dynamic model which can be visualized.
+With GEF, Eclipse developers have at their disposal a framework which can really simplify development of graphical editors.
+This article uses a simple but non-trivial example to show how a GEF application works -
+and what you need to do to get it to perform its little miracles.
+</p>
+<p>
+The screenshot below shows what our example editor looks like.
+The edit area uses a "flyout" palette which contains some very basic entries and can be minimized to increase the editable screen area.
+On the right side is a scrollable graphical viewer containing the tables and their relationships.
+</p>
+<p> <img src="images/editor.JPG" height=645 width=597 align=CENTER></p>
+
+<p> <img src="images/tryit.gif" width="61" height="13"> Download and unzip the
+ example plug-in <a href="schemaeditor.zip">schemaeditor.zip</a> into your <i>eclipse/</i>
+ directory, then create a new diagram by launching the wizard from the File menu:
+ File -> New -> Example ... -> GEF (Graphical Editing Framework) -> Schema Diagram
+ Editor. </p>
+
+<p>
+At the heart of GEF is the <B>Model-View-Controller</B> pattern, discussed in Randy Hudson's introductory tutorial
+<i><a href="http://www-106.ibm.com/developerworks/opensource/library/os-gef/" target="_blank">How to Get Started with the GEF</a></i>, and also
+providing a focus for much of this article.
+</p>
+<h2>The Model</h2>
+<p>
+The starting point for any GEF application is the model. This is what needs to be displayed, edited and persisted.
+Our somewhat oversimplified model contains the following classes:
+</p>
+<ul>
+ <li><CODE>Table</CODE>: represents a relational database table. The only attribute that the table holds itself is the name</li>
+ <li><CODE>Column</CODE>: represents a table column. Here we are interested in the column name and the type of data, which itself can either be <CODE>VARCHAR</CODE> or <CODE>INTEGER</CODE></li>
+ <li><CODE>Relationship</CODE>: represents a primary key/foreign key relationship between two tables.
+ The foreign key table we denote the <B>source</B> of the relationship, while the primary key table is the <B>target</B>.
+ Note that our model applies a relationship directly between two tables,
+ rather than between foreign and primary key fields in the respective tables,
+ as we would in the real world</li>
+ <li><CODE>Schema</CODE>: simply represents all the tables we plan to group together (and ultimately show on the same diagram)</li>
+</ul>
+Our model is extremely simple, but does at least include the two key forms of relationship in a typical GEF model:
+<ul>
+ <li>The <B>parent-child</B> relationship that exists between schemas and tables, and between tables and columns</li>
+ <li><B>Connections</B> between different <B>nodes</B>.
+ In our example application, the connections are in the form of primary key/foreign key relationships, with the nodes being the tables</li>
+</ul>
+<p>
+Of course, we need to decide what we want our editor to be able to do with the model. Here, we want to be able to:
+</p>
+<ul>
+ <li>lay our tables nicely on the diagram. The diagram must scale to accommodate any growth in our model, and should be readable</li>
+ <li>add new tables to our schema, and new columns to our table, using either drag and drop or point and click</li>
+ <li>directly edit the names of the tables as well as both the names and types of our columns. In both cases, we want validation to tell us when we are typing in nonsense</li>
+ <li>use drag and drop to set up relationships between tables, as well as to change these relationships</li>
+ <li>use drag and drop to move column definitions from one table to another, or to reorder columns within tables</li>
+ <li>be able to delete tables, columns and relationships by hitting the delete key</li>
+ <li>have a choice between manually laying out our diagram, and having this done automatically. When using manual layout, we want to be able to
+ shift our tables around using drag and drop</li>
+</ul>
+There are of course many more things we would like to be able to do with our editor,
+but we have enough here to be able to test out many of the most commonly used GEF features.
+<h2>The View</h2>
+
+<h3>Figures</h3>
+<p>
+The display component in both GEF and draw2d is built around the draw2d <code>IFigure</code> interface.
+Figures in draw2d are lightweight objects which can be nested to create a complex graphical representation.
+The view is created by rendering and laying out the set of figures which reflect the model.
+In a typical GEF application, you would normally create a set of customized <code>IFigure</code> implementations, each subclassing <code>Figure</code>.
+</p>
+
+<p>
+<img src="images/tip.gif" width="62" height="13">
+If you're unfamiliar with draw2d and <code>Figures</CODE>, take a look at Daniel Lee's article on <i><a href="../Article-GEF-Draw2d/GEF-Draw2d.html">Display a UML Diagram using Draw2D</a></i>,
+</p>
+
+<p>
+In our application we have the following figures:
+<ul>
+ <li><CODE>EditableLabel</CODE>: a subclass of the draw2d <CODE>Label</CODE> class which itself
+ subclasses <CODE>Figure</CODE>. We need this for the column and table names</li>
+ <li><CODE>ColumnsFigure</CODE>: a container for all the column labels</li>
+ <li><CODE>TableFigure</CODE>: contains an <CODE>EditableLabel</CODE> for the table name, as well as a <CODE>ColumnsFigure</CODE> for the column names</li>
+ <li><CODE>SchemaFigure</CODE>: a container for all the <CODE>TableFigures</CODE> in the schema</li>
+</ul>
+<p>
+We haven't provided any custom figures to represent connections - we simply use the draw2d <CODE>PolylineConnection</CODE> class,
+which is a just a line with zero or more kinks or bend points.
+</p>
+<p>
+Because the table names as well as the number of columns and their names are likely to change during the lifetime of a <CODE>TableFigure</CODE> instance,
+we want our <CODE>ColumnsFigure</CODE> and <CODE>TableFigure</CODE> to be resizable.
+A key role in allowing this to happen is played by layout managers, another important part of the draw2d framework.
+</p>
+
+<h3>Layout Management</h3>
+<p>
+GEF provides a layout management framework which is distinct from the Swing and Eclipse SWT layout managers:
+its job is specifically to handle layout of the child figures of draw2d <CODE>IFigure</CODE> instances.
+Your job as an application developer is to decide which layout manager to use
+for each figure containing child figures.</p>
+<p>
+Broadly speaking, there are three types of layout managers:
+<ul>
+ <li><B>Structured layout managers</B>, such as <CODE>FlowLayout</CODE> and <CODE>ToolbarLayout</CODE>,
+ which lay out child figures according to their <B>order</B> by arranging them vertically or horizontally
+ <li><B>Constraint-based layout managers</B>, such as the <CODE>XYLayout</CODE> and the <CODE>DelegatingLayout</CODE>.
+ Here the application itself participates directly in the placement of figures by setting a constraint <CODE>Object</CODE>
+ for each child figure. In the case of the <CODE>XYLayout</CODE>, this object is a <CODE>Rectangle</CODE>
+ with specified location and size</li>
+ <li>
+ <B>Layout using geometry computation algorithms</B>. Here layout is determined by applying a series of rather complex algorithms to
+ calculate the "best" layout for child figures. The algorithms take a specially constructed data structure as input and
+ deliver as their output a solution to geometrical problems such as node placement and routing of paths.
+ The algorithms provided by GEF are in the classes <CODE>DirectedGraphLayout</CODE>
+ and <CODE>CompoundDirectedGraphLayout</CODE>
+ </li>
+</ul>
+<p>
+The GEF developer needs to understand which layout managers can be best applied in which situation.
+Structured layout managers are suitable when there is a well defined parent-child relationship between the
+containing figure and its children <I>and</I>
+the children are not related to each other in arbitrary ways.
+In our example application, <CODE>TableFigure</CODE> uses a <CODE>ToolbarLayout</CODE> to place its children
+(simply stacking them vertically). The <CODE>ColumnsFigure</CODE> does the same with its child <CODE>Label</CODE> objects,
+but uses the <CODE>FlowLayout</CODE> for this purpose.
+<p>
+This kind of arrangement of course does not work with <CODE>SchemaFigure</CODE> -
+any of its child <CODE>TableFigures</CODE> may be related to any other via a primary key/foreign key relationship,
+so we cannot simply stack the table figures next to each other or side by side.
+For <CODE>SchemaFigure</CODE> we need to choose between either a constraint-based layout manager or a graph layout manager.
+In our example application we use both. Users can switch between manual layout, which involves dragging table figures
+to their desired locations, and automatic placement of figures using geometry computation algorithms.
+How this is done is beyond the scope of this article,
+although interested readers can examine the
+<CODE>DelegatingLayoutManager</CODE> class in the example application source code.
+
+<p>
+<img src="images/tryit.gif" width="61" height="13"> Open a schema diagram editor and make some changes, switching between manual
+and automatic layout using the
+<img src="images/layout.gif" width="16" height="16"> icon.
+</p>
+
+<h2>The Controller</h2>
+<p>
+We only really move into GEF territory proper when we start talking about the controller in the MVC trilogy.
+GEF provides an abstraction that prevents the model from having to know about the figures, and vice versa.
+At the centre of this architecture is the <CODE>EditPart</CODE> interface.
+</p>
+<h3>EditParts</h3>
+<p>
+The first thing to know is that typically every separately editable part of the model will need to be
+associated with an <CODE>EditPart</CODE> instance. This means that there will usually be a close to one-for-one mapping between classes
+in the model hierarchy and classes in the <CODE>EditPart</CODE> hierarchy.
+In most cases, an <CODE>EditPart</CODE> is also a <CODE>GraphicalEditPart</CODE>, which means that
+as well as managing a model component, it also has an associated view component. Because the
+model and view are completely decoupled, all coordination between the model and the view must be managed by the <CODE>EditPart</CODE>.
+This coordination can be divided into two separate areas of activity:
+<ol>
+ <li>Acting as a listener to changes in the model so that these can be propagated to the view, by calling layout related methods. We discuss this
+ in detail in the section <A HREF="#viewUpdate">Updating an Repainting the Display</A>
+ </li>
+ <li>Providing a means by which user interaction can be interpreted and propagated to changes in the model.
+ Central to this are <CODE>EditPolicies</CODE>, discussed in the section <A HREF="#editPolicies">EditPolicies and Roles</A>
+ </li>
+ <li>Managing what are known as direct edits, where the user types text directly into an editable control
+ </li>
+</ol>
+In our example application we have the following <CODE>EditPart</CODE> implementations
+<ul>
+ <li><CODE>SchemaDiagramPart</CODE>: represents a <CODE>Schema</CODE> instance and associated <CODE>SchemaFigure</CODE></li>
+ <li><CODE>TablePart</CODE>: represents a <CODE>Table</CODE> and manages the <CODE>TableFigure</CODE> and child view components</li>
+ <li><CODE>ColumnPart</CODE>: enables editing functionality for the column label</li>
+ <li><CODE>RelationshipPart</CODE>: represents a primary key/foreign key relationship.
+ In the same way that Relationship in the model is associated with two <CODE>Table</CODE> instances,
+ a <CODE>RelationshipPart</CODE> is associated with two <CODE>TableParts</CODE></li>
+</ul>
+<p>
+When an instance of any of these classes is created, it is automatically associated with a part of the model.
+This is a build-in feature of the framework. As part of our editor, we have to provide an <CODE>EditPartFactory</CODE> implementation.
+Ours looks like this:
+</p>
+<font color="#0000cc">
+<pre>public class SchemaEditPartFactory implements EditPartFactory
+{
+ public EditPart createEditPart(EditPart context, Object model)
+ {
+ EditPart part = null;
+ if (model instanceof Schema)
+ part = new SchemaDiagramPart();
+ else if (model instanceof Table)
+ part = new TablePart();
+ else if (model instanceof Relationship)
+ part = new RelationshipPart();
+ else if (model instanceof Column)
+ part = new ColumnPart();
+ part.setModel(model);
+ return part;
+ }
+}</pre>
+</font>
+<p>
+<CODE>SchemaDiagramPart</CODE>, <CODE>TablePart</CODE> and <CODE>ColumnPart</CODE>
+all extend <CODE>AbstractGraphicalEditPart</CODE> and implement <CODE>GraphicalEditPart</CODE>.
+In addition, <CODE>TablePart</CODE> can be a <I>node</I> in a primary/foreign key relationship,
+so it has to implement <CODE>NodeEditPart</CODE>.
+Finally, <CODE>RelationshipPart</CODE> represents the <I>connection</I> part of the relationship,
+so it extends <CODE>AbstractConnectionEditPart</CODE>.
+</p>
+<p>
+<CODE>SchemaDiagramPart</CODE>'s job is primarily managing the layout of the tables.
+<CODE>ColumnPart</CODE>'s role is relatively limited - it just needs to handle editing of the label displaying name and type information.
+</p>
+<p>
+Of the four of these, <CODE>TablePart</CODE> has the most to do.
+In GEF, most of the work that is done to manage relationships is done
+by <CODE>NodeEditPart</CODE>, and not <CODE>ConnectionEditPart</CODE>.
+Because we sometimes need to rename tables, <CODE>TablePart</CODE> also has to manage
+editing of the label that displays its name.
+We will spend more of our time focusing on <CODE>TablePart</CODE>.
+</p>
+
+
+In a GEF application, there are a number of tasks <CODE>EditPart</CODE> subclasses must
+fulfill:
+<ol>
+ <li>
+ <p>
+ Provide a figure instance to be associated with the <CODE>EditPart</CODE>.
+ In the case of <CODE>TablePart</CODE>, we simply return a new <CODE>TableFigure</CODE> instance with a name label:
+<font color="#0000cc">
+<pre> protected IFigure createFigure()
+ {
+ Table table = getTable();
+ EditableLabel label = new EditableLabel(table.getName());
+ TableFigure tableFigure = new TableFigure(label);
+ return tableFigure;
+ }</pre>
+ </font>
+ </li>
+ <li>
+ <p>
+ <CODE>EditParts</CODE> which represent parent objects in <B>parent-child</B> relationships need to override <CODE>getModelChildren()</CODE>.
+ In the case of <CODE>TablePart</CODE>, our
+ implementation of this method simply returns the <CODE>Column</CODE> objects it contains:
+<font color="#0000cc">
+<pre> protected List getModelChildren()
+ {
+ return getTable().getColumns();
+ }</pre>
+</font>
+ Note that the <CODE>AbstractEditPart</CODE> implements a parallel method <CODE>getChildren()</CODE>,
+ which returns the <CODE>EditPart</CODE> collection representing the model children.
+ In the case of <CODE>TablePart</CODE>, <CODE>getChildren()</CODE> returns a list of <CODE>ColumnPart</CODE> objects.
+ We know this because our implementation of <CODE>EditPartFactory</CODE> associates
+ <CODE>Column</CODE> model instances with instances of <CODE>ColumnPart</CODE>.
+ The <CODE>EditPart</CODE> <CODE>List</CODE> returned by <CODE>getChildren()</CODE>
+ always needs to be kept in sync with the <CODE>getModelChildren()</CODE>.
+ In the Section <A HREF="#synchronising">Synchronizing EditPart Relationships with Model Changes</A> we describe how this happens
+ <br>
+ </li>
+ <li>
+ <p>
+ If the parent <CODE>EditPart</CODE>'s figure is not the direct parent of the child <CODE>EditPart</CODE>'s figure, you will
+ need to override <CODE>AbstractGraphicalEditPart.getContentPane()</CODE>.
+ The <B>content pane</B> is the containing figure into which GEF adds figures created by child <CODE>EditParts</CODE>,
+ which is by default the figure returned by the <CODE>EditPart</CODE>'s <CODE>createFigure()</CODE> method.
+ </p>
+ <p>
+ In our example application
+ the column labels are not contained within a <CODE>TableFigure</CODE> but within its <CODE>ColumnsFigure</CODE> child.
+ Our implementation of <CODE>getContentPane()</CODE> in <CODE>TablePart</CODE> reflects this:
+<pre>public IFigure getContentPane()
+{
+ TableFigure figure = (TableFigure) getFigure();
+ return figure.getColumnsFigure();
+}</pre>
+<p>
+<img src="images/tip.gif" width="62" height="13"> Do not add and remove child figures
+by overriding <CODE>AbstractGraphicalEditPart.addChildVisual()</CODE> and <CODE>AbstractGraphicalEditPart.removeChildVisual()</CODE>.
+Override <CODE>getContentPane()</CODE> instead.
+</p>
+ </li>
+ <li>
+ <CODE>EditParts</CODE> which represent nodes (model objects which may participate in connections)
+ must also implement a number of additional methods defined in the interface <CODE>NodeEditPart</CODE>
+ <ul>
+ <li>
+ <p>
+ <CODE>protected List getModelSourceConnections()</CODE>: this returns all the connection model objects for which the
+ node model object is the source.
+ In our example application, we have identified foreign keys as the source of a primary key/foreign key relationship.
+ <CODE>TablePart</CODE>'s implementation contains just a single line of code:
+ </p>
+ <p>
+ <font color="#0000cc"><CODE>return getTable().getForeignKeyRelationships();</CODE></font>
+ </p>
+ <p>
+ This method simply returns the <CODE>Relationship</CODE> objects for
+ which the current <CODE>TablePart</CODE>'s <CODE>Table</CODE> is the foreign key.
+ Once again, there is a parallel method <CODE>getSourceConnections()</CODE>,
+ which returns the <CODE>List</CODE> of <CODE>RelationshipParts</CODE> associated with these relationships.
+ We also consider in the Section <A HREF="#synchronising">Synchronizing EditPart Relationships with Model Changes</A>
+ how the <CODE>ConnectionEditPart</CODE> list returned by
+ <CODE>getSourceConnections()</CODE> stays in sync with the
+ <CODE>Relationship</CODE> list returned by <CODE>getModelSourceConnections()</CODE>
+ </p>
+ </li>
+ <li>
+ <p>
+ <CODE>protected List getModelTargetConnections()</CODE>:
+ this works identically to <CODE>getModelSourceConnections()</CODE>,
+ except that it returns the <CODE>Relationship</CODE> objects for which the current
+ <CODE>TablePart</CODE>'s <CODE>Table</CODE> is the primary key
+ </p>
+ </li>
+ <li>
+ <p>
+ the node <CODE>GraphicalEditPart</CODE> must also provide implementations of the
+ <CODE>NodeEditPart</CODE> <CODE>getSourceConnectionAnchor()</CODE> and <CODE>getTargetConnectionAnchor()</CODE> methods.
+ In each case, these methods return objects which represent the points to which connections between nodes can be attached
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>Provide an implementation for <CODE>createEditPolicies()</CODE>,
+ during which <CODE>EditPolicy</CODE> implementations are associated with specific editing roles.
+ The <CODE>EditPolicy</CODE> and its associated roles, <CODE>Request</CODE> and
+ <CODE>Command</CODE> objects are a fundamental part of GEF which we discuss in the next sections
+ </li>
+</ol>
+
+<h3>Requests</h3>
+<p>
+We begin with requests because these are really the starting point of the editing process that GEF application developer works with.
+In fact, the real magic in GEF is being able to interpret user interactions and transform
+these into <B>requests</B>,
+which the application can work with in an object-oriented fashion.
+For example, when we drag from the "New Column" palette button onto an existing
+table on the diagram, we are of course trying to add a new column to the table.
+As users interact with the application, GEF's behind-the-scenes work produces <CODE>Request</CODE> objects.
+In the create column example, GEF produces
+a <CODE>CreateRequest</CODE>, which contains the following important information:
+<ul>
+ <li>the instance of the new model object that has been created
+ (but probably not yet configured and definitely not added to the rest of the model)</li>
+ <li>The <CODE>EditPart</CODE> object which is hosting this request.
+ In our case this will be an instance of <CODE>TablePart</CODE></li>
+</ul>
+Different types of user interactions will produce different <CODE>Request</CODE> types
+- these are well covered in the GEF API and platform documentation.
+These request objects neatly encapsulate the information the application needs to transform user interaction into changes to the model.
+We can take a look at how this is done once we have looked at <CODE>Commands</CODE> and <CODE>EditPolicies</CODE>,
+which we cover in the next section.
+
+
+
+<A NAME="editPolicies"></A>
+<h3>EditPolicies and Roles</h3>
+<p>
+An <CODE>EditPolicy</CODE> is really just an extension of an <CODE>EditPart</CODE>,
+in the sense that certain editing related tasks are passed on from the <CODE>EditPart</CODE> to its <CODE>EditPolicy</CODE> delegates.
+<CODE>EditPart</CODE> implementations would rapidly become bloated if they had to take on everything that <CODE>EditPolicies</CODE> do.
+To understand what an <CODE>EditPolicy</CODE> is and what it does,
+lets start by looking at the <CODE>createEditPolicies()</CODE> method in <CODE>TablePart</CODE>:
+<font color="#0000cc">
+<pre>protected void createEditPolicies()
+{
+ installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new TableNodeEditPolicy());
+ installEditPolicy(EditPolicy.LAYOUT_ROLE, new TableLayoutEditPolicy());
+ installEditPolicy(EditPolicy.CONTAINER_ROLE, new TableContainerEditPolicy());
+ installEditPolicy(EditPolicy.COMPONENT_ROLE, new TableEditPolicy());
+ installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new TableDirectEditPolicy());
+}</pre>
+</font>
+<p>
+The purpose of this method is simply to decorate the <CODE>TablePart</CODE> with editing functionality.
+Each call to <CODE>installEditPolicy()</CODE> in the above method
+registers an <CODE>EditPolicy</CODE> with the <CODE>EditPart</CODE>.
+The key constant used in each of these calls is the name of the <B>role</B> used.
+For example, <CODE>EditPolicy.CONTAINER_ROLE</CODE> is
+simply the string <I>"ContainerEditPolicy"</I>.
+The container role is relevant for <CODE>TablePart</CODE> because we know that tables contain
+columns, and one of our application's requirements is to create new columns
+and add these to existing tables.
+</p>
+<p>
+The use of a particular role name in the <CODE>installEditPolicy()</CODE> call is really just a convention - the framework does not
+attach any behavior to a particular choice of role name.
+What distinguishes an <CODE>EditPolicy</CODE> implementation (and its corresponding role) is the type of requests it understands.
+Most of the abstract <CODE>EditPolicy</CODE> classes
+provide an implementation of the <CODE>getCommand(Request request)</CODE> method.
+</p>
+<p>
+In <CODE>ContainerEditPolicy</CODE> we find the following:
+
+<font color="#0000cc">
+<pre>public Command getCommand(Request request) {
+ if (REQ_CREATE.equals(request.getType()))
+ return getCreateCommand((CreateRequest)request);
+ if (REQ_ADD.equals(request.getType()))
+ return getAddCommand((GroupRequest)request);
+ if (REQ_CLONE.equals(request.getType()))
+ return getCloneCommand((ChangeBoundsRequest)request);
+ if (REQ_ORPHAN_CHILDREN.equals(request.getType()))
+ return getOrphanChildrenCommand((GroupRequest)request);
+ return null;
+}</pre>
+</font>
+<p>
+Here <CODE>getCommand()</CODE> simply uses the request type to determine which <CODE>getXXXCommand()</CODE> method to call.
+In <CODE>ContainerEditPolicy</CODE>, <CODE>getCreateCommand()</CODE> is abstract -
+we must provide an implementation in order to use the base <CODE>ContainerEditPolicy</CODE> functionality.
+</p>
+<p>
+Here is our implementation of <CODE>TableContainerEditPolicy</CODE>:
+
+<font color="#0000cc">
+<pre>public class TableContainerEditPolicy extends ContainerEditPolicy
+{
+ protected Command getCreateCommand(CreateRequest request)
+ {
+ <img src="images/tag_1.gif" height=13 width=24 align=CENTER> Object newObject = request.getNewObject();
+ if (!(newObject instanceof Column))
+ {
+ return null;
+ }
+ Column column = (Column) newObject;
+
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> TablePart tablePart = (TablePart) getHost();
+ Table table = tablePart.getTable();
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> ColumnCreateCommand command = new ColumnCreateCommand();
+ command.setTable(table);
+ command.setColumn(column);
+ return command;
+ }
+}</pre>
+</font>
+<p>
+In most cases, our <CODE>EditPolicy</CODE> implementations simply amount to using a
+<CODE>Request</CODE> object to generate a <CODE>Command</CODE>.
+Our <CODE>getCreateCommand()</CODE> method
+<ul>
+ <li><img src="images/tag_1.gif" height=13 width=24 align=CENTER> gets the new object embodied in the <CODE>CreateRequest</CODE>
+ and makes sure that it is an instance of <CODE>Column</CODE>,</li>
+ <li><img src="images/tag_2.gif" height=13 width=24 align=CENTER> gets the <CODE>Table</CODE> object associated with
+ the host <CODE>EditPart</CODE>, and</li>
+ <li><img src="images/tag_3.gif" height=13 width=24 align=CENTER> creates an instance of the relevant <CODE>Command</CODE> class,
+ configures it with the <CODE>Table</CODE> and <CODE>Column</CODE> information, and returns it</li>
+</ul>
+Our <CODE>TablePart</CODE> <CODE>createEditPolicies()</CODE> implementation uses one of
+our customized <CODE>EditPolicy</CODE> implementations for each invocation of
+<CODE>installEditPolicy()</CODE>.
+Each of our <CODE>EditPolicy</CODE> implementations subclasses a GEF-provided abstract <CODE>EditPolicy</CODE> for a different role.
+For example, <CODE>TableEditPolicy</CODE> extends <CODE>ComponentEditPolicy</CODE> to
+fulfill the <CODE>EditPolicy.COMPONENT_ROLE</CODE>.
+It does so by implementing the
+<CODE>createDeleteCommand(GroupRequest request)</CODE> to handle requests of type <CODE>REQ_DELETE</CODE>.
+<p>
+The GEF platform documentation provides a lot more detail on the types of roles and requests and how and when they can be used,
+so we won't cover them in any more detail here.
+</p>
+<h3>Commands</h3>
+
+<p>
+<CODE>Command</CODE> is GEF's abstract base class whose function is simply to encapsulate our application's response to a request.
+Key methods included in the <CODE>Command</CODE> class are the following:
+<ul>
+ <li><CODE>execute()</CODE>:
+ <CODE>Command</CODE> provides a no-op implementation. As the name suggests,
+ this contains the code to apply any change to the model that the <CODE>Command</CODE> object encapsulates</li>
+ <li><CODE>undo()</CODE>: used to reverse the effect of <CODE>execute()</CODE>.
+ Here <CODE>Command</CODE> also provides a no-op implementation</li>
+ <li><CODE>redo()</CODE>: used redo a command execution.
+ The <CODE>Command</CODE> implementation simply calls <CODE>execute()</CODE>, which should usually be adequate</li>
+ <li><CODE>canExecute()</CODE>: whether <CODE>execute()</CODE> can be executed.
+ The subclass can implement this to specify the conditions under which the command can be executed</li>
+ <li><CODE>canUndo()</CODE>: whether <CODE>undo()</CODE> can be executed.
+ The <CODE>Command</CODE> implementation simply returns true, which subclasses can override</li>
+ <li><CODE>canRedo()</CODE>: whether <CODE>redo()</CODE> can be executed. The <CODE>Command</CODE> implementation here also simply returns true</li>
+</ul>
+<p>
+Any non-trivial <CODE>Command</CODE> subclass would need to implement <CODE>execute()</CODE>.
+Implementation of <CODE>undo()</CODE> would be recommended in most cases. The other methods
+are optional and would only be overridden as required.
+</p>
+<p>
+Lets take a look at our rather straightforward <CODE>ColumnCreateCommand</CODE> implementation:
+
+<font color="#0000cc">
+<pre>public class ColumnCreateCommand extends Command
+{
+ private Column column;
+ private Table table;
+
+ public void setColumn(Column column)
+ {
+ this.column = column;
+ <img src="images/tag_1.gif" height=13 width=24 align=CENTER> this.column.setName(&quot;COLUMN &quot; + (table.getColumns().size() + 1));
+ this.column.setType(Column.VARCHAR);
+ }
+
+ public void setTable(Table table)
+ {
+ this.table = table;
+ }
+
+ public void execute()
+ {
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> table.addColumn(column);
+ }
+
+ public void undo()
+ {
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> table.removeColumn(column);
+ }
+}</pre>
+</font>
+Much of the class is self-explanatory.
+We have setter methods to populate the <CODE>Command</CODE> object
+with the newly-created <CODE>Column</CODE> as well as the
+target container <CODE>Table</CODE>.
+We arbitrarily provide a name and type for the <CODE>Column</CODE> <img src="images/tag_1.gif" height=13 width=24 align=CENTER>,
+which the user can later change.
+We can also see that <CODE>execute()</CODE> <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+simply adds the <CODE>Column</CODE> object to the <CODE>Table</CODE>,
+and <CODE>undo()</CODE> <img src="images/tag_3.gif" height=13 width=24 align=CENTER> simply reverses that change.
+<p>
+The use of <CODE>Commands</CODE> has two key advantages over using <CODE>EditPolicies</CODE> directly to effect model changes
+<ul>
+ <li>Commands are more elegant and in line with OO best practice</li>
+ <li>The <CODE>Command</CODE> framework has built-in support for undo and redo functionality</li>
+</ul>
+<p>
+<img src="images/tip.gif" width="62" height="13"> The <CODE>Command</CODE> implementation is closely tied to the model,
+and should be cleanly separated from GEF-specific components.
+It should not contain any references to <CODE>EditParts</CODE> or <CODE>EditPolicies</CODE>.
+Observing this rule preserves the clean separation
+between commands and the UI logic, helping to keep code more maintainable and bug-free.
+</p>
+
+
+<h2>Propagating Model Changes</h2>
+
+<p>
+Once we've changed the model, our GEF editor needs to propagate these changes to the UI. Our model, view and controller need
+to work together to achieve this.
+</p>
+<p>
+So far, we have discussed the <CODE>GraphicalEditPart</CODE>'s responsibility to provide a figure
+to represent the part of the model it is managing.
+To participate in a fully functional graphical editor, it needs to do more:
+<ul>
+ <li>It needs to act as a <B>listener</B> for changes in the model.
+ The model itself needs to <B>fire event notifications</B> which the <CODE>EditPart</CODE> can receive</li>
+ <li>It needs to maintain its own
+ child and connection relationships with other <CODE>EditParts</CODE>, keeping these in sync with changes to the model</li>
+ <li>It needs to update the figures that it is managing, and their layouts, in line with model changes</li>
+</ul>
+We discuss each of these in turn.
+
+<h3>Sending and Receiving Event Notifications</h3>
+<p>
+The requirements imposed on our model implementation are that
+<ol>
+ <li>it exposes a mechanism by which listeners can register interest in event notifications, and</li>
+ <li>it actually fires these event notifications at the appropriate times!</li>
+</ol>
+In our example application we want all our model objects to use a common framework,
+so we satisfy the first requirement by
+allowing all our model classes to extend <CODE>PropertyAwareObject</CODE>, which looks like this:
+
+<font color="#0000cc">
+<pre>public abstract class PropertyAwareObject implements Serializable
+{
+
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> public static final String CHILD = &quot;CHILD&quot;;
+ ... other String constants representing the other types of model changes
+
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> protected transient PropertyChangeSupport listeners = new PropertyChangeSupport(this);
+
+ protected PropertyAwareObject()
+ {
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> listeners.addPropertyChangeListener(l);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener l)
+ {
+ <img src="images/tag_4.gif" height=13 width=24 align=CENTER> listeners.removePropertyChangeListener(l);
+ }
+
+ protected void firePropertyChange(String prop, Object old, Object newValue)
+ {
+ <img src="images/tag_5.gif" height=13 width=24 align=CENTER> listeners.firePropertyChange(prop, old, newValue);
+ }
+
+ ...
+}</pre>
+</font>
+
+Our abstract model base class
+contains a few <CODE>String</CODE> constants <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+representing the types of model changes it knows about.
+It uses the <CODE>java.beans.PropertyChangeSupport</CODE> <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+to provide the "plumbing" for the event handling.
+It also exposes methods <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+and <img src="images/tag_4.gif" height=13 width=24 align=CENTER> which observers can use to register and deregister their
+interest in model changes.
+Finally, it includes a <CODE>firePropertyChange()</CODE> <img src="images/tag_5.gif" height=13 width=24 align=CENTER> method
+which subclasses can use to trigger property events.
+In our example of adding a column to a table, we see a good example in <CODE>Table</CODE>:
+
+<font color="#0000cc">
+<pre>public void addColumn(Column column)
+{
+ columns.add(column);
+ firePropertyChange(CHILD, null, column);
+}</pre>
+</font>
+
+With this mechanism available, we now need to take advantage in our <CODE>EditPart</CODE> listeners.
+Once again, we address the issue
+by providing a common base class for our <CODE>GraphicalEditParts</CODE> to extend, shown below:
+
+<font color="#0000cc">
+<pre>public abstract class PropertyAwarePart
+ extends AbstractGraphicalEditPart
+ implements PropertyChangeListener
+{
+ public void activate()
+ {
+ super.activate();
+ PropertyAwareObject propertyAwareObject = (PropertyAwareObject) getModel();
+ <img src="images/tag_1.gif" height=13 width=24 align=CENTER> propertyAwareObject.addPropertyChangeListener(this);
+ }
+
+ public void deactivate()
+ {
+ super.deactivate();
+ PropertyAwareObject propertyAwareObject = (PropertyAwareObject) getModel();
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> propertyAwareObject.removePropertyChangeListener(this);
+ }
+
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> //handle property change event
+ ...
+ }
+}</pre>
+</font>
+The GEF API documentation recommends the use of <CODE>activate()</CODE> and <CODE>deactivate()</CODE>
+to register or deregister model listeners.
+This is what we do here. After casting our model object to <CODE>PropertyAwareObject</CODE>,
+we add our <CODE>EditPart</CODE> as a listener in <img src="images/tag_1.gif" height=13 width=24 align=CENTER>,
+and allow it to be removed on deactivation in <img src="images/tag_2.gif" height=13 width=24 align=CENTER>.
+Once the <CODE>EditPart</CODE> is activated, any event notifications fired from our model
+will result in an invocation of <CODE>propertyChange()</CODE> <img src="images/tag_3.gif" height=13 width=24 align=CENTER>.
+Our <CODE>propertyChange()</CODE> implementation in <CODE>PropertyAwarePart</CODE> in turn delegates
+its response to other methods, which can be overridden by <CODE>EditPart</CODE> subclasses
+to customize reactions to specific changes in the model.
+
+<A NAME="synchronising"></A>
+<h3>Synchronizing EditPart Relationships with Model Changes</h3>
+<p>
+As we mentioned previously, the first thing the <CODE>EditPart</CODE> implementation needs to do in response to a model change is to
+ensure that its relationship hierarchy is in sync with that of the model.
+GEF provides a quick and easy solution in the form of three methods in the <CODE>EditPart</CODE>
+hierarchy. Before discussing
+a more performant approach that many applications will demand, we'll take a look at these methods.
+<ul>
+ <li><CODE>refreshChildren()</CODE>: when an <CODE>EditPart</CODE> represents a model object with children,
+ this method may need to be called.
+ Our example of adding a column to a table is a good one. The same applies for removing a column from a table.
+ If we moved a column from one table to another,
+ <CODE>refreshChildren()</CODE> would need to be called for both corresponding <CODE>TableParts</CODE>.
+ The base implementation of this method not only synchronizes your model and <CODE>EditPart</CODE> hierarchies -
+ it also adds or removes visual components as required
+ by calling the <CODE>AbstractGraphicalEditPart</CODE> <CODE>addChildVisual()</CODE> and <CODE>removeChildVisual()</CODE> methods
+ </li>
+ <li><CODE>refreshSourceConnections()</CODE>: this applies to any model change where the source of a connection
+ is added, removed or reassigned.
+ For example, if we added or deleted a primary/foreign key relationship, this method would need to be called
+ </li>
+ <li>
+ <CODE>refreshTargetConnections()</CODE>: this only applies to a model change where the target
+ of a connection is added, removed or reassigned. It would be needed for any change affecting
+ the primary key of a relationship between tables</li>
+</ul>
+<p>
+Returning to our example of adding a column to a table,
+our implementation of <CODE>PropertyAwarePart.propertyChange()</CODE> can be
+reduced to the following:
+<A NAME = "propertyChange"></A>
+<font color="#0000cc">
+<pre>public void propertyChange(PropertyChangeEvent evt)
+{
+ String property = evt.getPropertyName();
+
+ if (PropertyAwareObject.CHILD.equals(property))
+ {
+ <img src="images/tag_1.gif" height=13 width=24 align=CENTER> refreshChildren();
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> refreshVisuals();
+ }
+ ... handle other types of property changes here
+
+}</pre>
+</font>
+
+To resynchronize the <CODE>EditPart</CODE> hierarchy, we simply call
+<CODE>refreshChildren()</CODE> <img src="images/tag_1.gif" height=13 width=24 align=CENTER>.
+To update the display, we then call <CODE>refreshVisuals()</CODE> <img src="images/tag_2.gif" height=13 width=24 align=CENTER>.
+We discuss the
+mechanics and rationale for <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+in the next section.
+<p>
+Using the methods <CODE>refreshChildren()</CODE>, <CODE>refreshSourceConnections()</CODE> and <CODE>refreshSourceConnections()</CODE>
+can help you get your application working quickly, but if we want our application to run <B>efficiently</B>,
+we need to be more selective
+in the methods we use. For example, to add or remove a child, we can use the <CODE>EditPart</CODE> methods
+<CODE>addChild(EditPart, int)</CODE> and <CODE>removeChild(EditPart)</CODE>.
+Our revised <CODE>handleChildChange(PropertyChangeEvent)</CODE>below is a better performing replacement for <CODE>refreshChildren()</CODE>
+which uses these methods:
+<font color="#0000cc">
+<pre>protected void handleChildChange(PropertyChangeEvent evt)
+{
+ Object newValue = evt.getNewValue();
+ Object oldValue = evt.getOldValue();
+
+ if (newValue != null)
+ {
+ //add new child
+ <img src="images/tag_1.gif" height=13 width=24 align=CENTER> EditPart editPart = createChild(newValue);
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> int modelIndex = getModelChildren().indexOf(newValue);
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> addChild(editPart, modelIndex);
+ }
+ else
+ {
+ //remove an existing child
+ List children = getChildren();
+
+ EditPart partToRemove = null;
+ for (Iterator iter = children.iterator(); iter.hasNext();)
+ {
+ EditPart part = (EditPart) iter.next();
+ if (part.getModel() == oldValue)
+ {
+ <img src="images/tag_4.gif" height=13 width=24 align=CENTER> partToRemove = part;
+ break;
+ }
+ }
+ if (partToRemove != null)
+ <img src="images/tag_5.gif" height=13 width=24 align=CENTER> removeChild(partToRemove);
+ }
+}</pre>
+</font>
+<p>
+When adding our child, we need to call <CODE>createChild()</CODE>
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> to get a new <CODE>EditPart</CODE> for the model child.
+We then find the index of the model child in the containing <CODE>List</CODE><img src="images/tag_2.gif" height=13 width=24 align=CENTER>,
+and add our new child <CODE>EditPart</CODE> using this index <img src="images/tag_3.gif" height=13 width=24 align=CENTER>.
+When removing a child, we iterate through the existing children
+<CODE>EditParts</CODE> until we find the one representing the removed model child <img src="images/tag_4.gif" height=13 width=24 align=CENTER>.
+We then remove this <CODE>EditPart</CODE> <img src="images/tag_5.gif" height=13 width=24 align=CENTER>.
+</p>
+<p>
+Clearly, there is more work here than in simply calling <CODE>refreshChildren()</CODE>: but for large models where performance is critical, this effort will be worth it.
+</p>
+<p>
+Interested readers can examine <CODE>handleInputChange(PropertyChangeEvent)</CODE> and <CODE>handleOuputChange(PropertyChangeEvent)</CODE> in
+<CODE>PropertyAwarePart</CODE>
+for similar alternatives to <CODE>refreshSourceConnections()</CODE> and <CODE>refreshTargetConnections()</CODE> when updating relationships.
+</p>
+
+<A NAME="viewUpdate"></A>
+<h3>Updating and Repainting the Display</h3>
+
+<p>
+Consider our example of adding a column to a table. In draw2d terms,
+this is represented by adding an <CODE>EditableLabel</CODE> into
+a <CODE>ColumnsFigure</CODE> instance, which is itself contained within a <CODE>TableFigure</CODE>.
+Both the <CODE>ColumnsFigure</CODE> and the <CODE>TableFigure</CODE> both need to enlarge
+- the result otherwise is ugly (take my word for it!).
+</p>
+<p>
+A few things need to happen:
+<ol>
+ <li>The cached information held by the layout managers for the <CODE>TableFigure</CODE> and <CODE>ColumnsFigure</CODE>,
+ which includes minimum size and preferred size for the child figures, needs to be thrown away</li>
+ <li>The <CODE>SchemaFigure</CODE>'s layout manager needs to
+ update any cached constraint information it is holding for the <CODE>TableFigure</CODE></li>
+ <li>The bounds of both the <CODE>TableFigure</CODE> and the <CODE>ColumnsFigure</CODE>
+ need to change to reflect addition of the column&nbsp;</li>
+ <li>Any area affected by the change needs to be repainted</li>
+</ol>
+
+<p>
+In fact, all we need to achieve this is in our implementation of <CODE>refreshVisuals()</CODE> in <CODE>TablePart</CODE>:
+
+<font color="#0000cc">
+<pre>protected void refreshVisuals()
+{
+ TableFigure tableFigure = (TableFigure) getFigure();
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> Point location = tableFigure.getLocation();
+ SchemaDiagramPart parent = (SchemaDiagramPart) getParent();
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> Rectangle constraint = new Rectangle(location.x, location.y, -1, -1);
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> parent.setLayoutConstraint(this, tableFigure, constraint);
+}</pre>
+</font>
+We get the
+location of our figure <img src="images/tag_1.gif" height=13 width=24 align=CENTER>,
+use this to provide a new <CODE>Rectangle</CODE> constraint object <img src="images/tag_2.gif" height=13 width=24 align=CENTER>.
+By setting the width and height to <B>-1</B>, we ensure that the preferred width and height are calculated automatically.
+We then pass on the constraint to the parent <CODE>EditPart</CODE>'s layout manager <img src="images/tag_3.gif" height=13 width=24 align=CENTER>.
+<p>
+That's all there is to it.
+
+
+
+
+
+But how do we know that the preferred size calculation for the
+<CODE>TableFigure</CODE> or <CODE>ColumnFigure</CODE>
+won't be using some stale cached value?
+If you're interested in the answers to questions like this, read the
+sidebar below.
+</p>
+<table border="1" cellpadding="4" width="90%" bgcolor="FFFFCC"><tr>
+ <td bgcolor="0080c0"><font size="+1" color="FFFFCC"><b>Sidebar: Invalidating and Updating Figures</b></font> </td>
+ </tr>
+<tr><td>
+<p>
+How does GEF know when to rearrange and resize figures, and which parts of the screen to repaint?
+The key is in the methods in the <CODE>IFigure</CODE> interface and in the behavior of the <B>update manager</B>:
+
+<ul>
+ <li>
+ <p>
+ <CODE>invalidate()</CODE>: each <CODE>Figure</CODE> instance has a <B>valid</B>
+ flag which can be set to <CODE>true</CODE> or <CODE>false</CODE>.
+ When <CODE>invalidate()</CODE> is called:
+ <ol>
+ <li>the valid flag for the figure is set to false (the figure becomes invalid)
+ </li>
+ <li><CODE>invalidate()</CODE> is called on the <CODE>Figure</CODE>'s layout manager.
+ Here, any cached preferred size information that the layout manager holds for the figure is thrown away
+ <br>
+ <br>
+ </li>
+ </ol>
+ The importance of the invalid state will become more clear when we discuss <CODE>validate()</CODE>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <CODE>revalidate()</CODE>: this method is used to <CODE>invalidate()</CODE> a figure and its parent chain.
+ When called on a figure, this figure invalidates itself and then
+ calls its parent's <CODE>revalidate()</CODE> method.
+ The hierarchy's root figure (one with no parent) is finally placed on the update manager's queue of
+ <B>invalid root figures</B>,
+ that is, figures that need to be validated.
+ </p>
+ <p>
+ <CODE>revalidate()</CODE> is called automatically when changes to figures occur which are likely to affect the bounds of
+ parent figures.
+ Its role can be clearly seen in its usages in the <CODE>Figure</CODE> and <CODE>Label</CODE> classes draw2d package, shown below:
+<p>
+<img src="images/revalidate-s.JPG" height=274 width=259 align=CENTER>
+</p>
+<p>
+ In our example of adding a column label to a table, <CODE>revalidate()</CODE> is automatically called when the new column label is added to the
+ <CODE>ColumnsFigure</CODE> instance using the <CODE>IFigure.addFigure(IFigure, Object, int)</CODE> method.
+ This is why correct resizing of the table occurs without having to invalidate any figures in our
+ example's code.
+ </p>
+ <p>
+<p>
+<img src="images/tip.gif" width="62" height="13"> If no method is called which itself automatically invokes <CODE>revalidate()</CODE>,
+you may need to invoke this method yourself in your application code to correctly update the display.
+</p>
+ </p>
+ </li>
+ <li>
+ <p>
+ <CODE>repaint()</CODE>: in the same way that <CODE>revalidate()</CODE> queues a figure with the update manager for validating,
+ this method queues the figure's bounds as a <I>dirty region</I> for repainting.
+ Like <CODE>revalidate()</CODE>, this method is automatically called in many places in draw2d, such as when the size of a figure changes.
+ You are most likely to need to call this method in your application code if implementing custom subclasses of <CODE>Figure</CODE>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <CODE>validate()</CODE>: this finishes the job that <CODE>revalidate()</CODE> started.
+ The update manager calls <CODE>validate()</CODE> on each of the invalid root figures on the queue.
+ During the <CODE>validate()</CODE> execution the following happens:
+ <ol>
+ <li>the figure's valid flag is set back to true</li>
+ <li>layout takes place - if the figure has a layout manager
+ then its <CODE>layout()</CODE>
+ method is called
+ </li>
+ <li>
+ the figure then validates each of its invalid children
+ </li>
+ <br>
+ </ol>
+ The value of <CODE>revalidate()</CODE> is in helping to ensure that
+ only figures that <I>need</I> to participate in the validate and layout process
+ can be correctly flagged as invalid before this process begins.
+ </p>
+ <p>
+ After validating its invalid root figures, the update manager will repaint the enclosing rectangle for regions marked as <I>dirty</I>
+ via the <CODE>repaint()</CODE> method.
+ </p>
+ </li>
+</ul>
+</p>
+</td></tr></table>
+
+<h2>Conclusion</h2>
+<p>
+We've covered quite a lot of ground in this article.
+Most significantly, we've talked about how you can use the
+basic building blocks of a GEF application to easily build an application which adheres to a clean MVC design.
+With the exception of the direct editing functionality, most
+of the other types of editing operations work in a very similar way to the simple column adding example presented.
+Of course, all of the building blocks need to be put together in the
+context of an Eclipse editor. Space limitations preclude any discussion of these
+topics, but interested readers can peruse the source code, as well as that of the official GEF examples,
+to see how this can be done.
+</p>
+<p>
+For more information on GEF, look at the Eclipse platform documentation,
+available via Eclipse online help if you download and install the GEF SDK.
+<a href="http://www-106.ibm.com/developerworks/opensource/library/os-gef/" target="_blank">How to Get Started with the GEF</a>
+ gives a good introduction to GEF basics. <a href="../Article-GEF-Draw2d/GEF-Draw2d.html">Display a UML Diagram using Draw2D</a>
+ is a good starting point for those unfamiliar with Eclipse draw2d. <a href="http://publib-b.boulder.ibm.com/Redbooks.nsf/RedbookAbstracts/sg246302.html?Open" target="_blank">
+ Eclipse Development using the Graphical Editing Framework and the Eclipse Modeling Framework</a>
+ is an IBM Redbook providing more detailed coverage of GEF and EMF.
+ You will also need to install EMF to get the Redbook examples to work.
+</p>
+<h2>Acknowledgements</h2>
+<p>
+Thanks to Randy Hudson and Jim des Rivières for their thorough and careful reviews,
+which have been very helpful in improving both the technical accuracy and readability of
+this article.
+<h2>Source Code</h2>
+<p> To run the example or view the source code for this article, download and
+ unzip <a href="schemaeditor.zip">schemaeditor.zip</a> into your <i>eclipse/</i>
+ subdirectory. Note that you will need Eclipse 3.0 or later to run the examples.</p>
+
+</body>
+</html>
diff --git a/Article-GEF-editor/images/Idea.jpg b/Article-GEF-editor/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-GEF-editor/images/Idea.jpg
Binary files differ
diff --git a/Article-GEF-editor/images/editor.JPG b/Article-GEF-editor/images/editor.JPG
new file mode 100644
index 0000000..d6785a4
--- /dev/null
+++ b/Article-GEF-editor/images/editor.JPG
Binary files differ
diff --git a/Article-GEF-editor/images/layout.gif b/Article-GEF-editor/images/layout.gif
new file mode 100644
index 0000000..2f7185f
--- /dev/null
+++ b/Article-GEF-editor/images/layout.gif
Binary files differ
diff --git a/Article-GEF-editor/images/revalidate-s.JPG b/Article-GEF-editor/images/revalidate-s.JPG
new file mode 100644
index 0000000..9fe9515
--- /dev/null
+++ b/Article-GEF-editor/images/revalidate-s.JPG
Binary files differ
diff --git a/Article-GEF-editor/images/revalidate.JPG b/Article-GEF-editor/images/revalidate.JPG
new file mode 100644
index 0000000..bbf3de4
--- /dev/null
+++ b/Article-GEF-editor/images/revalidate.JPG
Binary files differ
diff --git a/Article-GEF-editor/images/tag_1.gif b/Article-GEF-editor/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-GEF-editor/images/tag_1.gif
Binary files differ
diff --git a/Article-GEF-editor/images/tag_2.gif b/Article-GEF-editor/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-GEF-editor/images/tag_2.gif
Binary files differ
diff --git a/Article-GEF-editor/images/tag_3.gif b/Article-GEF-editor/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-GEF-editor/images/tag_3.gif
Binary files differ
diff --git a/Article-GEF-editor/images/tag_4.gif b/Article-GEF-editor/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-GEF-editor/images/tag_4.gif
Binary files differ
diff --git a/Article-GEF-editor/images/tag_5.gif b/Article-GEF-editor/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-GEF-editor/images/tag_5.gif
Binary files differ
diff --git a/Article-GEF-editor/images/tag_6.gif b/Article-GEF-editor/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-GEF-editor/images/tag_6.gif
Binary files differ
diff --git a/Article-GEF-editor/images/tag_7.gif b/Article-GEF-editor/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-GEF-editor/images/tag_7.gif
Binary files differ
diff --git a/Article-GEF-editor/images/tip.gif b/Article-GEF-editor/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-GEF-editor/images/tip.gif
Binary files differ
diff --git a/Article-GEF-editor/images/tryit.gif b/Article-GEF-editor/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-GEF-editor/images/tryit.gif
Binary files differ
diff --git a/Article-GEF-editor/schemaeditor.zip b/Article-GEF-editor/schemaeditor.zip
new file mode 100644
index 0000000..e21b0b7
--- /dev/null
+++ b/Article-GEF-editor/schemaeditor.zip
Binary files differ
diff --git a/Article-Image-Viewer/Image_viewer.html b/Article-Image-Viewer/Image_viewer.html
new file mode 100644
index 0000000..3a9d9fd
--- /dev/null
+++ b/Article-Image-Viewer/Image_viewer.html
@@ -0,0 +1,831 @@
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<title>A basic image viewer</title>
+<link rel="stylesheet" href="../default_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080">
+<div align="right">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; Copyright
+ &copy; 2004 Chengdong Li
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">A Basic Image Viewer</h1>
+
+<blockquote>
+<b>Summary</b>
+
+<br>
+This article shows how to extend SWT <code>Canvas</code> to implement a mini image viewer plug-in using Java2D
+transforms. The
+extended image canvas can be used to scroll and zoom large images, and can also
+be extended to apply other transforms. The implementation is based on SWT and
+the non-UI portions of AWT. The plug-in has been tested on Windows, Linux GTK, and Mac
+OS X Carbon with Eclipse 2.1 or better.
+<p><b> By Chengdong
+Li (</b><a href="mailto:cdli@ccs.uky.edu">cdli@ccs.uky.edu</a><b>)
+Research in Computing for Humanities, University of Kentucky <br>
+</b>
+March 15, 2004</p>
+</blockquote>
+
+<hr width="100%">
+<h2>Contents</h2>
+<ul>
+ <li><a href="#Introduction">Introduction</a></li>
+ <li><a href="#Overview">Classes overview</a></li>
+ <li><a href="#Implement_Canvas">Canvas implementation</a>
+ <ul>
+ <li><a href="#Loading_image">Loading images</a></li>
+ <li><a href="#Extending_Canvas">Extending org.eclipse.swt.widgets.Canvas</a></li>
+ <li><a href="#Rendering_image">Rendering images</a></li>
+ <li><a href="#Transformation">Transformations</a></li>
+ <li><a href="#Synchronize_scrollbar">Scrollbar synchronization</a></li>
+ </ul>
+ </li>
+ <li><a href="#Rotating">Rotation</a></li>
+ <li><a href="#Plug-in_Implementation">Plug-in implementation</a>
+ <ul>
+ <li><a href="#Create_view_plug-in">Create view plug-in</a></li>
+ <li><a href="#Add_viewActions_extension">Add viewActions extension</a></li>
+ </ul>
+ </li>
+ <li><a href="#Summary">Summary</a></li>
+ <li><a href="#Acknowledge">Acknowledgements</a></li>
+ <li><a href="#Reference">References</a></li>
+</ul>
+<h2>Conventions &amp; Terms</h2>
+<p>The following typographic conventions are used in this article:</p>
+<p><i>Italic</i>:<br>
+&nbsp;&nbsp;&nbsp; Used for references to articles.</p>
+<code>Courier New:</code><br>
+&nbsp;&nbsp;&nbsp; Used for code or variable names.
+<p>The following terms are used in this article:</p>
+<p><b>client area<br>
+</b>&nbsp;&nbsp;&nbsp; The
+drawable area of canvas. Also called the <b>paint area</b> or <b>canvas domain</b>.<br>
+<b>source image</b><br>
+&nbsp;&nbsp;&nbsp; The image constructed directly from
+the original image data with the same width and height. Unlike image data, it is
+device dependent. It is the <code> sourceImage</code> in source
+code. Also called the <b>original image</b> or <b>image domain</b>.</p>
+<h2><a name="Introduction">Introduction</a></h2>
+<p> The goal of this article is to show you how to implement an image viewer with
+scrolling and zooming operations using affine transforms.
+If you are new to graphics in SWT, please read Joe Winchester's article <i><a href="http://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html">Taking a look at SWT Images</a></i>.
+A screenshot of the image viewer is shown in Figure 1:</p>
+<p><img border="0" src="images/screen_shot.jpg" width="359" height="318"><br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Figure 1 - Image viewer</p>
+<p>The implementation here is different from the implementation of the Image Analyzer example
+that comes with Eclipse. This implementation uses affine transforms for scrolling and zooming.</p>
+<p>The advantages of this implementation are :</p>
+<ul>
+ <li>it offers unlimited zoom scale</li>
+ <li>it works well for large images</li>
+</ul>
+<p>In the following sections, we will first review the structure of the package
+and relationship of classes,
+then we will discuss how the image canvas works and how to implement a scrollable
+and zoom-able image canvas - <code> SWTImageCanvas</code>. We will use
+affine transforms to selectively render images and to generally simplify the implementation. After that, we will show
+briefly how to use the local toolbar to facilitate image&nbsp; manipulation.</p>
+<p>For the detailed steps on how to implement a view, Dave Springgay's
+ article: <i><a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html">Creating
+an Eclipse View</a></i> is the most helpful one.</p>
+<p>You can compare this implementation with the Image Analyzer example by running both of
+them:</p>
+<ul>
+ <li>To run the example for this article unzip <a href="imageviewer.zip">
+imageviewer.zip</a> into your <i>eclipse/plugins/ </i>subdirectory and restart
+ Eclipse. To open the image
+viewer view, choose Window -&gt; Show View -&gt; Other -&gt; Sample Category -&gt;
+Image Viewer. The source plug-in project is imageviewersrc.zip which is included inside the <a href="imageviewer.zip">
+imageviewer.zip</a>.</li>
+ <li>To run the Image Analyzer example that comes with Eclipse, download the Example
+Plug-ins from <a href="http://www.eclipse.org/downloads/index.php">Eclipse.org</a>,
+and unzip to the <i>eclipse/plugins/</i> subdirectory and restart Eclipse. Then choose Window -&gt; Show
+View -&gt; Other -&gt; SWT Example Launcher -&gt; Standalone -&gt; Image
+Analyzer.</li>
+</ul>
+<p>To compile and run the image viewer from source code, unzip the imageviewersrc.zip
+file (inside <a href="imageviewer.zip">
+imageviewer.zip</a>), then import the existing project into the workspace, update the
+class path, compile, and run.</p>
+<h2><a name="Overview">Classes Overview</a></h2>
+<p>The following diagram (Figure 2) shows all classes in this demo plug-in. The <code> SWTImageCanvas</code> is a subclass of
+<code>org.eclipse.swt.widgets.Canvas</code>;
+it implements image loading, rendering, scrolling, and zooming. The <code> ImageView</code> class is a subclass of
+<code>
+org.eclipse.ui.part.ViewPart</code>; it has an <code> SWTImageCanvas</code> instance. The helper class
+<code>SWT2Dutil</code> holds utility
+functions. <code> PushActionDelegate</code> implements <code>
+org.eclipse.ui.IViewActionDelegate</code>; it delegates the toolbar button actions,
+and has an <code>ImageView</code> instance. The <code>
+ImageViewerPlugin</code> extends <code> org.eclipse.ui.plugin.AbstractUIPlugin</code>
+(this class is PDE-generated).</p>
+<p><img border="0" src="images/all_classes.jpg" width="640" height="308"><br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Figure 2 - Class diagram ( The classes without package prefix are implemented
+in our approach. )</p>
+<p>A plug-in manifest file plugin.xml defines the runtime requirements and contributions (view and
+viewActions extensions) to
+Eclipse. Eclipse will create toolbar buttons
+for <code> ImageView</code> and delegate toolbar actions via <code> PushActionDelegate</code>.</p>
+<h2><a name="Implement_Canvas">Canvas implementation</a></h2>
+<p> <code> SWTImageCanvas</code> handles image loading,
+painting, scrolling, and
+zooming. It saves a copy of the original SWT image (the <code> sourceImage</code>)
+in memory, and then translates and scales
+the image using <code>java.awt.geom.AffineTransform</code>. The
+rendering and transformation are applied only to the portion of the image
+visible on the
+screen, allowing it to operate on images of any size with good performance. The <code> AffineTransform</code>
+ gets applied changes as the user scrolls the window and pushes the toolbar buttons.</p>
+<h4><a name="Loading_image">Loading images</a>&nbsp;</h4>
+<p>First, let's have a look at how to load an image into memory. There are several ways to load an
+image:</p>
+<ul>
+ <li> load an image from the local file system.</li>
+ <li> load an image from the workspace.&nbsp;</li>
+ <li>load an image from a website.</li>
+</ul>
+<p>In this simple implementation, we only allow the user to choose an image from
+the local file
+system. To improve this, you could contribute to the <code>org.eclipse.ui.popupMenus</code>
+of the Navigator view for image files; that way, whenever an image file is selected, the menu item will be available and
+the user can choose to load the image
+from the workspace (you need add <code>nameFilters</code>, and you may also need to use workspace
+API). To see how to load an image from a URL, please refer to
+the Image Analyzer of SWT
+examples.</p>
+<p>The image loading process is as following (Figure 3):</p>
+<p align="left"><img border="0" src="images/open_activity.jpg" width="402" height="255"><br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Figure 3 - Image-loading diagram</p>
+<p>Now let's take a look at the code for loading images.&nbsp;</p>
+<p>SWT
+provides <code> ImageLoader</code> to load an image into memory.
+Image loading is done by using the <code>Image(Display,String)</code> constructor. To facilitate image loading, we provides a
+dialog to locate all image files supported by SWT <code> ImageLoader</code>.&nbsp;</p>
+<pre><b>public</b> <b>void</b> onFileOpen(){
+ FileDialog fileChooser = <b>new</b> FileDialog(getShell(), SWT.OPEN);
+ fileChooser.setText(&quot;Open image file&quot;);
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> fileChooser.setFilterPath(currentDir);
+ fileChooser.setFilterExtensions(
+ <b>new</b> String[] { &quot;*.gif; *.jpg; *.png; *.ico; *.bmp&quot; });
+ fileChooser.setFilterNames{
+ <b>new</b> String[] { &quot;SWT image&quot; + &quot; (gif, jpeg, png, ico, bmp)&quot; });
+ String filename = fileChooser.open();
+ if (filename != <b>null</b>){
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> loadImage(filename);
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> currentDir = fileChooser.getFilterPath();
+ }
+}<b>
+public</b> Image loadImage(String filename) {
+ <b>if</b>(sourceImage!=<b>null</b> &amp;&amp; !sourceImage.isDisposed()){
+ sourceImage.dispose();
+ sourceImage=<b>null</b>;
+ }
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> sourceImage= <b>new</b> Image(getDisplay(),filename);
+<img src="images/tag_5.gif" height=13 width=24 align=CENTER> showOriginal();
+ <b>return</b> sourceImage;
+}</pre>
+<p>We use <code>currentDir</code> in <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+ and <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+to remember the directory for the file open dialog, so that the user can later open other files
+in the same directory.</p>
+<p>The <code>loadImage</code> method (shown above) in <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+ disposes the old <code> sourceImage</code> and creates a new <code>sourceImage</code>,
+then it calls the <code>showOriginal()</code> to notify the canvas to
+paint new image. If loading fails, the canvas will clear the painting area
+and disable the scrollbar. Notice that we cannot see <code>ImageLoader</code>
+directly in the code above, however, when we call <code>Image(Display,
+String)</code> in
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER>, Eclipse will call
+<code>ImageLoader.load()</code> to
+load the image into memory. <img src="images/tag_5.gif" height=13 width=24 align=CENTER>
+is used to show the image at its original size; we will
+discuss this in more detail <a href="#func_showOriginal">later</a>.</p>
+<p><img src="images/tip.gif" width="62" height="13"> In fact, the above two functions
+could be merged into one method. The reason why we separate them is we
+may invoke them separately from other functions; for example, we may get the image file
+name from the database, then we can reload the image by only calling <code>loadImage()</code>.</p>
+<h4><a name="Extending_Canvas">Extending org.eclipse.swt.widgets.Canvas</a></h4>
+<p>Now, let's see how to create a canvas to render the image and do some
+transformations.</p>
+<p>The <code>org.eclipse.swt.widgets.Canvas</code>
+ is suitable to be extended for rendering images. <code>SWTImageCanvas</code>
+extends it and adds scrollbars. This is done by setting the <code>SWT.V_SCROLL</code>
+and <code>SWT.H_SCROLL</code> style bits at the <code>Canvas</code>
+constructor:</p>
+<pre><b>public</b> SWTImageCanvas(<b>final</b> Composite parent, <b>int</b> style) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b>super</b>(parent,style|SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL
+ |SWT.NO_BACKGROUND);
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> addControlListener(<b>new</b> ControlAdapter() { <font color="#3f7f5f">/* resize listener */</font>
+ <b>public</b> <b>void</b> controlResized(ControlEvent event) {
+ syncScrollBars();
+ }
+ });
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> addPaintListener(<b>new</b> PaintListener() { <font color="#3f7f5f">/* paint listener */</font>
+ <b>public</b> <b>void</b> paintControl(PaintEvent event) {
+ paint(event.gc);
+ }
+ });
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> initScrollBars();
+}<b>
+private</b> <b>void</b> initScrollBars() {
+ ScrollBar horizontal = getHorizontalBar();
+ horizontal.setEnabled(<b>false</b>);
+ horizontal.addSelectionListener(<b>new</b> SelectionAdapter() {<b>
+ public</b> <b>void</b> widgetSelected(SelectionEvent event) {
+ scrollHorizontally((ScrollBar) event.widget);
+ }
+ });
+ ScrollBar vertical = getVerticalBar();
+ vertical.setEnabled(<b>false</b>);
+ vertical.addSelectionListener(<b>new</b> SelectionAdapter() {<b>
+ public</b> <b>void</b> widgetSelected(SelectionEvent event) {
+ scrollVertically((ScrollBar) event.widget);
+ }
+ });
+}</pre>
+<p><img src="images/tip.gif" width="62" height="13"> In order to speed up the
+rendering process and reduce flicker, we set the style to <code>SWT.NO_BACKGROUND</code>
+in <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+(and later we use <a href="#double-buffering">double buffering</a> to render) so that the background (client area) won't be cleared.
+The new image will be
+overlapped on the background. We need to fill the gaps between the new image and
+the background when the new image does not fully cover the background.</p>
+<p><img src="images/tag_2.gif" height=13 width=24 align=CENTER> registers a
+resize listener to synchronize the
+size and position of the scrollbar thumb to the image zoom scale and
+translation; <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+registers a paint listener (here it does <code>paint(GC gc)</code>)
+to render the image whenever the <code>PaintEvent</code>
+is fired; <img src="images/tag_4.gif" height=13 width=24 align=CENTER>
+registers the <code>SelectionListener</code>
+for each scrollbar,
+the <code>SelectionListener</code>
+ will notify <code>SWTImageCanvas</code> to scroll and zoom
+the image based on the current selection of scrollbars; another function of the <code>SelectionListener</code>
+ is to enable or disable the scrollbar based on the image size and zoom scale.&nbsp;</p>
+<h4><a name="Rendering_image">Rendering images</a></h4>
+<p>Whenever the SWT<code> PaintEvent</code> is fired, the paint listener (<code>paint(GC
+gc)</code>)
+will be called to paint the
+damaged area. In this article, we simply paint the whole client area of the
+canvas (see Figure 4).
+Since we support scrolling and zooming, we need to figure out which part of
+the original image should be drawn to which part of the client area. The painting process is as
+following:</p>
+<ol>
+ <li>Find a rectangle <code>imageRect</code> inside the source
+ image (<b>image domain</b>); the image inside this rectangle will be drawn to the client area of canvas (<b>canvas
+ domain</b>).</li>
+ <li>Map the <code>imageRect</code> to the client area and
+ get <code>destRect</code>.</li>
+ <li>Draw the source image within <code>imageRect</code> to <code>destRect</code>
+ (scaling it if the sizes are different).</li>
+ <li>Fill the gaps (shown as blue and green bands in the picture below) if
+ necessary.</li>
+</ol>
+<p><a name="Rendering_scenario_figure"></a><img border="0" src="images/render_model.jpg" width="656" height="426">&nbsp;&nbsp;&nbsp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Figure 4 - Rendering scenarios</p>
+<p>1) and 2) can be done based on <code>AffineTransform</code>, which we will discuss next.&nbsp;</p>
+<p>3) draws a part of the source image to the client area using GC's <code>drawImage</code>:<br>
+<code> &nbsp;&nbsp;&nbsp; drawImage
+(Image&nbsp;image, int&nbsp;srcX, int&nbsp;srcY, int&nbsp;srcWidth, int&nbsp;srcHeight,
+int&nbsp;destX, int&nbsp;destY, int&nbsp;destWidth, int&nbsp;destHeight)</code></p>
+<p>which copies a rectangular area from the source image into a destination rectangular
+area and automatically scale the
+image if the source rectangular area has a different size from the destination
+rectangular area.</p>
+<p>If we draw the image directly on the screen, we need to calculate the gaps in
+4) and fill them. Here we make use of <a href="#double-buffering"> double
+buffering</a>, so the gaps will be filled
+automatically.</p>
+<p><img src="images/tip.gif" width="62" height="13">We use the following
+approach to render the image: We save only the source image. When the canvas needs to update the visible area,
+it copies the corresponding image area from the source image to the destination area on
+the canvas. This approach can
+offer a very large zoom scale and save the memory, since it does not
+need to save the whole big zoomed image. The drawing process is also speeded up.
+If the size of canvas is very huge, we could divide the canvas into several small
+grids, and render each grid using our approach; so this approach is to some extent scalable.</p>
+<p><img border="0" src="images/note.gif" width="62" height="13">The Image Analyzer example
+that comes with Eclipse draws the whole
+zoomed image, and scrolls the zoomed image (which is saved by system) to the right place based on the
+scrollbar positions. This implementation works well for small images, or when the zoom
+scale is not
+large. However,
+for large-sized images and zoom scale greater than 1, the scrolling becomes very
+slow since it has to operate on a very large zoomed image. This can be shown in
+Image Analyzer.</p>
+<p>Now let's look at the code used to find out the corresponding rectangles in the
+source image and the client area:</p>
+<pre><b>private</b> <b>void</b> paint(GC gc) {
+<b>1</b> Rectangle clientRect = getClientArea(); <font color="#3f7f5f">/* canvas' painting area */</font>
+<b>2</b> <b>if</b> (sourceImage != <b>null</b>) {
+<b>3</b> Rectangle imageRect=SWT2Dutil.inverseTransformRect(transform, clientRect);
+<b>4</b>
+<b>5</b> <b>int</b> gap = 2; <font color="#3f7f5f">/* find a better start point to render. */</font>
+<b>6</b> imageRect.x -= gap; imageRect.y -= gap;
+<b>7</b> imageRect.width += 2 * gap; imageRect.height += 2 * gap;
+<b>8</b>
+<b>9 </b>Rectangle imageBound=sourceImage.getBounds();
+<b>10</b> imageRect = imageRect.intersection(imageBound);
+<b>11</b> Rectangle destRect = SWT2Dutil.<a href="#transformRect">transformRect</a>(transform, imageRect);
+<b>12</b>
+<b>13</b> <b>if</b> (screenImage != <b>null</b>){screenImage.dispose();}
+<b>14</b> screenImage = <b>new</b> Image( getDisplay(),clientRect.width, clientRect.height);
+<b>15</b> GC newGC = <b>new</b> GC(screenImage);
+<b>16</b> newGC.setClipping(clientRect);
+<b>17</b> newGC.drawImage( sourceImage,
+<b>18</b> imageRect.x,
+<b>19</b> imageRect.y,
+<b>20</b> imageRect.width,
+<b>21</b> imageRect.height,
+<b>22</b> destRect.x,
+<b>23</b> destRect.y,
+<b>24</b> destRect.width,
+<b>25</b> destRect.height);<b>
+26 </b>newGC.dispose();<b>
+27
+28</b> gc.drawImage(screenImage, 0, 0);<b>
+29</b> } <b>else</b> {
+<b>30</b> gc.setClipping(clientRect);
+<b>31</b> gc.fillRectangle(clientRect);
+<b>32</b> initScrollBars();
+<b>33</b> }
+}</pre>
+<p>Line 3 to line 10 are used to find a rectangle (<code>imageRect</code>) in the source image, the source image inside
+this rectangle will be drawn to the canvas. This is done by inverse
+transforming the canvas's client area to the image domain and intersecting it with the bounds of image. The
+<code>imageRect</code>
+of line 10 is the exact rectangle we need.
+Once we have got <code>imageRect</code>,
+we transform <code>imageRect</code> back to the canvas domain in
+line 11 and get a rectangle <code>destRect</code> inside
+the client area. The source image inside the <code>imageRect</code> will be
+drawn to the client area inside <code>destRect</code>.</p>
+<p>After we get the <code>imageRect</code> of the source
+image and the corresponding <code>destRect</code> of the
+client area, we can draw just the part of image to be shown, and draw it in the right place.
+For convenience, here we use <a name="double-buffering"> double buffering</a> to ease the drawing process:
+we first create a <code>screenImage</code> and draw image to
+the <code>screenImage</code>, then copy the <code>screenImage</code>
+to the canvas.</p>
+<p>Line 30 to line 32 are used to clear the canvas and reset the scrollbar whenever the
+source image is set to null.</p>
+<p><img src="images/tip.gif" width="62" height="13">Line 5 to line 7 are used to
+find a better point to start drawing the rectangular image, since the transform may compress or
+enlarge the size of each pixel. To make the scrolling and zooming
+smoothly, we always draw the image from the beginning of a pixel. This also guarantee
+that the image always fills the canvas if it is larger than the canvas.</p>
+<p>The flowchart of rendering is as following (Figure 5):</p>
+<p><img border="0" src="images/render_flowchart.jpg" width="677" height="209"><br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Figure 5 - Rendering flowchart</p>
+<p>In the code above, we use <code>inverseTransformRect()</code>
+in line 3 and <code>transformRect()</code> in line 11 for
+transforming rectangles between different domain. We will discuss them in detail in
+the next section.</p>
+<h4><a name="Transformation">Transformations</a></h4>
+<p><img border="0" src="images/note.gif" width="62" height="13"> When we say scrolling in this
+section, we mean scrolling the image, not the scrollbar thumb (which actually moves
+in the opposite direction).</p>
+<p>Our primary goal is to develop a canvas with scrolling and zooming functions. To
+do
+that, we must solve the following problems:</p>
+<ul>
+ <li>How to save the scrolling and zooming parameters.</li>
+ <li>How to change the scrolling and zooming parameters.</li>
+ <li>How the scrolling and zooming parameters control the image rendering.</li>
+</ul>
+<p>Scrolling and zooming entails two transformations: translation and scaling (see
+Figure 6).
+Translation is used to change the horizontal and
+vertical position of the image; scrolling involves translating the image in the
+horizontal or vertical directions. Scaling is used to change the size of image;
+scale with a rate
+greater than 1 to zoom in; scale with a rate less than 1 to zoom out.</p>
+<p><img border="0" src="images/transform.jpg" width="333" height="145"><br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Figure 6 - Translation and scaling</p>
+<p><code>SWTImageCanvas</code> uses an <code> AffineTransform</code> to
+save the parameters of both the translation and
+the scaling. In this implementation, only translation and scaling are
+used. The basic idea of <code> AffineTransform</code> is to represent the transform as a matrix and
+then merge several transforms into one by matrix multiplication. For
+example, a scaling <b>S</b> followed by a translation <b>T </b>can be merged into
+a transform like: <b>T</b>*<b>S</b>. By merging first and then
+transforming, we can reduce times for transforming
+and speed up the process.</p>
+<p><code>SWTImageCanvas</code> has an <code>AffineTransform</code>
+instance transform:</p>
+<pre><b> private</b> AffineTransform transform;</pre>
+<p><code>AffineTransform</code> provides
+methods to access the translation and scaling parameters of an affine
+transform:</p>
+<pre> <b>public double</b> getTranslateX();
+ <b>public double</b> getTranslateY();
+ <b>public double</b> getScaleX();
+ <b>public double</b> getScaleY();</pre>
+<p>To change the <code>AffineTransform</code>, we can either reconstruct an <code>AffineTransform</code>
+by merging itself
+and another transform, or start from scratch. <code>AffineTransform</code> provides
+<code>preConcatenate()</code> and <code>concatenate()</code>
+ methods, which can merge two <code>AffineTransform</code>s
+into one. Using these two methods, each time the user scrolls or
+zooms the image, we can create a new transform based on the changes (scrolling
+changes translation and zooming changes scaling) and the transform itself. The
+merge operation is matrix multiplication. Since 2D <code>AffineTransform</code> uses&nbsp;a 3x3 matrix, so the computation is very cheap.</p>
+<p> For
+example, when the user scrolls the image by <b>tx</b> in the x direction and<b>
+ty </b> in the y
+direction:</p>
+<pre>&nbsp;&nbsp;&nbsp; newTransform = oldTransform.preconcatenate(AffineTransform.getTranslateInstance(<b>tx</b>,<b>ty</b>));&nbsp;</pre>
+<p>To construct a scaling or translation transform from scratch:</p>
+<pre> <b>static</b> AffineTransform getScaleInstance(sx, sy);
+ <b>static</b> AffineTransform getTranslateInstance(tx,ty);</pre>
+<p> Once you have an <code>AffineTransform</code>, the transformation can be easily done.
+To transform a point:</p>
+<pre>&nbsp;&nbsp;&nbsp; <b>public static</b> Point transformPoint(AffineTransform af, Point pt) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Point2D src = <b>new</b> Point2D.Float(pt.x, pt.y);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Point2D dest= af.transform(src, <b>null</b>);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Point point=<b>new</b> Point((int)Math.floor(dest.getX()),(int)Math.floor(dest.getY()));
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>return</b> point;
+&nbsp;&nbsp;&nbsp; }</pre>
+<p>To get the inverse transform of a point:</p>
+<pre> <b>static</b> Point2D inverseTransform(Point2D&nbsp;ptSrc, Point2D&nbsp;ptDst);</pre>
+<p>Since we use only translation and scaling in our implementation,
+transforming a rectangle can be done by first transforming the top-left point,
+and then scaling the width and height. To do that, we need to convert an arbitrary
+rectangle to a rectangle with positive width and length. The following code
+shows how to transform an arbitrary rectangle using <code>AffineTransform</code>
+(the inverse transform is almost the same):</p>
+<pre><b>1</b>&nbsp;&nbsp; <b>public static</b> Rectangle <a name="transformRect">transformRect</a>(AffineTransform af, Rectangle src){
+<b>2</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Rectangle dest= <b>new</b> Rectangle(0,0,0,0);
+<b>3</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src=absRect(src);
+<b>4</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Point p1=<b>new</b> Point(src.x,src.y);
+<b>5</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p1=transformPoint(af,p1);
+<b>6</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dest.x=p1.x; dest.y=p1.y;
+<b>7</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dest.width=(<b>int</b>)(src.width*af.getScaleX());
+<b>8</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dest.height=(<b>int</b>)(src.height*af.getScaleY());
+<b>9</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>return</b> dest;
+<b>10</b> &nbsp;}</pre>
+<p>The <code>absRect()</code> function in line 3 is used to
+convert an arbitrary rectangle to a rectangle with positive width and height.</p>
+<p>For more detail about <code>AffineTransform</code>, you can
+read <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/geom/AffineTransform.html"> the
+Java API document from SUN website</a>.</p>
+<p><img src="images/tip.gif" width="62" height="13"> <code>AffineTransform</code>
+also supports shear and rotation. In this
+article, we only need translation and scaling. <code> AffineTransform</code> is widely used in the AWT's
+image packages, and it has no relation with UI event loop, so it can be used in
+SWT. (Even if <code>AffineTransform</code> were unavailable,&nbsp; we could easily replace or rewrite it since we only use the translation and
+scaling).</p>
+<p>We have seen how we save the scrolling and scaling parameters in <code>AffineTransform</code>,
+and how we can change them. But how do they control the image rendering?</p>
+<p><img border="0" src="images/scroll_zoom_activity.jpg" width="540" height="149"><br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Figure 7 - Scrolling and zooming diagram</p>
+<p>The basic idea is shown in Figure 7. When the user interacts with GUI
+(scrollbars and toolbar buttons), her/his action will be caught by Eclipse, Eclipse will
+invoke the listeners (for scrollbars) or delegates (for toolbar buttons) to change the parameters in
+the transform,
+then the canvas will update the status of scrollbars based on the transform,
+and finally it will notify itself to repaint the image. The painter
+will consider the updated transform when it
+repaints the image. For
+example, it will use transform to find out the corresponding rectangle in the source
+image to the visible
+area on the canvas, and copy
+the source image inside the rectangle to the canvas with scaling.</p>
+<p>Let's take a look at some methods which use <code>AffineTransform</code>
+to translate and zoom images.</p>
+<p>First let's see how to show an image at its original size:</p>
+<pre><b><a name="func_showOriginal"></a>public</b> <b>void</b> showOriginal() {<b>
+</b><img src="images/tag_1.gif" height=13 width=24 align=CENTER><b> </b>transform=<b>new</b> AffineTransform();
+ syncScrollBars();
+}</pre>
+<p>Here we first change transform in <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+ (defaults to a scaling rate of 1, and no translation), and then call <code>syncScrollBars()</code> to update the
+scrollbar and repaint the canvas. It's that simple.</p>
+<p>Now let's try another one - zooming. When we zoom the image, we will zoom it around the center of
+the client
+area (centered zooming). The procedure for centered zooming is:</p>
+<ol>
+ <li>Find the center of client area: (x,y).</li>
+ <li>Translate the image by (-x,-y), so that (x,y) is at the origin.</li>
+ <li>Scale the image.</li>
+ <li>Translate the image by (x,y).</li>
+</ol>
+<p>The <a href="#func_syncScrollBars">syncScrollBars</a>()
+ (see next section) guarantees that the image will be centered in the client
+area if it is smaller than the client area.</p>
+<p>Steps 2-4 can be used to scale images around an arbitrary point (dx,dy).
+Since the same steps will be used by many other methods, we put them in the method
+<code>centerZoom(dx,dy,scale,af)</code>:&nbsp;</p>
+<pre><b>public</b> <b>void</b> centerZoom(<b>double</b> dx,<b>double</b> dy,<b>double</b> scale,AffineTransform af) {
+ af.preConcatenate(AffineTransform.getTranslateInstance(-dx, -dy));
+ af.preConcatenate(AffineTransform.getScaleInstance(scale, scale));
+ af.preConcatenate(AffineTransform.getTranslateInstance(dx, dy));
+ transform=af;
+ syncScrollBars();
+}</pre>
+<p> Now the code for <code>zoomIn</code>
+is:</p>
+<pre><b>public</b> <b>void</b> zoomIn() {
+ <b>if</b> (sourceImage == <b>null</b>) <b>return</b>;
+ Rectangle rect = getClientArea();<b>
+</b> <b>int</b> w = rect.width, h = rect.height;
+ <font color="#3f7f5f">/* zooming center */</font>
+ <b>double</b> dx = ((<b>double</b>) w) / 2;
+ <b>double</b> dy = ((<b>double</b>) h) / 2;
+ centerZoom(dx, dy, ZOOMIN_RATE, transform);
+}</pre>
+<p>Here the (<code>dx</code>,<code>dy</code>) is the zooming center, <code>ZOOMIN_RATE</code>
+is a constant for incremental zooming in. <code>centerZoom()</code> will also call
+<code>syncScrollBars()</code>
+to update the scrollbar and repaint the canvas.</p>
+<h4><a name="Synchronize_scrollbar">Scrollbar synchronization</a></h4>
+<p>Each time user zooms or scrolls the image, the scrollbars need to update
+themselves to synchronize with the state of image. This includes adjusting the position and the size of the
+thumbs,
+enabling or disabling the scrollbars, changing the range of the scrollbars, and
+finally notifying the canvas to repaint the client area. We use <code>syncScrollBars()</code>
+to do this:</p>
+<pre><b><a name="func_syncScrollBars"></a>public</b> <b>void</b> syncScrollBars() {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b>if</b> (sourceImage == <b>null</b>){
+ redraw();
+ <b>return</b>;
+ }
+ AffineTransform af = transform;<b>
+</b> <b>double</b> sx = af.getScaleX(), sy = af.getScaleY();
+ <b>double</b> tx = af.getTranslateX(), ty = af.getTranslateY();
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> <b>if</b> (tx &gt; 0) tx = 0; <b>if</b> (ty &gt; 0) ty = 0;
+
+ ScrollBar horizontal = getHorizontalBar();
+ horizontal.setIncrement((<b>int</b>)(getClientArea().width/100));
+ horizontal.setPageIncrement(getClientArea().width);<b>
+</b> Rectangle imageBound = swtImage.getBounds();<b>
+</b> <b>int</b> cw = getClientArea().width, ch = getClientArea().height;
+ <b>if</b> (imageBound.width * sx &gt; cw) { <font color="#3f7f5f">/* image is wider than client area */</font>
+ horizontal.setMaximum((<b>int</b>) (imageBound.width * sx));
+ horizontal.setEnabled(<b>true</b>);
+ <b>if</b> (((<b>int</b>) - tx) &gt; horizontal.getMaximum()-cw) {
+ tx = -horizontal.getMaximum()+cw;
+ }
+ } <b>else</b> { <font color="#3f7f5f">/* image is narrower than client area */</font>
+ horizontal.setEnabled(<b>false</b>);
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> tx = (cw - imageBound.width * sx) / 2;
+ }
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> horizontal.setSelection((<b>int</b>) (-tx));
+<img src="images/tag_5.gif" height=13 width=24 align=CENTER> horizontal.setThumb((<b>int</b>)(getClientArea().width));
+
+ <font color="#3f7f5f">/* update vertical scrollbar, same as above. */</font>
+ ScrollBar vertical = getVerticalBar();
+ ....
+ <font color="#3f7f5f">/* update transform. */</font>
+<img src="images/tag_6.gif" height=13 width=24 align=CENTER> af = AffineTransform.getScaleInstance(sx, sy);
+ af.preConcatenate(AffineTransform.getTranslateInstance(tx, ty));
+ transform=af;
+
+<img src="images/tag_7.gif" height=13 width=24 align=CENTER> redraw();
+}</pre>
+<p>If there is no image, the paint listener will be
+notified to clear the client area in <img src="images/tag_1.gif" height=13 width=24 align=CENTER>.</p>
+<p>If there is an image to show, we correct the current translation to make sure it's legal (&lt;=0).
+The
+point (<code>tx</code>,<code>ty</code>) in <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+corresponds to the bottom-left corner of the zoomed image (see the right-hand
+image in <a href="#Rendering_scenario_figure">Figure 4</a>), so it's
+reasonable to make it no larger than zero (the bottom-left corner of the canvas
+client area is (0,0)) except if the zoomed image is smaller than the client
+area. In such a situation, we correct the transform in <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+so that it will translate the
+image to the center of client area. We change the selection in <img src="images/tag_4.gif" height=13 width=24 align=CENTER>
+and the thumb size in <img src="images/tag_5.gif" height=13 width=24 align=CENTER>,
+so that the horizontal scrollbar will show the relative position to the whole
+image exactly.
+The other lines between&nbsp;<img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+and <img src="images/tag_5.gif" height=13 width=24 align=CENTER>
+set the GUI parameters for the horizontal scrollbar, you can change them to
+control the scrolling increment. The
+process for the vertical scrollbar is exactly the same, so we don't show
+it here. Lines between
+<img src="images/tag_6.gif" height=13 width=24 align=CENTER>
+and <img src="images/tag_7.gif" height=13 width=24 align=CENTER>
+create a new transform based on the corrected translation and
+the scaling and update the old transform. Finally, line <img src="images/tag_7.gif" height=13 width=24 align=CENTER>
+notifies the canvas to repaint itself.</p>
+<h2><a name="Rotating">Rotation</a></h2>
+<p>Joe Winchester's <i><a href="http://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html">Taking a look at SWT Images</a></i>
+explains pixel manipulation in
+great detail. Here
+we will show how to rearrange the pixels to get a 90<sup>0 </sup>counter-clockwise
+rotation. In order to demonstrate how other
+classes can interact with <code>SWTImageCanvas</code>, we put
+the implementation in the <code>PushActionDelegate</code> class. The basic steps for our rotation are:</p>
+<ul>
+ <li>Get image data from <code>SWTImageCanvas</code>.</li>
+ <li> Create new image data and rearrange the pixels.</li>
+ <li>Set new image data back to <code>SWTImageCanvas</code>.</li>
+</ul>
+<p>The code in <code>PushActionDelegate</code>
+for rotation is:</p>
+<pre> ImageData src=imageCanvas.getImageData();
+ <b>if</b>(src==<b>null</b>) <b>return</b>;
+ PaletteData srcPal=src.palette;
+ PaletteData destPal;
+ ImageData dest;
+
+ <font color="#3f7f5f">/* construct a new ImageData */</font>
+ <b>if</b>(srcPal.isDirect){
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> destPal=<b>new</b> PaletteData(srcPal.redMask,srcPal.greenMask,srcPal.blueMask);
+ }<b>else</b>{
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> destPal=<b>new</b> PaletteData(srcPal.getRGBs());
+ }
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> dest=<b>new</b> ImageData(src.height,src.width,src.depth,destPal);
+ <font color="#3f7f5f">/* rotate by rearranging the pixels */</font>
+ <b>for</b>(<b>int</b> i=0;i&lt;src.width;i++){<b>
+</b> <b>for</b>(<b>int</b> j=0;j&lt;src.height;j++){
+ <b>int</b> pixel=src.getPixel(i,j);
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> dest.setPixel(j,src.width-1-i,pixel);
+ }
+ }
+<img src="images/tag_5.gif" height=13 width=24 align=CENTER> imageCanvas.setImageData(dest);</pre>
+<p>The code for <code>setImageData()</code> is:</p>
+<pre><b>public</b> <b>void</b> setImageData(ImageData data) {
+ <b>if</b> (sourceImage != <b>null</b>) sourceImage.dispose();
+ <b>if</b>(data!=<b>null</b>)
+ sourceImage = <b>new</b> Image(getDisplay(), data);
+ syncScrollBars();
+}</pre>
+<p>Since we won't change the pixel value, we needn't care about
+the RGB of each pixel. However, we must reconstruct a new <code>ImageData</code> object with different dimension. This
+needs different <code>PaletteData</code> in <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+and <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+for different image formats.&nbsp;<img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+creates a new <code>ImageData</code> and <img src="images/tag_4.gif" height=13 width=24 align=CENTER>
+sets the value of each pixel. <code>setImageData()</code> in <img src="images/tag_5.gif" height=13 width=24 align=CENTER>
+ will dispose the previous <code>sourceImage</code>
+and reconstruct <code>sourceImage</code>
+based on the new <code>ImageData</code>, then update the scrollbars
+and repaint the canvas. We put <code>setImageData()</code>
+inside <code>SWTImageCanvas</code> so it could be used
+by other methods in the future.</p>
+<h2><a name="Plug-in_Implementation">Plug-in Implementation</a></h2>
+<p>We have known how the image canvas works. Now, let's talk briefly about how to implement the plug-in.</p>
+<h3><a name="Create_view_plug-in">Step 1. Create view plug-in</a></h3>
+<p>Follow the steps 1-3 in <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html"><i>Creating
+an Eclipse View</i></a>, we can create a plug-in with a
+single view. The plugin.xml is:</p>
+<pre>&lt;plugin id=&quot;uky.article.imageviewer&quot;
+ name=&quot;image viewer Plug-in&quot;
+ version=&quot;1.0.0&quot;
+ provider-name=&quot;Chengdong Li&quot;
+ class=&quot;uky.article.imageviewer.ImageViewerPlugin&quot;&gt;
+ &lt;runtime&gt;
+ &lt;library name=&quot;imageviewer.jar&quot;/&gt;
+ &lt;/runtime&gt;
+ &lt;requires&gt;
+ &lt;import plugin=&quot;org.eclipse.ui&quot;/&gt;
+ &lt;/requires&gt;
+
+ &lt;extension point=&quot;org.eclipse.ui.views&quot;&gt;
+ &lt;category name=&quot;Sample Category&quot;
+ id=&quot;uky.article.imageviewer&quot;&gt;
+ &lt;/category&gt;
+ &lt;view name=&quot;Image Viewer&quot;
+ icon=&quot;icons/sample.gif&quot;
+ category=&quot;uky.article.imageviewer&quot;
+ class=&quot;uky.article.imageviewer.views.ImageView&quot;
+ id=&quot;uky.article.imageviewer.views.ImageView&quot;&gt;
+ &lt;/view&gt;
+ &lt;/extension&gt;
+&lt;/plugin&gt;</pre>
+<p>The <code>ImageViewerPlugin</code>
+and <code>ImageView</code>
+ are as following:</p>
+<b>
+<pre>public class </b>ImageViewerPlugin<b> extends </b>AbstractUIPlugin {
+<b> public </b>ImageViewerPlugin(IPluginDescriptor descriptor) {
+ <b>super</b>(descriptor);
+ }
+}
+<b>
+public</b> <b>class</b> ImageView <b>extends</b> ViewPart {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b>public</b> SWTImageCanvas imageCanvas;<b>
+ public</b> ImageView() {} <b>
+ public</b> <b>void</b> createPartControl(Composite frame) {
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> imageCanvas=<b>new</b> SWTImageCanvas(frame);
+ }
+ <b>public</b> <b>void</b> setFocus() {
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> imageCanvas.setFocus();
+ }
+ <b>public</b> <b>void</b> dispose() {
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> imageCanvas.dispose();
+ <b>super</b>.dispose();
+ }
+}</pre>
+<p><img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+ declares an instance variable <code>imageCanvas</code>
+to point to an instance of <code>SWTImageCanvas</code>,
+so that other methods can use it. <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+creates an <code>SWTImageCanvas</code> to show the image.
+When the view gets focus, it will set focus to <code>imageCanvas</code>
+in <img src="images/tag_3.gif" height=13 width=24 align=CENTER>.
+The dispose method of <code>SWTImageCanvas</code>
+ will be automatically called in&nbsp;<img src="images/tag_4.gif" height=13 width=24 align=CENTER>
+whenever the view is disposed.</p>
+<h3><a name="Add_viewActions_extension">Step 2. Add viewActions extension</a></h3>
+<p>The image viewer view has five local toolbar buttons: <img border="0" src="images/buttons.jpg" width="138" height="22">. To
+take the advantage of Eclipse, we&nbsp;contribute to the <code>org.eclipse.ui.viewActions</code>
+extension point by adding the following lines to plugin.xml:</p>
+<pre>&lt;extension point=&quot;org.eclipse.ui.viewActions&quot;&gt;
+ &lt;viewContribution
+ targetID=&quot;uky.article.imageviewer.views.ImageView&quot;
+ id=&quot;uky.article.imageviewer.views.ImageView.pushbutton&quot;&gt;
+ &lt;action label=&quot;open&quot;
+ icon=&quot;icons/Open16.gif&quot;
+ tooltip=&quot;Open image&quot;
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> class=&quot;uky.article.imageviewer.actions.PushActionDelegate&quot;
+ toolbarPath=&quot;push_group&quot;
+ enablesFor=&quot;*&quot;
+ id=&quot;toolbar.open&quot;&gt;
+ &lt;/action&gt;
+ .....
+&lt;/viewContribution&gt;</pre>
+<p>The delegate class <code>PushActionDelegate</code>
+ in <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+ will process all the actions from the
+toolbar buttons. It is defined as following:</p>
+<b>
+<pre>public</b> <b>class</b> PushActionDelegate <b>implements</b> IViewActionDelegate {
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> <b>public</b> ImageView view;<b>
+</b> <b>public</b> <b>void</b> init(IViewPart viewPart) {
+ <b>if</b>(viewPart <b>instanceof</b> ImageView){
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> <b>this</b>.view=(ImageView)viewPart;
+ }
+ }<b>
+ public</b> <b>void</b> run(IAction action) {
+ String id=action.getId();
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> SWTImageCanvas imageCanvas=view.imageCanvas;
+ <b>if</b>(id.equals(&quot;toolbar.open&quot;)){
+ imageCanvas.onFileOpen();
+ <b>return</b>;
+ }
+ ....
+<b> if</b>(id.equals(&quot;toolbar.zoomin&quot;)){
+ ....
+ }
+ }
+}</pre>
+<p>This class implements the <code>IViewActionDelegate</code> interface. It has a view instance in <img src="images/tag_2.gif" height=13 width=24 align=CENTER>.
+It gets the view instance during the initialization period<img src="images/tag_3.gif" height=13 width=24 align=CENTER>,
+and later in <img src="images/tag_4.gif" height=13 width=24 align=CENTER>
+it uses the view instance to interact with the <code>SWTImageCanvas</code>.&nbsp;</p>
+<h2><a name="Summary">Summary</a></h2>
+<p>We have shown the detail on how to implement a simple image viewer plug-in for
+Eclipse. The <code>SWTImageCanvas</code> supports scrolling
+and zooming functions by using AWT's <code>AffineTransform</code>. It supports unlimited
+zoom scale and smooth scrolling even for large images.</p>
+<p>Compared with the implementation of Image Analyzer example, this implementation is
+both memory
+efficient and fast.</p>
+<p>The <code>SWTImageCanvas</code> can be used as a base
+class for rendering, scrolling, and scaling image.</p>
+<p>Shortcut keys are a must for usable image viewers. In the interest of space, we did not show
+this here; however, they can be easily added.</p>
+<h2><a name="Acknowledge">Acknowledgements</a></h2>
+<p>I appreciate the help I received from the <a href="http://dev.eclipse.org/newslists/news.eclipse.platform.swt/msg00951.html"> Eclipse mailing
+list</a>; the Eclipse
+team's help in reviewing&nbsp; the article; Pengtao Li's photo picture; and
+finally the support from <a href="http://www.rch.uky.edu">RCH</a> lab at the
+University of Kentucky.</p>
+<h2><a name="Reference">Reference</a>s</h2>
+<p><a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html">Creating
+an Eclipse View</a>. Dave Springgay, 2001 <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html"><br>
+</a>
+<a href="http://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html">Taking a look at SWT
+Images</a>. Joe Winchester, 2003 <a href="http://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html"><br>
+</a>
+<a href="http://www.amazon.com/exec/obidos/tg/detail/-/0321159640/103-6992553-2927029?v=glance">
+The Java Developer's Guide to ECLIPSE</a>. Sherry Shavor, Jim D'Anjou, Scott
+Fairbrother, Dan Kehn, John Kellerman, Pat McCarthy. Addison-Wesley, 2003
+
+</body>
+</html>
diff --git a/Article-Image-Viewer/images/Idea.jpg b/Article-Image-Viewer/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Image-Viewer/images/Idea.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/activity.bmp b/Article-Image-Viewer/images/activity.bmp
new file mode 100644
index 0000000..4520973
--- /dev/null
+++ b/Article-Image-Viewer/images/activity.bmp
Binary files differ
diff --git a/Article-Image-Viewer/images/allClass.jpg b/Article-Image-Viewer/images/allClass.jpg
new file mode 100644
index 0000000..bb9e058
--- /dev/null
+++ b/Article-Image-Viewer/images/allClass.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/all_classes.jpg b/Article-Image-Viewer/images/all_classes.jpg
new file mode 100644
index 0000000..bb9e058
--- /dev/null
+++ b/Article-Image-Viewer/images/all_classes.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/buttons.bmp b/Article-Image-Viewer/images/buttons.bmp
new file mode 100644
index 0000000..172b9e9
--- /dev/null
+++ b/Article-Image-Viewer/images/buttons.bmp
Binary files differ
diff --git a/Article-Image-Viewer/images/buttons.jpg b/Article-Image-Viewer/images/buttons.jpg
new file mode 100644
index 0000000..0102845
--- /dev/null
+++ b/Article-Image-Viewer/images/buttons.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/flower.jpg b/Article-Image-Viewer/images/flower.jpg
new file mode 100644
index 0000000..e8e5321
--- /dev/null
+++ b/Article-Image-Viewer/images/flower.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/gap.bmp b/Article-Image-Viewer/images/gap.bmp
new file mode 100644
index 0000000..eb8d01c
--- /dev/null
+++ b/Article-Image-Viewer/images/gap.bmp
Binary files differ
diff --git a/Article-Image-Viewer/images/linux_only.gif b/Article-Image-Viewer/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Image-Viewer/images/linux_only.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/model.bmp b/Article-Image-Viewer/images/model.bmp
new file mode 100644
index 0000000..f9f6246
--- /dev/null
+++ b/Article-Image-Viewer/images/model.bmp
Binary files differ
diff --git a/Article-Image-Viewer/images/note.gif b/Article-Image-Viewer/images/note.gif
new file mode 100644
index 0000000..e015c95
--- /dev/null
+++ b/Article-Image-Viewer/images/note.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/open.bmp b/Article-Image-Viewer/images/open.bmp
new file mode 100644
index 0000000..14ec49b
--- /dev/null
+++ b/Article-Image-Viewer/images/open.bmp
Binary files differ
diff --git a/Article-Image-Viewer/images/open1.bmp b/Article-Image-Viewer/images/open1.bmp
new file mode 100644
index 0000000..1572b8d
--- /dev/null
+++ b/Article-Image-Viewer/images/open1.bmp
Binary files differ
diff --git a/Article-Image-Viewer/images/open_activity.jpg b/Article-Image-Viewer/images/open_activity.jpg
new file mode 100644
index 0000000..0551001
--- /dev/null
+++ b/Article-Image-Viewer/images/open_activity.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/paint.bmp b/Article-Image-Viewer/images/paint.bmp
new file mode 100644
index 0000000..acb626d
--- /dev/null
+++ b/Article-Image-Viewer/images/paint.bmp
Binary files differ
diff --git a/Article-Image-Viewer/images/render_flowchart.jpg b/Article-Image-Viewer/images/render_flowchart.jpg
new file mode 100644
index 0000000..53c66ac
--- /dev/null
+++ b/Article-Image-Viewer/images/render_flowchart.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/render_model.jpg b/Article-Image-Viewer/images/render_model.jpg
new file mode 100644
index 0000000..fa41b38
--- /dev/null
+++ b/Article-Image-Viewer/images/render_model.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/screen_shot.jpg b/Article-Image-Viewer/images/screen_shot.jpg
new file mode 100644
index 0000000..0c27751
--- /dev/null
+++ b/Article-Image-Viewer/images/screen_shot.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/scroll_zoom_activity.jpg b/Article-Image-Viewer/images/scroll_zoom_activity.jpg
new file mode 100644
index 0000000..058986c
--- /dev/null
+++ b/Article-Image-Viewer/images/scroll_zoom_activity.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/tag_1.gif b/Article-Image-Viewer/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Image-Viewer/images/tag_1.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/tag_2.gif b/Article-Image-Viewer/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Image-Viewer/images/tag_2.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/tag_3.gif b/Article-Image-Viewer/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Image-Viewer/images/tag_3.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/tag_4.gif b/Article-Image-Viewer/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Image-Viewer/images/tag_4.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/tag_5.gif b/Article-Image-Viewer/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Image-Viewer/images/tag_5.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/tag_6.gif b/Article-Image-Viewer/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Image-Viewer/images/tag_6.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/tag_7.gif b/Article-Image-Viewer/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Image-Viewer/images/tag_7.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/tip.gif b/Article-Image-Viewer/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Image-Viewer/images/tip.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/transform.bmp b/Article-Image-Viewer/images/transform.bmp
new file mode 100644
index 0000000..28dc072
--- /dev/null
+++ b/Article-Image-Viewer/images/transform.bmp
Binary files differ
diff --git a/Article-Image-Viewer/images/transform.jpg b/Article-Image-Viewer/images/transform.jpg
new file mode 100644
index 0000000..8c170bd
--- /dev/null
+++ b/Article-Image-Viewer/images/transform.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/tryit.gif b/Article-Image-Viewer/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Image-Viewer/images/tryit.gif
Binary files differ
diff --git a/Article-Image-Viewer/images/viewer.jpg b/Article-Image-Viewer/images/viewer.jpg
new file mode 100644
index 0000000..0c27751
--- /dev/null
+++ b/Article-Image-Viewer/images/viewer.jpg
Binary files differ
diff --git a/Article-Image-Viewer/images/win_only.gif b/Article-Image-Viewer/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Image-Viewer/images/win_only.gif
Binary files differ
diff --git a/Article-Image-Viewer/imageviewer.zip b/Article-Image-Viewer/imageviewer.zip
new file mode 100644
index 0000000..3af692f
--- /dev/null
+++ b/Article-Image-Viewer/imageviewer.zip
Binary files differ
diff --git a/Article-Internationalization/how2I18n.html b/Article-Internationalization/how2I18n.html
new file mode 100644
index 0000000..929e39f
--- /dev/null
+++ b/Article-Internationalization/how2I18n.html
@@ -0,0 +1,1255 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<META name="GENERATOR" content="IBM WebSphere Studio Homepage Builder V6.0.2 for Windows">
+<META http-equiv="Content-Style-Type" content="text/css">
+<title>How to Internationalize your Eclipse Plug-In</title>
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+<BODY link="#0000ff" vlink="#800080" bgcolor="#ffffff" leftMargin="2" topMargin="2" marginwidth="2" marginheight="2">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2002 International Business Machines Corp.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">How to Internationalize your Eclipse Plug-In</h1>
+<BLOCKQUOTE>
+<b>Summary</b>
+<br>
+This article is a roadmap for writing Eclipse plug-ins destined for the
+international market. We'll begin with a brief review of the motivations
+and technical challenges of internationalization, followed by step-by-step
+instructions of how to internationalize your Eclipse plug-in.
+<p><B>By Dan Kehn, Scott Fairbrother, and Cam-Thu Le</b><br>
+IBM Eclipse ISV Enablement
+(Jumpstart) Team
+
+ <p>August 23, 2002</p>
+ <p>Editor's note: This article reflects Eclipse release 2.0.</p>
+</blockquote>
+<H2>Introduction</H2>
+<p>An old joke in the internationalization community goes like this:</p>
+<blockquote>"A person who speaks three languages is called trilingual.
+ And a person who speaks two languages is called bilingual.
+ So what do you call someone who only speaks one language?"
+<P><I>&lt;insert dramatic pause here&gt;</I></P>
+</blockquote>
+<blockquote>
+ "American."
+</blockquote>
+<p>Today, providing a software product solely in English is no longer acceptable
+ from a usability, quality, marketing, and in some cases, legal standpoint. Enabling your product for the world market simply makes economic sense. And the enablement process is relatively straightforward, as this article will show.</p>
+<p>A few notes before we begin. Because the Eclipse
+Platform adopts the internationalization
+implementation provided with the Java SDK, it's helpful
+to read the <a href="http://java.sun.com/docs/books/tutorial/i18n/intro/index.html">Java
+ Tutorial: Internationalization</a> trail before continuing. The tutorial presents a fine overview of the issues and
+ steps involved in the process. We will assume that you've already read the tutorial
+ so we can underscore the key points, surface other noteworthy items, and cover
+ Eclipse-specific issues and steps in this article. And when you run into unfamiliar
+ terminology or acronyms in this article,
+jump to our <a href="#glossary">glossary</a>.</p>
+<H3><a name="overview">Overview of internationalization</a></H3>
+<p><i>Internationalization</i> is the process of creating software for the world market.
+ Besides the economic benefits, some countries require products to pass certain localization requirements set by the government before it can be introduced to their markets.</p>
+<p>The process of internationalition is usually accomplished in two steps:</p>
+<ol>
+<li>
+<b>NLS-enabling the product.</b>
+<br />
+ This step covers coding techniques and user interface
+ design issues. Enabling a product for National Language Support (NLS) ensures the product is designed for national language function
+ and uses proper APIs to handle national language data. During this step, smart
+ coding practices -- such as avoiding hardcoded strings, making input buffers
+ large enough to hold translatable text, properly parsing strings that contain
+ non-Latin characters, not localizing strings saved as part of a file format,
+ and isolating the national language elements from program code -- must be weighed
+ and considered so the translation can be completed with minimal expense and
+ effort.
+<p>
+ </li>
+<li>
+<b>Translating the product.</b>
+<br />This step involves translating the domestic
+language elements
+ into a foreign language. As with words and phrases, pictures
+ and symbols may also be interpreted differently
+by various cultures. It is during
+ the translation verification step that
+all translations are reviewed for contextual
+ accuracy, icons or clip art are modified
+to ensure there are no user misinterpretations,
+ and page layouts are checked for inadvertent
+text truncation. While verifying
+ the product's functional integrity after
+translation, this step also looks for
+ hidden cultural impacts.
+</li>
+</ol>
+<H3><a name="affected">What does internationalization affect?</a></H3>
+<p><i>Monoglots take note</i>: This is the beginning of your sensitivity training.
+ There may be a quiz at end of this article. :-)</p>
+<p>Let's begin with a distillation of the list of culturally dependent data
+presented in the Java Internationalization tutorial, reordered by the likelihood
+that the typical developer will encounter it, and followed by details on
+each:</p>
+<ol>
+<li>
+<a href="#data_text">Text</a>
+<br />Messages, labels on GUI components
+ <br />Online help (*.html), Plug-in manifest (plugin.xml)<br />
+ </li>
+<li>
+<a href="#data_formatting">Data formatting</a>
+<br />Numbers, dates, times, currencies
+ <br />Phone numbers, postal addresses<br />
+ </li>
+<li>
+<a href="#data_regional">Regional and personal substitutions</a>
+<br />Measurements
+ <br />Honorifics and personal titles<br />
+ </li>
+<li>
+<a href="#data_multimedia">Multimedia considerations</a>
+</li>
+</ol>
+<H4><a name="data_text">Text</a></H4>
+<p><b>Messages, labels on GUI components</b>
+<br />
+Resource bundles nicely handle language-dependent
+texts. The strategy is either to load all
+strings at once into a <a href="http://java.sun.com/j2se/1.3/docs/api/java/util/class-use/ResourceBundle.html">ResourceBundle</a> subclass, or to retrieve them individually.
+The Eclipse Java Development Tooling (JDT)
+in version 2.0 provides wizards to support
+the detection of translatable strings. We'll
+return to them shortly in <a href="#steps">Internationalization steps</a>.</p>
+<p>Loading translated strings into memory is only the first step. The next
+step is to pass them to the appropriate controls for display (such as a
+label, text field, menu choice, etc.). The page designer and programmer
+must work together to assure that the chosen layout allows for appropriate
+resizing and reflowing of the dialog. The layout support in the Standard
+Widget Toolkit (SWT) library relies heavily on the programmer to &quot;do
+the right thing&quot; by specifying layout descriptions that react appropriately
+to changes in field sizes. The article <A href="http://eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm">Understanding Layout in SWT</A> covers the implementation issues in detail.</p>
+<p>This is particularly important because text
+length increases during translation. English
+phrases are often shorter than their equivalent
+translations, usually on the order of 40%.
+Font sizes also may need to be modified to
+accommodate the local language.
+</p>
+<p>
+<b>
+<a name="plugin_xml_attribs">Online help (*.html), Plug-in manifest (plugin.xml)</a>
+</b>
+<br />
+ These forms of text content are more involved than simple key/value-oriented
+ properties files, so the steps to their externalization are slightly more complex.</p>
+<p>In the case of the manifest file, it is coupled
+with a similarly named property file, plugin.properties,
+ containing only the externalized text.
+Special care must be taken with manifest
+files like plugin.xml and fragment.xml, since
+the attributes of the tags can contain both
+translated and untranslated text. Consider
+the benign example below:</p>
+<a name="c1"><b>Listing 1. Plug-in manifest file, before translation</b></a><table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+<tr><td><pre><code> &lt;plugin
+ name=&quot;Jumpstart Example Plug-in&quot;
+ id=&quot;com.ibm.jumpstart.example&quot;
+ version=&quot;2.0.0&quot;
+ provider-name=&quot;IBM Corporation&quot;
+ class=&quot;com.ibm.jumpstart.example.ExamplePlugin&quot;&gt;
+</code></pre></td></tr>
+</table>
+<p>Here we see a mix of translatable text, untranslatable text, and "gray
+ area" translatable text, all as tag attributes. Clearly the
+<code>id</code> and <code>class</code> attributes are not translatable,
+since they represent programming identifiers. It is equally certain that the
+<code>name</code> attribute should be translated.</p>
+<p>You might be tempted to consider the
+<code>version</code> attribute (because of the locale-dependent decimal separator) or <CODE>provider-name</CODE> attribute (because of the locale-dependent legal attribution &quot;Corporation&quot;)
+as candidates for translation, since they will be displayed to the end
+user. However, version numbers are generally left untranslated for two
+reasons: end users attribute little meaning to their numeric value, and
+programmers sometimes write code that expects version numbers to be a composed
+string like &quot;3.5.4&quot;. It is arguably a better design decision
+that the version information be stored as separate numbers like major,
+minor, and service update to avoid the need to parse a version string,
+but that discussion is beyond the scope of this article.</p>
+<p>The <CODE>provider-name</CODE> may be left untranslated as well, since &quot;Corporation&quot; has legal meaning that can defy accurate translation. After identifying what text needs to be externalized, our example now looks like this:</p>
+<a name="c2"><b>Listing 2. Plug-in manifest file, after translation</b></a><table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+<tr><td><pre><code> &lt;plugin
+ name=&quot;<B>%<span class="boldcode">plugin.name</span></B>&quot;
+ id=&quot;com.ibm.jumpstart.example&quot;
+ version=&quot;2.0.0&quot;
+ provider-name=&quot;IBM Corporation&quot;
+ class=&quot;com.ibm.jumpstart.example.ExamplePlugin&quot;&gt;
+</code></pre></td></tr>
+</table>
+<p>where <code>plugin.properties</code> contains the externalized string, &quot;Jumpstart
+ Example Plug-in&quot; associated with the key <code>plugin.name</code>.</p>
+<p>This simple example demonstrates
+that translating isn't simply providing equivalent
+words or phrases for your text; it also involves
+an understanding of the local cultural considerations
+and potential legal impacts. This is why
+a translation professional is necessary,
+as well as translation verification testing.</p>
+<H4><a name="data_formatting">Data formatting</a></H4>
+<p><b>Numbers, dates, times, currencies</b>
+<br />
+The Java library includes classes that handle the necessary formatting for numbers
+ (decimal separator, thousands separator, grouping), dates (MDY, DMY, first day
+ of work week), times (12- or 24-hour format, separator), and currencies (local
+ symbol, shown as suffix or prefix, leading separator or none).</p>
+<p>
+<b>Phone numbers, postal addresses</b>
+<br />
+These are more subtle and less common text
+translation concerns, but still noteworthy.
+Many applications simply allow free-format
+entry of phone numbers since there are so
+many local variations. Postal addresses are
+straightforward: Adding a "State/Province"
+field and allowing for multiple address lines
+is generally sufficient.</p>
+<H4><a name="data_regional">Regional and personal substitutions</a></H4>
+<p><b>Honorifics and personal titles</b>
+<br />
+Though less common in the United States, the proper enablement
+ of honorifics (Mr., Mrs., Dr.) is considered absolutely necessary elsewhere to avoid a
+ serious breach of etiquette.</p>
+<p>
+<b>Measurements</b>
+<br />
+These are less frequently encountered. This
+involves substitution of measurement indications
+with corresponding conversion (for example, miles
+versus kilometers). In many cases, users
+will need either simultaneous display of
+a measure in different units, or an easy
+way of toggling between them.</p>
+<H4><a name="data_multimedia">Multimedia considerations</a></H4>
+<p>In general, products should select regionally
+ neutral sounds, colors, graphics, and icons.</p>
+<p>This means no Homer Simpson "D'oh!" sound associated with
+error messages. If you're thinking that
+no serious development organization would
+do such a thing, consider an icon that is
+typical of those that are proposed and rejected:</p>
+<p>
+<IMG src="images/route66.jpg" width="39" height="39" alt="Route 66 icon" />
+</p>
+<p>The developer wanted to convey a metaphor for &quot;IP router&quot; by using a symbol harkening back to a national highway that traversed the United States from Chicago to Los Angeles, called <A href="http://www.national66.org/66hstry.html">Route 66</A>. Most Americans would find this metaphor obtuse; imagine the confusion of the hapless non-US user.</p>
+<p>Similarly, the image below may be intuitive to many North American users:
+<p>
+<IMG src="images/mailbox.jpg" width="85" height="95" alt="Mailbox icon" />
+</p>
+ <p>But in recognition studies, others from outside
+the United States have guessed that this
+is a birdhouse. This is the more
+universally accepted image for mail:</p>
+<p>
+<IMG src="images/envelope.jpg" width="23" height="23" alt="Envelope icon" />
+</p>
+<p>To avoid confusing and potentially offensive visuals, the best course is to engage professional graphic artists who are aware of cultural issues.</p>
+<H3><a name="steps">Internationalization steps</a></H3>
+<p>Now let's turn to the actual steps for internationalizing your Eclipse plug-in:</p>
+<ol>
+<li>
+<a href="#step1">Move translatable strings into *.properties
+ files</a>
+</li>
+<li>
+<a href="#step2">Separate presentation-dependent parameters</a>
+</li>
+<li>
+<a href="#step3">Use proper locale-sensitive data formatting,
+ substitutions APIs</a>
+</li>
+<li>
+<a href="#step4">Test in domestic language</a>
+</li>
+<li>
+<a href="#step5">Create initial translated plug-in fragment</a>
+</li>
+<li>
+<a href="#step6">Prepare and send domestic language materials
+ for translation</a>
+</li>
+<li>
+<a href="#step7">Repackage and validate translated materials</a>
+</li>
+<li>
+<a href="#step8">Deploy fragments</a>
+</li>
+</ol>
+<p>We'll discuss each of these steps in detail.</p>
+<H4><a name="step1">Step 1. Move translatable strings into *.properties
+files</a></H4>
+<p>Fortunately, Eclipse's Java Development Tooling provides considerable help to properly separate translatable strings. The <b>Source &gt; Find Strings to Externalize</b> menu choice displays the <b>Externalize Strings</b> wizard. This wizard will lead you through
+the steps to locate hardcoded strings in
+your code, classify them as translatable
+or not, then modify the code to use a resource
+bundle where appropriate.</p>
+<p>We'll introduce the <b>Externalize Strings</b> wizard with an example,
+ the canonical "Hello World" <i>before</i> using the wizard:</p>
+<a name="c3"><b>Listing 3. Hello world, before translation</b></a><table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+<tr><td><pre><code> package com.jumpstart.nls.example.helloworld;
+ public class HelloWorld {
+ static public void main(String[] args) {
+ System.out.println(&quot;Copyright (c) IBM Corp. 2002.&quot;);
+ System.out.println(&quot;Hello.&quot;);
+ System.out.println(&quot;How are you?&quot;);
+ System.out.println(&quot;Goodbye.&quot;);
+ }
+}
+</code></pre></td></tr>
+</table>
+<p>Selecting <CODE>HelloWorld.java</CODE> and then <b>Source &gt; Externalize Strings</b> will display the wizard shown in Figure 1:</p>
+<p>
+<a name="f2"><b>Figure 1. Externalize Strings wizard</b></a><br /><IMG src="images/image2.jpg" width="576" height="430" alt="Externalize Strings wizard" />
+</p>
+<p>By selecting an entry from the table and
+then one of the pushbuttons to the
+ right, you can mark the strings as belonging
+to one of three cases:</p>
+<ul>
+<li>
+<IMG src="images/translate.jpg" width="10" height="10" alt="Translate" />
+ Translate
+<br />
+Action: An entry is added in the properties files; the auto-generated key and
+ access code is substituted in the code for the original string. The string used
+ to specify the key is marked as non-translatable with a comment marker, such as
+"<code>// $NON-NLS-1$</code>"<br />
+<br />
+</li>
+<li>
+<IMG src="images/never.jpg" width="12" height="11" alt="Never translate" />
+ Never Translate<br />
+Action: The string is marked as non-translatable with a comment marker. The
+ <b>Externalize Strings</b> wizard will not flag it as untranslated in subsequent
+ executions.<br />
+<br />
+</li>
+<li>
+<IMG src="images/skip.jpg" width="11" height="11" alt="Skip" />
+Skip<br />
+Action: Nothing is modified. Subsequent executions of the <b>Externalize Strings</b> wizard will flag the string as potentially translatable.</li>
+</ul>
+The trailing number in the <code>// $NON-NLS-1$</code> comment marker indicates which
+ string is not to be translated in the case where are there are several strings
+ on a single line. For example:
+ <blockquote>
+<code>x.foo("Date", "TOD", "Time"); // $NON-NLS-2$</code>
+</blockquote>
+ <p>Here the middle parameter is flagged as non-NLS. The other two are skipped.</p>
+<p>Returning to our example, note that the total number of strings for each category
+ is summarized below the list. The key names of the externalized strings are
+ auto-generated based on the string value, but they can be renamed directly in
+ the table. In addition, an optional prefix can be specified (<code>S_</code>
+ in the example below).</p>
+<p>
+<a name="f6"><b>Figure 2. Externalize Strings wizard</b></a><br /><IMG src="images/image6.jpg" width="576" height="434" alt="Externalize Strings wizard" />
+</p>
+<p>
+<i>Hint</i>: Clicking the icon in the first column of a given row will advance
+ to the next choice: Translate, Never Translate, or Skip.</p>
+<p>Now that we've identified what strings are translatable, continue to the next
+ step to choose how they will be externalized. Here's the page displayed after
+ selecting <b>Next</b>; the <b>Property file name</b> and resource bundle accessor
+ <b>Class name</b> were modified to more specific values than the defaults:</p>
+<p>
+<a name="f7"><b>Figure 3. Externalize Strings wizard</b></a><br /><IMG src="images/image7.jpg" width="576" height="434" alt="Externalize Strings wizard" />
+</p>
+<p>The resource bundle accessor class will contain code to load the properties
+ file and a static method to fetch strings from the file. The wizard will generate
+ this class, or you can specify your own existing alternative implementation.
+ In the latter case, you may want to uncheck the <b>Use default substitution
+ choice</b> and specify an alternative code pattern for retrieving externalized
+ strings. If the accessor class is outside of the package (for example, a centralized
+ resource bundle accessor class), you can optionally specify that you want to
+ <b>Add [an] import declaration</b> to the underlying source.</p>
+<p>The <b>Externalize Strings</b> wizard uses the JDT Refactoring framework, so
+ the next two pages should look familiar. First, a list of warnings:</p>
+<p>
+<a name="f8"><b>Figure 4. Externalize Strings wizard</b></a><br /><IMG src="images/image8.jpg" width="576" height="357" alt="Externalize Strings wizard" />
+</p>
+<p>And finally a side-by-side presentation of the proposed changes:</p>
+<p>
+<a name="f9"><b>Figure 5. Externalize Strings wizard</b></a><br /><IMG src="images/image9.jpg" width="576" height="356" alt="Externalize Strings wizard" />
+</p>
+<p>Once you select <b>Finish</b>, the wizard performs the source code modifications,
+ creates the resource bundle accessor class, and generates the initial properties
+ file. Here is the code for the standard resource bundle accessor class:</p>
+<a name="c4"><b>Listing 4. Standard resource bundle accessor class</b></a><table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+<tr><td><pre><code> package com.jumpstart.nls.example.helloworld;
+ import java.util.MissingResourceException;
+ import java.util.ResourceBundle;
+
+ public class HelloWorldMessages {
+
+ private static final String BUNDLE_NAME =
+ &quot;com.jumpstart.nls.example.helloworld.HelloWorld&quot;; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE =
+ ResourceBundle.getBundle(BUNDLE_NAME);
+
+ private HelloWorldMessages() {}
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return &quot;!&quot; + key + &quot;!&quot;;
+ }
+ }
+ }
+</code></pre></td></tr>
+</table>
+<p>The only variation in this generated code
+is the value assigned to the static final,
+<code>BUNDLE_NAME</code>. Before we continue to the next
+step, below are some noteworthy guidelines
+contributed by Erich Gamma and Thomas M&#228;der
+of the JDT team.</p>
+<H4><a name="gln">Guidelines for managing resource bundles and properties files</a></H4>
+<p>These guidelines are designed to:</p>
+<ul>
+<li>Reduce the number of NLS errors, in other words, the values of externalized strings
+ that are not found at runtime</li>
+<li>Enable cross-referencing between the keys
+ referenced in the code and the keys defined
+ in the properties file</li>
+<li>Simplify the management of the externalized strings. Using a centralized
+ property file can result in frequent change conflicts. In addition, it requires
+ the use of prefixes to make keys unique and complicates the management of
+ the keys.</li>
+</ul>
+<p>To achieve these goals, we propose the following guidelines: </p>
+<ol>
+<li>
+<b>Use a properties file per package, and qualify
+the keys by class name</b>
+<p>For example, all the strings for the JDT
+search component are in SearchMessages.properties,
+with key/value pairs like:<br />
+<br />
+<code>SearchPage.expression.pattern=(? = any character, * = any string) <BR>
+ ShowTypeHierarchyAction.selectionDialog.title=Show in Type Hierarchy </code>
+</p>
+</li>
+<li>
+<b>Use a dedicated static resource bundle accessor
+class </b>
+<p>Let the <b>Externalize Strings</b> wizard generate this class. It should be
+named like the properties file. So in our
+example, it would be called SearchMessages.
+When you need to create formatted strings,
+add the convenience methods to the bundle
+accessor class. For example:</p>
+<a name="c5"><b>Listing 5. Static resource bundle accessor class</b></a><table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+<tr><td><pre><code> public static String getFormattedString(String key, Object arg) {
+ String format= null;
+ try {
+ format= RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return &quot;!&quot; + key + &quot;!&quot;;//$NON-NLS-2$ //$NON-NLS-1$
+ }
+ if (arg == null)
+ arg= &quot;&quot;; //$NON-NLS-1$
+ return MessageFormat.format(format, new Object[] { arg });
+ }
+ public static String getFormattedString (String key, String[] args) {
+ return MessageFormat.format(RESOURCE_BUNDLE.getString(key), args);
+ }
+</code></pre></td></tr>
+</table>
+<br />
+</li>
+<li>
+<b>Do not use computed keys</b>
+<p>There is no easy way to correlate a computed
+key in the code with the key in the properties file. In particular
+it is almost impossible to determine whether a key is no longer in use.</p>
+</li>
+<li>
+<b>The convention for the key name is &lt;classname&gt;.&lt;qualifier&gt;</b>
+<p>Example: PackageExplorerPart.title</p>
+</li>
+</ol>
+<H4><a name="step2">Step 2. Separate presentation-dependent parameters</a></H4>
+<p>Not all externalized text is simply words and phrases that will be translated to a target language. Some are more specifically related to your plug-in's implementation. Examples include properties, preferences, and default dialog settings.</p>
+<p>Here are a few specific examples that might
+find their way into a properties file:</p>
+<ul>
+<li>Size or layout constraints. For example,
+ the appropriate width of a non-resizable
+ table column</li>
+ <li>Default fonts that are dependent on the language or operating system. A good
+ default font for Latin-1 languages is an invalid choice for DBCS languages.</li>
+</ul>
+<p>For those plug-ins that subclass from <a href="http://eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/reference/api/org/eclipse/ui/plugin/AbstractUIPlugin.html">AbstractUIPlugin</a>, NL-related parameters can also be found
+in its <a href="http://eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/guide/preferences_prefs.htm">default
+ preference</a> stores (pref_store.ini) and <a href="http://eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/guide/dialogs_settings.htm">dialog
+ settings </a>(dialog_settings.xml). The Eclipse Workbench itself does not use
+ default preference stores, opting instead to store defaults in properties files
+ and then initialize them via AbstractUIPlugin's <code>initializeDefaultPreferences(IPreferenceStore)</code> method.</p>
+<H4><a name="step3">Step 3. Use proper locale-sensitive data formatting, substitutions APIs</a></H4>
+<p>Please refer to the detailed coverage in the <a href="http://java.sun.com/docs/books/tutorial/i18n/intro/index.html">Java Tutorial: Internationalization</a> trail.</p>
+<H4><a name="step4">Step 4. Test in domestic language</a></H4>
+<p>Testing the readiness of a product for translation is non-trivial and beyond
+the scope of this article. However, the follow-on article <a href="http://eclipse.org/articles/Article-TVT/how2TestI18n.html">How to Test your Internationalized Eclipse Plug-in</a> presents strategies for validating the NL-sensitive aspects of your product.</p>
+<H4><a name="step5">Step 5. Create initial translated plug-in fragment</a></H4>
+<p>At this point, we could simply copy our domestic language property files to
+similarly named files with locale-specific suffixes (for example, MyMessages_xx.properties,
+where xx is the language), and move to step 6, <a href="#step6">Prepare and send domestic language materials for translation</a>. In this case, the product is delivered with its code and whatever languages it supports as a single install.</p>
+<p>However, this approach has a few drawbacks.
+Firstly, the code and its national language
+resources are intermingled in the same directory
+/ JAR file. If the translation lags the code
+delivery, the plug-in JAR file must be updated,
+despite the fact that the underlying code
+is unchanged. Secondly, files other than
+property files are not inherently locale-sensitive,
+so they must be segregated to separate directories
+for each language (for example, HTML, XML, images).</p>
+<p>To address these issues, the Eclipse Platform
+introduces the notion of another reusable
+component that complements plug-ins, called
+a <i>plug-in fragment</i>. A plug-in fragment provides
+additional functionality to its target plug-in.
+At runtime, these plug-in contributions
+are merged along with all dependent fragments.
+These contributions can include code contributions
+and contributions of resources associated
+with a plug-in, like property and HTML files.
+In other words, the plug-in has access to
+the fragment's contents via the plug-in's classloader.</p>
+<H4><a name="g1">How and why to use fragments to provide the translatable information</a></H4>
+<p>A plug-in fragment is an ideal way to distribute
+Eclipse-translated information including
+HTML, XML, INI, and bitmap files. Delivering
+translations in a non-intrusive way, the
+Eclipse Platform translations are packaged
+in fragment JAR files and are added to existing
+Eclipse installations without changing or
+modifying any of the original runtime elements.
+This leads to the notion of a <i>language
+pack</i>.</p>
+<p>The Eclipse Platform merges plug-in fragments
+in a way that the runtime elements in the
+fragment augment the original targeted plug-in.
+The target plug-in is not moved, removed,
+or modified in any way. Since the fragment's
+resources are located by the classloader, the plug-in developer
+has no need to know whether resources are
+loaded from the plug-in's JAR file or
+one of its fragments' JAR files.</p>
+<H4><a name="g2">Eclipse Language Pack JAR</a></H4>
+<p>The Java language supports the notion of a language pack
+with the resource bundle facility. The Java
+resource bundles do not require modification
+of the application code to support another
+language. The *.properties file namespace
+avoids collisions through the following naming
+convention: <i>basename_lang_region_variant</i>. At runtime, the <a href="http://java.sun.com/j2se/1.3/docs/api/java/util/class-use/ResourceBundle.html">ResourceBundle</a> facility finds the appropriate properties
+file for the current locale.</p>
+<p>The approach to deploying files such as HTML
+and XML files in fragments is slightly different
+than Java resource bundles in that the Eclipse
+fragment uses a directory structure to sort
+out the different language versions.</p>
+<p>
+<b>Example fragment contents</b>
+<br />
+The plug-ins and the plug-in fragments reside
+in separate subdirectories found immediately
+under the eclipse subdirectory. Looking at
+our example fragment, as deployed on a German
+system, we see an \nl folder, fragment.xml
+and an nl1.jar file.</p>
+<p>
+<a name="f20"><b>Figure 6. Fragments subdirectories</b></a><br /><IMG src="images/image20.jpg" width="504" height="278" border="0" alt="" />
+</p>
+<p>Typically, translated *.properties files
+are suffixed according to the resource bundle
+rules and deployed in JAR files. In contrast,
+when a view needs an input file type whose
+name is not locale-sensitive like resource
+bundles (such as *.xml), we define a subdirectory
+structure for each language version of the
+file. The de subdirectory above
+is one such example, where de = German.</p>
+<p>
+<b>Fragment manifest</b>
+<br />
+Each plug-in folder can optionally contain a fragment
+manifest file, fragment.xml. The manifest
+file describes the plug-in fragment, and
+is almost identical to the plug-in manifest
+(plugin.xml), with the following two exceptions:</p>
+<ul>
+<li>The <code>class</code> attribute is gone since
+ fragments do not have a plug-in class. They
+ just follow their target's specification.</li>
+<li>There are no dependencies because the fragments have the same dependencies
+ as their target plug-in.</li>
+</ul>
+<p>Manifests used to describe a national language
+fragment are typically quite simple, specifying
+only the <code>&lt;fragment&gt;</code> and <code>&lt;runtime&gt;/&lt;library&gt;</code> tags. Here's the example
+fragment manifest file in its entirety:</p>
+<a name="c6"><b>Listing 6. Fragment manifest file</b></a><table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+<tr><td><pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;fragment
+ id=&quot;com.jumpstart.nls.example.helloworld.nl1&quot;
+ name=&quot;NLS Example Plugin NL Support&quot;
+ version=&quot;1.0.0&quot;
+ provider-name=&quot;IBM&quot;
+ plugin-id=&quot;com.jumpstart.nls.example&quot;
+ plugin-version=&quot;1.0.0&quot;&gt;
+&lt;runtime&gt;
+ &lt;library name=&quot;nl1.jar&quot; type=&quot;resource&quot;/&gt;
+ &lt;library name=&quot;$nl$/&quot;/&gt;
+&lt;/runtime&gt;
+&lt;/fragment&gt;
+</code></pre></td></tr>
+</table>
+<p>The <code>&lt;fragment&gt;</code> tag attributes are:</p>
+<ul>
+<li>
+<b>
+<code>name</code>
+</b> -- User-displayable name for the extension.</li>
+<li>
+<b>
+<code>id</code>
+</b> -- Identifier for this fragment configuration.
+Used to uniquely identify this fragment instance.</li>
+<li>
+<b>
+<code>plugin-id</code>
+</b> -- Reference to the target extension point. This plug-in fragment merges with this target extension.</li>
+<li>
+<b>
+<code>plugin-version</code>
+</b> -- Version of the fragment plug-in. </li>
+<li>
+<b>
+<code>version</code>
+</b> -- Version specification in major.minor.service
+format.</li>
+ <li><B><CODE>type</CODE></B> -- The default is '&quot;code&quot;. Specifying &quot;resource&quot; indicates the library includes resource files and no code. This improves overall performance significantly because resource-only libraries are skipped when loading code.</li>
+ </ul>
+<p>The <code>&lt;runtime&gt;</code> section contains a definition of one or more libraries that make up the
+plug-in fragment runtime. The referenced libraries are used by the platform
+execution mechanisms where the plug-in loads, merges, and executes the
+correct code required by the plug-in. The <CODE>name</CODE> attribute accepts a library name (&quot;nl1.jar&quot; above) or directory
+containing resources. A directory reference must contain a trailing path
+separator. Optionally, the specification may include a substitution variable.
+In the example above, the second library includes a variable substitution
+<CODE>$nl$</CODE> based on the locale; it is used above to add a language/region specific
+folder to the library search path (e.g., a locale of &quot;it&quot; = Italy,
+&quot;fr&quot; = France, or &quot;de&quot; = Germany, etc. would add the
+corresponding plug-in subdirectory <CODE>it/</CODE>, <CODE>fr/</CODE>, or <CODE>de/</CODE> to the list of searched paths). The value of the <CODE>nl</CODE>, <CODE>os</CODE>, <CODE>ws</CODE>, and <CODE>arch</CODE> substitutions variables can be displayed and modified on the <B>Window &gt; Preferences &gt; Plug-in Development &gt; Target Environment</B> page. The <CODE>nl</CODE> substitution variable is used in those cases where it is not possible or practical to suffix files with the locale name.</p>
+<p>
+<b>Building a fragment</b>
+<br />
+The Eclipse Workbench comes with a tool used
+in plug-in development: <i>the Plug-in Development Environment
+(PDE)</i>. The PDE contains support for developing
+plug-in fragments.</p>
+<p>Let's now examine how to build a fragment
+for national language translations using
+the PDE. There is no practical limit to the
+number of languages in a given fragment.
+The fragment then is the basis of our "Language
+Pack" containing one or more language
+translations. However, in this example, we'll
+confine our language pack to the German translation.</p>
+<p>To build a plug-in fragment, start the New
+Project wizard (<b>File</b> &gt; <b>New</b> &gt; <b>Project...</b>), select the <b>Plug-in Development</b> category, then <b>Fragment Project</b> type. On the first page of the New Fragment
+Wizard, type the project name. Keep in mind
+that the project name will also become the
+fragment ID. For example, starting a project
+adding national language support to the HelloWorld
+example, we would name our project "com.jumpstart.nls.example.helloworld.nl1".
+The trailing ".nl1" is not required,
+but does help distinguish fragments that
+represent "language packs" from
+fragments that add additional code and functionality.</p>
+<p>
+<a name="f7"><b>Figure 7. Starting a fragment project</b></a><br /><IMG src="images/fraggen1.jpg" border="0" width="500" height="500" alt="Starting a fragment project" />
+</p>
+<p>Press <b>Next</b>. We see the default values for the project's
+source folder and runtime library on the
+second page:</p>
+<p>
+<a name="f8"><b>Figure 8. Defining fragment folders</b></a><br /><IMG src="images/fraggen2.jpg" border="0" width="500" height="500" alt="Defining fragment folders" />
+</p>
+<p>These values seem reasonable, so pressing
+<b>Next</b> again, we arrive at the "Fragment Code
+Generators" page. Select the second
+radio button to indicate we want to create
+the fragment manifest file from a template,
+then select the <b>Default Fragment Generator</b> wizard from the list.</p>
+<p>
+<a name="f9"><b>Figure 9. Selecting the default wizard</b></a><br /><IMG src="images/fraggen3.jpg" border="0" width="500" height="500" alt="Selecting the default wizard" />
+</p>
+<p>After pressing <b>Next</b>, we see the "Simple Fragment Content"
+page. This page has two entries used to target
+our fragment on an existing plug-in. We must
+supply the plug-in target id and version.
+We can use the <b>Browse</b> button to select the plug-in that we want
+to extend.</p>
+<p>
+<a name="f10"><b>Figure 10. Targeting the fragment</b></a><br /><IMG src="images/image23.jpg" border="0" width="500" height="500" alt="Targeting the fragment" />
+</p>
+<p>Now let's proceed to the fragment manifest editor, which is similar to the plug-in manifest editor in that
+it is a multi-page editor with Overview,
+Runtime, Extensions, Extension Points, and
+Source pages.</p>
+<p>
+<a name="f11"><b>Figure 11. Fragment manifest editor</b></a><br /><IMG src="images/image24.jpg" border="0" width="518" height="492" alt="Fragment manifest editor" />
+</p>
+<p>Notice the tabbed pages corresponding to
+sections of the fragment xml file. We will
+be using the <b>Runtime</b> page to point the fragment
+classpath at the libraries containing our
+translations.</p>
+<p>We specified the nl1.jar in the new fragment wizard so that library is already
+ included in the classpath of this fragment. What is missing at this point is
+ the inclusion of the locale-specific folder. You can add new runtime libraries
+ by selecting <b>More</b> from the Runtime Libraries section of the Overview
+ page, or by turning to the Runtime page, selecting <b>New...</b>, then entering
+ $nl$/.</p>
+<p>
+<a name="f12"><b>Figure 12. Fragment runtime information</b></a><br /><IMG src="images/image25.jpg" border="0" width="502" height="317" alt="Fragment runtime information" />
+</p>
+<p>Taking a look at the Source page of the fragment
+manifest editor, we see that the PDE generates
+all the XML necessary to describe our plug-in
+fragment.</p>
+<p>
+<a name="f13"><b>Figure 13. Fragment source</b></a><br /><IMG src="images/image26.jpg" border="0" width="444" height="374" alt="Fragment source" />
+</p>
+<H4><a name="step6">Step 6. Prepare and send domestic language materials for translation</a></H4>
+<p><br />
+Producing correct translations requires specific skills, which you must purchase. (Unfortunately, your four years
+of high school German classes do not qualify you!) There are many
+companies that will gladly produce professional-quality translations.</p>
+<p>For the Eclipse Platform, this step was accomplished
+in two phases. The first phase involved sending
+all the externalized text to a translation
+center. This first-pass translation is done
+"out of context." The translator
+does not see the running product, nor do
+they have product-specific experience. They
+have tools at their disposal to help speed
+the translations and assure consistency,
+but ultimately they rely on translation testers
+to validate the running product in the target
+language (the second phase).</p>
+<p>The risk and consequences of performing an
+out-of-context translation, the results of
+which are sometimes quite amusing, are
+discussed in the follow-on article <a href="http://eclipse.org/articles/Article-TVT/how2TestI18n.html">How To Test your Internationalized Eclipse Plug-in</a>.</p>
+<H4><a name="step7">Step 7. Repackage and validate translated materials</a></H4>
+<p>Now having the translated files, we reassemble
+them in their appropriate directories/JAR
+files as described in step 5, <a href="#step5">Create initial translated plug-in fragment</a>. The NL1 Fragment folder contains
+language versions of the plugin.properties
+file. After translating the HelloWorld.properties
+file to German, we rename it to HelloWorld_de.properties
+and store it in the NL1 Fragment
+source folder. Note that the nl\de (German)
+folder is new and is created manually, not
+by the PDE. These language-specific folders
+segregate the versions of non-properties
+files (such as hello.xml shown
+below) as we add translations over time.</p>
+<p>
+<a name="f14"><b>Figure 14. Reassembled fragment project</b></a><br /><IMG src="images/nav3.jpg" border="0" width="326" height="323" alt="Reassembled fragment project" />
+</p>
+<p>Be aware that the translated properties files will very likely contain accented
+ characters that are codepage dependent, so properties files must be converted
+ to the ISO 8859-1 codepage expected by the <a href="http://java.sun.com/j2se/1.3/docs/api/java/util/PropertyResourceBundle.html">PropertyResourceBundle</a>
+ class. The native2ascii utility will handle codepage conversions and insert
+ any necessary Unicode escapes.</p>
+<p>The term <i>Unicode escape</i> deserves a bit more explanation.
+The native2ascii conversion utility, included
+with the Java SDK, accepts a source encoding
+and produces output encoded in ISO 8859-1,
+plus it transforms characters outside this
+codepage to the notation known as Unicode
+escapes. This notation is \udddd, where dddd
+= the codepoint of the desired character
+in the Unicode codepage.</p>
+<p>Here's an example. Consider
+the French phrase "Son p&#232;re est
+all&#233;&nbsp;&#224; l'h&#244;tel"
+(his father went to the hotel). This contains
+four accented characters that
+are not part of the Latin-1 codepage. Transforming
+this phrase with the native2ascii utility
+yields:
+<br />
+<br />
+<code>Son p\u00e8re est all\u00e9 \u00e0 h\u00f4tel</code>
+</p>
+<p>There are no longer any accented characters, and the resulting string is
+composed entirely of characters having codepoints that are found in ISO
+8859-1. But what are the <code>\u00e8</code>,
+<code>\u00e9</code>, <code>\u00e0</code>, and <code>\u00f4</code> that were substituted?
+They are the Unicode codepoints of the accented
+characters in \udddd notation.</p>
+<p>A little caveat when using the native2ascii utility:
+It assumes that the source encoding is the
+same as the active codepage of the machine
+that executes it. However, translators typically
+save the translations in their default country
+codepage, and this codepage is different
+in each country and each operating system.
+So the person responsible for integrating
+the translations will need to either (a)
+know in which codepage that the translators
+save their files, or (b) ask that they save
+it in a common codepage. You can specify
+the source encoding when invoking native2ascii
+with the<code>-encoding</code> parameter.</p>
+<p> <i>Tip:</i> If you are uncertain of the source codepage, you can spot-check
+ the output of native2ascii against <a href="#unicode_table">Unicode codepoints
+ of common accented Latin characters</a> table later in this article. If you
+ find \udddd notations in your converted files that are not in this table (such
+ as \u0205), it is likely that you specified the incorrect source encoding. There
+ is no equivalent spotcheck for DBCS languages, where practically all the characters
+ in the converted files are Unicode escapes. You simply have to be careful and
+ validate against the running product.</p>
+<p>Testing the translation merits its own article. The follow-on article <a href="http://eclipse.org/articles/Article-TVT/how2TestI18n.html">How to Test your Internationalized Eclipse Plug-in</a> describes the process and lessons learned during the recent translation verification of the Eclipse Platform, and includes a view (an Eclipse plug-in, of course!) for performing a quick check of property file translations.</p>
+<H4><a name="step8">Step 8. Deploy fragments</a></H4>
+<p>Fragment sources, similar to plug-in sources,
+may be packaged in a JAR file. Using the
+PDE to generate the JAR package, select the
+"fragment.xml" file and choose
+"<b>Create Fragment JARs...</b>&quot; from the pop-up menu. A wizard will guide you in creating a build script to produce all the required JARs for your fragment. If your <CODE>fragment.xml</CODE> file includes translatable strings, separate them into a <CODE>plugin.properties</CODE> file (just as you would for a plugin.xml file, i.e., there is no such thing as a &quot;fragment.properties&quot; file). This works because fragments are an extension of a plug-in and therefore inherits it dependencies, including its <CODE>plugin.properties</CODE> file values.</p>
+<p>
+<a name="f15"><b>Figure 15. Selecting the fragment.xml file</b></a><br /><IMG src="images/image28.jpg" border="0" width="320" height="241" alt="Selecting the fragment.xml file" />
+</p>
+<p>To deploy this example fragment, copy the fragment.xml, the \nl directory,
+and JAR to the com.jumpstart.example.helloworld.nl1 subdirectory in the
+plugins directory. This completes our example and the steps for internationalization.</p>
+<H3><a name="summary">Summary</a></H3>
+<p>Enabling your product for the world market simply makes economic sense. And
+ the steps above show that the process is relatively straightforward. Now here's
+ that quiz we mentioned in the introduction:</p>
+<blockquote>True or False: The majority of IBM's worldwide
+software sales revenue is within the United
+States.</blockquote>
+<p>
+False. Indeed, more than 50% of IBM software revenue
+comes from outside the United States.</p>
+<p>Fortunately,
+those developers with products based on the Eclipse platform
+benefit from having ready translations of
+the base product. All that is left is to
+follow the clear steps outlined in this article
+to open your Eclipse-based product to a worldwide
+market!</p>
+<H4><a name="glossary">Glossary</a></H4>
+<p>
+<i>Codepoint</i>
+<br />
+ Characters can be represented by one or more bytes of information. Codepoints
+ are the hexadecimal values assigned to each graphic character.</p>
+<p>
+<i>Codepage</i>
+<br />
+ A codepage is a specification of code points for each graphic character in
+ a set, or in a collection of graphic character sets. Within a given codepage,
+ a codepoint can have only one specific meaning. You can display the active
+ codepage on the Windows&#174; operating system with the CHCP command (only one codepage is active at any given moment).</p>
+<p>
+<i>Encoding</i>
+<br />
+ The codepage associated with a given piece of data. A file is said to be "encoded"
+ in a given code page; for example, Notepad will encode its data in code page
+ 437 on a US-English machine by default. The <b>Save As</b> dialog allows the
+ user to select several other possible encodings, Unicode and UTF-8 most notable
+ among them.</p>
+<p>
+<i>Internationalization (sometimes abbreviated "I18N")</i>
+<br />
+ Internationalization refers to the process of developing programs without prior
+ knowledge of the language, cultural data, or character encoding schemes they
+ are expected to handle. In system terms, it refers to the provision of interfaces
+ that enable internationalized programs to change their behavior at run time
+ for specific language operation.</p>
+<p>
+<i>Single-Byte Coded Character Set (SBCS)</i>
+<br />
+ In a single-byte coded character set, a one-byte codepoint represents
+ each character in the set. Typically, SBCS is used to represent the characters
+ of the English language, the European languages, the Cyrillic languages, the
+ Arabic language, and the Hebrew language, to name a few.</p>
+<p>
+<i>Double-Byte Coded Character Set (DBCS)</i>
+<br />
+ In a double-byte coded character set (DBCS), a two-byte codepoint represents
+ each character in the set. Languages that are ideographic in nature, such as
+ Japanese, Chinese, and Korean, have more characters than can be represented
+ internally by 256 code points and thus require double-byte coded character sets.</p>
+<p>
+<i>Localization (sometimes abbreviated "L10N")</i>
+<br />
+ Localization refers to the process of establishing information within a computer
+ system specific to each supported language, cultural data, and coded character
+ set combination.</p>
+<p>
+<i>Mixed-Byte Character Set</i>
+<br />
+ A mixed-byte coded character set is a set of characters containing both single-byte
+ characters and double-byte characters. On the MBCS, each byte of data must be
+ examined to see if it is the first byte of a double-byte or single-byte character.
+ If the byte is in a certain range (greater than X'80', for example), then it
+ is the first byte of a double-byte character.</p>
+<p>
+<i>NLS</i>
+<br />
+ National Language Support.</p>
+<p>
+<i>Unicode</i>
+<br />
+ Directly from <A href="http://www.unicode.org">http://www.unicode.org</A>: "Unicode
+ provides a unique number for every character, no matter what the platform, no
+ matter what the program, no matter what the language."
+<br />Note: While it is true that Java text manipulation classes are Unicode-centric,
+ this is often not the case for data stored outside of your program's auspices.
+ Java programmers must take into consideration the data encoding by performing
+ local codepage-to-Unicode transformations where necessary.</p>
+<H4><a name="unicode_table">Unicode codepoints of common accented Latin characters</a></H4>
+<table width="39%" border="1" cellpadding="0" cellspacing="0">
+
+
+ <tr bgcolor="#CCCCCC">
+ <td colspan="2">
+ <div align="center"><b>Characters</b></div>
+ </td>
+ </tr>
+ <tr>
+ <td width="48%">\u00e0 </td>
+ <td width="52%">a grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00e1</td>
+ <td width="52%"> a acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00c0 </td>
+ <td width="52%">A grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00c1 </td>
+ <td width="52%">A acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00c2 </td>
+ <td width="52%">A circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00e2</td>
+ <td width="52%">a circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00c3 </td>
+ <td width="52%">A tilde</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00e4 </td>
+ <td width="52%">a dieresis</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00c4 </td>
+ <td width="52%">A dieresis</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00e8 </td>
+ <td width="52%">e grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00c8 </td>
+ <td width="52%">E grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00e9 </td>
+ <td width="52%">e acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00c9 </td>
+ <td width="52%">E acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ea </td>
+ <td width="52%">e circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00eb </td>
+ <td width="52%">e dieresis</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00cb </td>
+ <td width="52%">E dieresis</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ea </td>
+ <td width="52%">e circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ca </td>
+ <td width="52%">E circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ef </td>
+ <td width="52%">i dieresis</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ec</td>
+ <td width="52%"> i grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ed </td>
+ <td width="52%">i acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00cc</td>
+ <td width="52%"> I grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00cd </td>
+ <td width="52%">I acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ee </td>
+ <td width="52%">i circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ce </td>
+ <td width="52%">I circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00f6 </td>
+ <td width="52%">o dieresis</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00d6 </td>
+ <td width="52%">O dieresis</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00e3 </td>
+ <td width="52%">a tilde</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00f4 </td>
+ <td width="52%">o circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00d4 </td>
+ <td width="52%">O circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00f2 </td>
+ <td width="52%">o grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00d2 </td>
+ <td width="52%">O grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00f3 </td>
+ <td width="52%">o acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00d3 </td>
+ <td width="52%">O acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00f5 </td>
+ <td width="52%">o tilde</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00d5 </td>
+ <td width="52%">O tilde</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00f1 </td>
+ <td width="52%">n tilde</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00d1 </td>
+ <td width="52%">N tilde</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00f9 </td>
+ <td width="52%">u grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00d9 </td>
+ <td width="52%">U grave</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00fa </td>
+ <td width="52%">u acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00da </td>
+ <td width="52%">U acute</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00fb </td>
+ <td width="52%">u circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00db </td>
+ <td width="52%">U circumflex</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00fc </td>
+ <td width="52%">u dieresis</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00dc </td>
+ <td width="52%">U dieresis</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00df </td>
+ <td width="52%">s sharp</td>
+ </tr>
+ <tr bgcolor="#CCCCCC">
+ <td colspan="2">
+ <div align="center"><b>Special symbols</b></div>
+ </td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ba </td>
+ <td width="52%">masculine ordinal indicator</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00a7 </td>
+ <td width="52%">section sign</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00aa </td>
+ <td width="52%">feminine ordinal indicator</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00ac </td>
+ <td width="52%">not sign</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00b9 </td>
+ <td width="52%">1 superscript</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00b2 </td>
+ <td width="52%">2 superscript</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00b3 </td>
+ <td width="52%">3 superscript</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00a3 </td>
+ <td width="52%">pound sign</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00a2 </td>
+ <td width="52%">cents sign</td>
+ </tr>
+ <tr>
+ <td width="48%">\u00b0 </td>
+ <td width="52%">degree sign</td>
+ </tr>
+
+
+</table>
+<h3><A name="authors" />About the authors</A><A name="authors" /><BR><BR>
+</A></H3>
+<P><A name="authors" /><B>Dan Kehn</B> is a Senior Software Engineer at IBM in
+ Research Triangle Park, North Carolina.
+ His
+ interests in object-oriented programming
+ go back to 1985, long before it enjoyed
+ the
+ acceptance it has today. He has a broad
+ range
+ of software experience, having worked
+ on
+ development tools like VisualAge for
+ Smalltalk,
+ operating system performance and memory
+ analysis,
+ and user interface design. Dan worked
+ as
+ a consultant for object-oriented development
+ projects throughout the U.S. as well
+ as four
+ years in Europe. His recent interests
+ include
+ object-oriented analysis/design, programming
+ tools, and Web programming with the
+ WebSphere
+ Application Server. Last year he joined
+ the
+ Eclipse Jumpstart team, whose primary
+ goal
+ is to help ISVs to create commercial
+ offerings
+ based on the Eclipse Platform. In another
+ life, Dan authored several articles
+ about
+ diverse Smalltalk topics like meta-programming,
+ team development, and memory analysis.
+ You
+ can find them on</A>
+<A href="http://www.ibm.com/software/ad/smalltalk/discussion/index.html">Eye on SmallTalk</A>.
+
+<P><B>Scott Fairbrother</B> works on the Eclipse Jumpstart team at IBM in Research Triangle Park,
+North Carolina. He is a software developer with over 20 years of experience.
+He has developed object-oriented application frameworks for business process
+management. He has written specifications for IBM middleware on Windows
+2000 and has also authored on the subject of Microsoft Visual Studio .NET.</P>
+<P><A name="authors" /><B>Cam-Thu Le</B> joined IBM in 1983. Cam's experience spans
+ many aspects of software creation:
+development,
+ testing, and National Language Support
+(NLS)
+ planning and coordination. Cam has
+led the
+ National Language versions of IBM products
+ to worldwide concurrent general availability,
+ including the 4690 Point of Sales product
+ and VisualAge for Smalltalk. Cam joined
+the
+ Eclipse Project last year as the NLS
+focal
+ point. Cam coordinated the building
+and testing
+ of the NL versions of the Eclipse Workbench
+ and WebSphere Studio Workbench.</A>
+
+
+</BODY>
+</html>
diff --git a/Article-Internationalization/images/Idea.jpg b/Article-Internationalization/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Internationalization/images/Idea.jpg
Binary files differ
diff --git a/Article-Internationalization/images/envelope.jpg b/Article-Internationalization/images/envelope.jpg
new file mode 100644
index 0000000..57f72ea
--- /dev/null
+++ b/Article-Internationalization/images/envelope.jpg
Binary files differ
diff --git a/Article-Internationalization/images/fraggen1.jpg b/Article-Internationalization/images/fraggen1.jpg
new file mode 100644
index 0000000..e7d4335
--- /dev/null
+++ b/Article-Internationalization/images/fraggen1.jpg
Binary files differ
diff --git a/Article-Internationalization/images/fraggen2.jpg b/Article-Internationalization/images/fraggen2.jpg
new file mode 100644
index 0000000..6d4ea9e
--- /dev/null
+++ b/Article-Internationalization/images/fraggen2.jpg
Binary files differ
diff --git a/Article-Internationalization/images/fraggen3.jpg b/Article-Internationalization/images/fraggen3.jpg
new file mode 100644
index 0000000..50fdba8
--- /dev/null
+++ b/Article-Internationalization/images/fraggen3.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image2.jpg b/Article-Internationalization/images/image2.jpg
new file mode 100644
index 0000000..30e074d
--- /dev/null
+++ b/Article-Internationalization/images/image2.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image20.jpg b/Article-Internationalization/images/image20.jpg
new file mode 100644
index 0000000..337b5f6
--- /dev/null
+++ b/Article-Internationalization/images/image20.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image23.jpg b/Article-Internationalization/images/image23.jpg
new file mode 100644
index 0000000..fa732c0
--- /dev/null
+++ b/Article-Internationalization/images/image23.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image24.jpg b/Article-Internationalization/images/image24.jpg
new file mode 100644
index 0000000..34215e5
--- /dev/null
+++ b/Article-Internationalization/images/image24.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image25.jpg b/Article-Internationalization/images/image25.jpg
new file mode 100644
index 0000000..4089cb6
--- /dev/null
+++ b/Article-Internationalization/images/image25.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image26.jpg b/Article-Internationalization/images/image26.jpg
new file mode 100644
index 0000000..dbcdb21
--- /dev/null
+++ b/Article-Internationalization/images/image26.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image28.jpg b/Article-Internationalization/images/image28.jpg
new file mode 100644
index 0000000..7c17770
--- /dev/null
+++ b/Article-Internationalization/images/image28.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image6.jpg b/Article-Internationalization/images/image6.jpg
new file mode 100644
index 0000000..a501b9f
--- /dev/null
+++ b/Article-Internationalization/images/image6.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image7.jpg b/Article-Internationalization/images/image7.jpg
new file mode 100644
index 0000000..8458b33
--- /dev/null
+++ b/Article-Internationalization/images/image7.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image8.jpg b/Article-Internationalization/images/image8.jpg
new file mode 100644
index 0000000..542f002
--- /dev/null
+++ b/Article-Internationalization/images/image8.jpg
Binary files differ
diff --git a/Article-Internationalization/images/image9.jpg b/Article-Internationalization/images/image9.jpg
new file mode 100644
index 0000000..04a5f6c
--- /dev/null
+++ b/Article-Internationalization/images/image9.jpg
Binary files differ
diff --git a/Article-Internationalization/images/linux_only.gif b/Article-Internationalization/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Internationalization/images/linux_only.gif
Binary files differ
diff --git a/Article-Internationalization/images/mailbox.jpg b/Article-Internationalization/images/mailbox.jpg
new file mode 100644
index 0000000..a2260df
--- /dev/null
+++ b/Article-Internationalization/images/mailbox.jpg
Binary files differ
diff --git a/Article-Internationalization/images/nav3.jpg b/Article-Internationalization/images/nav3.jpg
new file mode 100644
index 0000000..035d74e
--- /dev/null
+++ b/Article-Internationalization/images/nav3.jpg
Binary files differ
diff --git a/Article-Internationalization/images/never.jpg b/Article-Internationalization/images/never.jpg
new file mode 100644
index 0000000..b723589
--- /dev/null
+++ b/Article-Internationalization/images/never.jpg
Binary files differ
diff --git a/Article-Internationalization/images/route66.jpg b/Article-Internationalization/images/route66.jpg
new file mode 100644
index 0000000..6a40319
--- /dev/null
+++ b/Article-Internationalization/images/route66.jpg
Binary files differ
diff --git a/Article-Internationalization/images/skip.jpg b/Article-Internationalization/images/skip.jpg
new file mode 100644
index 0000000..e88235e
--- /dev/null
+++ b/Article-Internationalization/images/skip.jpg
Binary files differ
diff --git a/Article-Internationalization/images/tag_1.gif b/Article-Internationalization/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Internationalization/images/tag_1.gif
Binary files differ
diff --git a/Article-Internationalization/images/tag_2.gif b/Article-Internationalization/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Internationalization/images/tag_2.gif
Binary files differ
diff --git a/Article-Internationalization/images/tag_3.gif b/Article-Internationalization/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Internationalization/images/tag_3.gif
Binary files differ
diff --git a/Article-Internationalization/images/tag_4.gif b/Article-Internationalization/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Internationalization/images/tag_4.gif
Binary files differ
diff --git a/Article-Internationalization/images/tag_5.gif b/Article-Internationalization/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Internationalization/images/tag_5.gif
Binary files differ
diff --git a/Article-Internationalization/images/tag_6.gif b/Article-Internationalization/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Internationalization/images/tag_6.gif
Binary files differ
diff --git a/Article-Internationalization/images/tag_7.gif b/Article-Internationalization/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Internationalization/images/tag_7.gif
Binary files differ
diff --git a/Article-Internationalization/images/tip.gif b/Article-Internationalization/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Internationalization/images/tip.gif
Binary files differ
diff --git a/Article-Internationalization/images/translate.jpg b/Article-Internationalization/images/translate.jpg
new file mode 100644
index 0000000..473599c
--- /dev/null
+++ b/Article-Internationalization/images/translate.jpg
Binary files differ
diff --git a/Article-Internationalization/images/tryit.gif b/Article-Internationalization/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Internationalization/images/tryit.gif
Binary files differ
diff --git a/Article-Internationalization/images/win_only.gif b/Article-Internationalization/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Internationalization/images/win_only.gif
Binary files differ
diff --git a/Article-JET/default_style.css b/Article-JET/default_style.css
new file mode 100644
index 0000000..24c7629
--- /dev/null
+++ b/Article-JET/default_style.css
@@ -0,0 +1,24 @@
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt; color:#4444cc}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
+.jet { background-color: #FFFFCC}
+
+li p { margin-top: 10px; margin-bottom: 10px; }
+
+a.footnote:link { text-decoration: none; }
+a.footnote:visited { text-decoration: none; }
+a.footnote:hover { text-decoration: underline; }
+
+tt.code { color: #4444CC; }
+pre.code { color: #4444CC; }
+
+.highlight { background-color: #FFFFCC; }
+
diff --git a/Article-JET/images/Idea.jpg b/Article-JET/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-JET/images/Idea.jpg
Binary files differ
diff --git a/Article-JET/images/addJetNaturePopup.gif b/Article-JET/images/addJetNaturePopup.gif
new file mode 100644
index 0000000..cd086b9
--- /dev/null
+++ b/Article-JET/images/addJetNaturePopup.gif
Binary files differ
diff --git a/Article-JET/images/compiledTemplate.gif b/Article-JET/images/compiledTemplate.gif
new file mode 100644
index 0000000..949d12b
--- /dev/null
+++ b/Article-JET/images/compiledTemplate.gif
Binary files differ
diff --git a/Article-JET/images/generator_skeleton.gif b/Article-JET/images/generator_skeleton.gif
new file mode 100644
index 0000000..45c20b4
--- /dev/null
+++ b/Article-JET/images/generator_skeleton.gif
Binary files differ
diff --git a/Article-JET/images/jetWizard.gif b/Article-JET/images/jetWizard.gif
new file mode 100644
index 0000000..0ea9684
--- /dev/null
+++ b/Article-JET/images/jetWizard.gif
Binary files differ
diff --git a/Article-JET/images/linux_only.gif b/Article-JET/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-JET/images/linux_only.gif
Binary files differ
diff --git a/Article-JET/images/missing_jet_directive.gif b/Article-JET/images/missing_jet_directive.gif
new file mode 100644
index 0000000..8491e01
--- /dev/null
+++ b/Article-JET/images/missing_jet_directive.gif
Binary files differ
diff --git a/Article-JET/images/newproject.gif b/Article-JET/images/newproject.gif
new file mode 100644
index 0000000..2b123ac
--- /dev/null
+++ b/Article-JET/images/newproject.gif
Binary files differ
diff --git a/Article-JET/images/projectProperties.gif b/Article-JET/images/projectProperties.gif
new file mode 100644
index 0000000..351a28c
--- /dev/null
+++ b/Article-JET/images/projectProperties.gif
Binary files differ
diff --git a/Article-JET/images/tag_1.gif b/Article-JET/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-JET/images/tag_1.gif
Binary files differ
diff --git a/Article-JET/images/tag_2.gif b/Article-JET/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-JET/images/tag_2.gif
Binary files differ
diff --git a/Article-JET/images/tag_3.gif b/Article-JET/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-JET/images/tag_3.gif
Binary files differ
diff --git a/Article-JET/images/tag_4.gif b/Article-JET/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-JET/images/tag_4.gif
Binary files differ
diff --git a/Article-JET/images/tag_5.gif b/Article-JET/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-JET/images/tag_5.gif
Binary files differ
diff --git a/Article-JET/images/tag_6.gif b/Article-JET/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-JET/images/tag_6.gif
Binary files differ
diff --git a/Article-JET/images/tag_7.gif b/Article-JET/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-JET/images/tag_7.gif
Binary files differ
diff --git a/Article-JET/images/tip.gif b/Article-JET/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-JET/images/tip.gif
Binary files differ
diff --git a/Article-JET/images/tryit.gif b/Article-JET/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-JET/images/tryit.gif
Binary files differ
diff --git a/Article-JET/images/win_only.gif b/Article-JET/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-JET/images/win_only.gif
Binary files differ
diff --git a/Article-JET/jet_tutorial1.html b/Article-JET/jet_tutorial1.html
new file mode 100644
index 0000000..5f4f19d
--- /dev/null
+++ b/Article-JET/jet_tutorial1.html
@@ -0,0 +1,644 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>JET Tutorial Part 1 (Introduction to JET)</title>
+<link rel="stylesheet" href="default_style.css">
+</head>
+
+<body lang="EN-US" xml:lang="EN-US">
+
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">&copy;
+ Copyright <a href="http://www.azzurri.jp">Azzurri Ltd.</a> 2003, 2004. All rights
+ reserved</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" align=CENTER width="120" height="86"></h1>
+</div>
+
+<h1 align="CENTER">JET Tutorial Part 1 (Introduction to JET) </h1>
+
+<blockquote>
+<b>Summary</b>
+
+<br/>
+<p>
+ Generating source code can save you time in your projects and can reduce the
+ amount of tedious redundant programming. Generating source code can be powerful,
+ but the program that writes the code can quickly become very complex and hard
+ to understand. One way to reduce complexity and increase readability is to use
+ templates. </p>
+ <p> The Eclipse Modeling Framework (<a href="http://www.eclipse.org/emf/" target="_blank">EMF</a>)
+ project contains two very powerful tools for generating source code: JET (Java
+ Emitter Templates) and JMerge (Java Merge). With JET you can use a JSP-like
+ syntax (actually a subset of the JSP syntax) that makes it easy to write templates
+ that express the code you want to generate. JET is a generic template engine
+ that can be used to generate SQL, XML, Java source code and other output from
+ templates. It is located in the org.eclipse.emf.codegen plug-in as part of
+ the EMF runtime download. </p>
+
+ <p>
+ In this article you will learn how to create JET templates, how to use the JET
+ Nature and JET Builder to automatically translate templates into Java classes,
+ and how to use these classes to generate source code. This article also provides
+ a short reference to the JET syntax.
+ </p>
+ <p>Contributed by Remko Popma, Azzurri Ltd., remko.popma at azzurri dot jp,
+ July 30, 2003. Last update: May 31, 2004 for EMF 2.0 (Eclipse 3.0).</p>
+</blockquote>
+
+<hr width="100%" />
+
+<h2>Getting Started</h2>
+<p>Before creating our first template, you'll need the EMF plug-in version 2.0.
+ If you haven't installed it yet, install it now before continuing with this
+ tutorial.</p>
+
+<p>A JET template is a text file with a file name that ends with &quot;jet&quot;.
+ I will follow the EMF convention of appending &quot;jet&quot; to whatever the
+ file extension of the generated code would be, so <i>.javajet</i> implies that
+ the template generates a .java file, <i>.xmljet</i> templates generate XML,
+ templates that generate SQL have the <i>.sqljet</i> extension, and so on.</p>
+<h3> JET Nature and JET Builder </h3>
+
+<p>
+Let's follow tradition and start with a template that creates the message &quot;Hello,
+world&quot;. We will create our first template using the following four step process: </p>
+<ol>
+ <li> Create a new Java project and give it a &quot;<i>src</i>&quot; source folder</li>
+ <li> Add the JET Nature to the project. This will create a folder called &quot;<i>templates</i>&quot;
+ under the project root</li>
+
+ <li> Change the JET properties of the project to ensure that templates are translated
+ into the &quot;<i>src</i>&quot; source folder of the project</li>
+ <li> Create a new file called &quot;<i>helloworld.txtjet</i>&quot; and save
+ it in the <i>templates</i> folder</li>
+
+</ol>
+
+<h4> Step 1. Create a Project </h4>
+From the workbench menu, select File &gt; New &gt; Project to bring up the New
+Project wizard. Create a new Java project and add a source folder to it named
+<i>src</i>.
+<h4> Step 2. Convert the Project to a JET Project</h4>
+<p>After creating the project, right-click on it in the Package Explorer or Hierarchy
+ view and select New &gt; Other... &gt; Java Emitter Templates &gt; Convert Projects to JET Projects. After pressing the Next button, select
+ the project you've created and click Finish.</p>
+
+<img src="images/jetWizard.gif"/>
+
+<p> The wizard adds the JET Nature to the project creating a <i>templates</i> folder
+ under the project root as shown in the image below. Also, a JET Builder is added
+ to the project that will automatically translate every file in the templates
+ folder with a file name ending in &quot;jet&quot; to a Java class. </p>
+<p> <img src="images/newproject.gif" border="1"/></p>
+<h4> Step 3. Change JET Settings </h4>
+<p> Before creating our first template, let's make sure that the <i>src</i> source
+ folder of the project is the destination folder of the translated templates.
+ Right-click on the project and select &quot;Properties&quot; from the popup
+ menu. In the Project Properties dialog, select JET Settings on the left-hand
+ menu and enter &quot;src&quot; (the name of your source folder) in the &quot;Source
+ Container&quot; text field. The image below shows the JET Settings properties
+ page of the Project Properties dialog. </p>
+
+<p>
+<img src="images/projectProperties.gif"/>
+</p>
+<p> <i><img src="images/tip.gif" width="62" height="13"/>Note: you can specify
+ multiple folders in the Template Containers field, separated by a space or a
+ semicolon. However, if templates in different folders have the same filename,
+ only the template in the first folder will be translated automatically by the
+ JET Builder. If you want all templates to be translated, make sure they have
+ different file names.</i></p>
+<h4> Step 4. Create a JET Template File </h4>
+<p> The JET builder will now translate all templates to Java source files in the
+ <i>src</i> folder of the project. Now we create our first template. From the
+ workbench menu, select File &gt; New &gt; File to bring up the New File wizard.
+ Select the <i>templates</i> directory as the parent folder, and call the file
+ <i>helloworld.txtjet</i>. You will get the following error when you press the
+ OK button: &quot;The jet directive is missing in 'helloworld.txtjet' at line
+ 1 column 1&quot;, as shown in the image below. </p>
+
+<p>
+<img src="images/missing_jet_directive.gif"/>
+</p>
+<p> Fortunately, this does not mean that there is a real problem, just that the
+ JET Builder tried to translate our template as soon as we created it, and discovered
+ that it is still empty. Press Close to close the error dialog. Open the <i>helloworld.txtjet</i> file
+ if it is not opened and type or cut-and-paste the following contents in the editor. </p>
+<pre class="code">
+ <span class="highlight">&lt;%@ jet package=&quot;hello&quot; class=&quot;HelloWorldTemplate&quot; %&gt;</span>
+
+ Hello, world!</pre>
+<p> When you save the template file, it will automatically be translated by the
+ JET Builder. Because we specified package <i>hello</i> and class <i>HelloWorldTemplate</i>
+ in the first line of the template, the builder creates a <i>hello</i> package
+ in the <i>src</i> folder and saves a Java file <i>HelloWorldTemplate.java</i>
+ in this package, as shown in the image below.</p>
+
+<p> <img src="images/compiledTemplate.gif" border="1"/>
+</p>
+<p> This Java class is the result of translating the template and is called a
+ <i>template implementation class</i>. This class has a method called <tt class="code">generate</tt>.
+ This is the method that generates the code indicated in the template.</p>
+<p><img src="images/tryit.gif" width="61" height="13"/>We can create an instance
+ of the <tt class="code">HelloWorldTemplate</tt> template implementation class and invoke
+ its <tt class="code">generate</tt> method like this: </p>
+
+<pre class="code"> HelloWorldTemplate helloworld = new HelloWorldTemplate();
+ String result = helloworld.generate(null);
+ System.out.println(result);
+</pre>
+<p> The code above will print the words &quot;Hello, world!&quot; to the console.
+ Yay!</p>
+<h3> Passing Arguments to the Template </h3>
+<p>To recap, we just created our first template and generated some code with it.
+ The result may not have been very impressive, but now we are all set up and
+ we can start to explore what JET can do for you. The next step is to pass an
+ argument to the template. </p>
+<p><img src="images/tryit.gif" width="61" height="13"/>Add a new JET template file
+ or change the existing one to the following content: </p>
+<pre class="code">
+
+ <span class="highlight">&lt;%@ jet package=&quot;hello&quot; class=&quot;GreetingTemplate&quot; %&gt;</span>
+ Hello, <span class="highlight">&lt;%=argument%&gt;</span>!
+</pre>
+<p> The JET Builder will translate this template to a class <tt class="code">GreetingTemplate</tt>
+ in the <tt class="code">hello</tt> package. Again we create an instance of this template
+ class, but this time we pass a string argument to the <tt class="code">generate</tt> method:
+
+</p>
+<pre class="code"> GreetingTemplate sayHello = new GreetingTemplate();
+ String result = sayHello.generate(&quot;Tutorial Reader&quot;);
+ System.out.println(result);
+</pre>
+<p>
+The code above will print the words &quot;Hello, Tutorial Reader!&quot; to the
+console.
+</p>
+<h3> Importing Packages </h3>
+<p>The argument you pass to a template can be any object. In the previous example
+ we passed a string as the argument to the generate method, but in your application
+ you probably want to pass in your own model object. If the argument is not in
+ the <tt class="code">java.lang</tt> package, or if your template uses any other classes not
+ in the <tt class="code">java.lang</tt> package, you need to import these classes in the template
+ <tt class="code">jet</tt> directive. A <tt class="code">jet</tt> directive with an <img src="images/tag_1.gif" width="24" height="13"/><i>imports</i>
+ attribute looks like this: </p>
+
+<pre class="code">
+ &lt;%@ jet package=&quot;hello&quot; <b><img src="images/tag_1.gif" width="24" height="13"/>imports=&quot;java.util.*&quot;</b> class=&quot;ImportDemoTemplate&quot; %&gt;
+</pre>
+<p> The JET Syntax Reference section of this article gives more details on the
+ <tt class="code">jet</tt> directive and its attributes.</p>
+
+<p> In the next example we will create a template that generates XML code. To
+ stick to the EMF convention of appending &quot;jet&quot; to whatever the file
+ extension of the generated code would be, we will save this template to a file
+ called <i>importdemo.xmljet</i>. Note that we pass the template a <tt class="code">java.util.List</tt>
+ object that contains the data to use when generating the XML.</p>
+<pre class="code">
+ <span class="highlight">&lt;%@ jet package=&quot;hello&quot; <img src="images/tag_1.gif" width="24" height="13"/><b>imports=&quot;java.util.*&quot;</b> class=&quot;XMLDemoTemplate&quot; %&gt;</span>
+
+<img src="images/tag_2.gif" width="24" height="13"/><b class="highlight">&lt;% List elementList = (List) argument; %&gt;</b>
+ <b> </b>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+ <b> </b>&lt;demo&gt;
+ <span class="highlight">&lt;% for (Iterator i = elementList.iterator(); i.hasNext(); ) { %&gt;</span>
+
+ &lt;element&gt;<span class="highlight">&lt;%=i.next().toString()%&gt;</span>&lt;/element&gt;
+ <span class="highlight">&lt;% } %&gt;</span>
+ <b> </b>&lt;/demo&gt;
+</pre>
+<p> The code below shows how to invoke the template instance. We create a <img src="images/tag_2.gif" width="24" height="13"/>list
+ and <img src="images/tag_3.gif" width="24" height="13"/>pass it to the <tt class="code">generate</tt>
+ method of the template implementation class:</p>
+
+<pre class="code"><img src="images/tag_2.gif" width="24" height="13"/>List data = new ArrayList();
+ data.add(&quot;first&quot;);
+ data.add(&quot;second&quot;);
+ data.add(&quot;third&quot;);
+
+ XMLDemoTemplate generateXml = new XMLDemoTemplate();
+ String result = generateXml.generate(<img src="images/tag_3.gif" width="24" height="13"/>data);
+ System.out.println(result);
+</pre>
+<p>
+This prints the following XML result to the console:
+</p>
+<pre class="code">
+ &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+
+ &lt;demo&gt;
+ &lt;element&gt;first&lt;/element&gt;
+ &lt;element&gt;second&lt;/element&gt;
+ &lt;element&gt;third&lt;/element&gt;
+
+ &lt;/demo&gt;
+</pre>
+<p> This is a very simple example that creates very simple XML. Of course you
+ can use JET to create more complex XML, using attributes and namespaces. When
+ you do this, you may find it more convenient to create a special class that
+ is a better model of an XML document than a <tt class="code">java.util.List</tt>. Generally,
+ the more complex your JET template becomes, the more logic you will want to
+ push into the model object that you pass to the template, to keep your templates
+ readable. We will explore this further in Part 2 of this tutorial. </p>
+<h3> Changing Tags </h3>
+<p>A neat feature of JET is that you can change the tags that mark scriptlets
+ in the template file. This is very convenient when the syntax of the code you
+ generate is very similar to the default JET syntax, for example if you use JET
+ to generate JSP pages. </p>
+<p>In the next example we will use JET to generate a simple JSP page. We will
+ change the JET tags to use the &quot;&lt;$&quot; character sequence to start
+ a template tag, and &quot;$&gt;&quot; to end a template tag. The template still
+ contains &quot;&lt;%&quot; and &quot;%&gt;&quot; strings, but the JET engine
+ will not see them as special anymore, and they will be written to the result
+ like any other character sequence.</p>
+
+<p></p>
+<p> <img src="images/tryit.gif" width="61" height="13"/>To change the tag markers,
+ add a <i><img src="images/tag_1.gif" width="24" height="13"/>startTag</i> and
+ an <i><img src="images/tag_2.gif" width="24" height="13"/>endTag</i> attribute
+ to the JET directive on the first line of the template, like in the example
+ below. </p>
+<pre class="code">
+ <span class="highlight">&lt;%@ jet package=&quot;tags.demo&quot; class=&quot;JspTemplate&quot; <img src="images/tag_1.gif" width="24" height="13"/><b>startTag=&quot;&lt;$&quot; <img src="images/tag_2.gif" width="24" height="13"/>endTag=&quot;$&gt;&quot;</b> %&gt;</span>
+
+ <b><span class="highlight">&lt;$</span></b><span class="highlight"> String paramName = (String) argument; /* This is an executed scriptlet */ <b>$&gt;</b></span>
+ <b><span class="highlight">&lt;$</span></b><span class="highlight"> if (paramName != null) { <b>$&gt;</b></span>
+ <img src="images/tag_3.gif" width="24" height="13"/> &lt;%= request.getParameter(&quot;<b><span class="highlight">&lt;$=</span></b><span class="highlight">paramName<b>$&gt;</b></span>&quot;) %&gt; &lt;!-- this is generated JSP --&gt;
+
+ <b><span class="highlight">&lt;$</span></b><span class="highlight"> } <b>$&gt;</b></span>
+</pre>
+<p> Again, we invoke this implementation class with a string argument, like below:
+</p>
+<pre class="code"> System.out.println(new tags.demo.JspTemplate().generate(&quot;button&quot;));
+</pre>
+The following output will appear on the console. Note that the output contains
+the intact JSP tag: the &quot;&lt;%&quot; and &quot;%&gt;&quot; character strings
+are not interpreted as a JET scriptlet, but are simply inserted in the generated
+code.
+
+<pre class="code">
+ <img src="images/tag_3.gif" width="24" height="13"/> &lt;%= request.getParameter(&quot;button&quot;) %&gt; &lt;!-- this is generated JSP --&gt;
+</pre>
+<h1> Under the Hood </h1>
+<p>In the previous section we have looked at creating JET templates, how to set up
+the JET Nature to automatically translate templates into Java implementation classes,
+and how to use these Java implementation classes to generate code.
+</p>
+<p> In this section we will take a closer look at the Java implementation classes
+ that are the result of translating a template. We will see why we can use the
+ implicit objects <tt class="code">argument</tt> and <tt class="code">stringBuffer</tt> in a template,
+ and also look at customizing the translated implementation class by providing
+ a custom &quot;skeleton&quot;. </p>
+
+<h3> Translated Templates </h3>
+<p>A JET template is translated to a Java implementation class. There are some
+ objects in the Java implementation class that can be referenced directly in
+ the JET template. The following example demonstrates how the implicit objects
+ <tt class="code">argument</tt> and <tt class="code">stringBuffer</tt> can be used in a template.</p>
+<pre class="code">
+ <span class="highlight">&lt;%@ jet package=&quot;hello&quot; class=&quot;TranslationDemoTemplate&quot; %&gt;</span>
+
+<img src="images/tag_1.gif" width="24" height="13"/> Hello, <span class="highlight">&lt;%=<b>argument</b>%&gt;</span>!
+<img src="images/tag_2.gif" width="24" height="13"/> <span class="highlight">&lt;% <b>stringBuffer.append(&quot;Hello again!&quot;);</b> %&gt;</span>
+</pre>
+<p> The template above is translated to a Java implementation class like below:
+
+</p>
+<pre class="code">
+ package hello;
+
+ public class TranslationDemoTemplate
+ {
+ protected final String NL = System.getProperties().getProperty(&quot;line.separator&quot;);
+ protected final String TEXT_1 = &quot;Hello, &quot;;
+ protected final String TEXT_2 = &quot;!&quot;;
+
+ public String generate(Object <b>argument</b>)
+ {
+ StringBuffer <b>stringBuffer</b> = new StringBuffer();
+ stringBuffer.append(TEXT_1);
+<img src="images/tag_1.gif" width="24" height="13"/> stringBuffer.append(<b>argument</b>);
+ stringBuffer.append(TEXT_2);
+
+<img src="images/tag_2.gif" width="24" height="13"/> <b>stringBuffer.append(&quot;Hello again!&quot;);</b>
+ return stringBuffer.toString();
+ }
+ }
+</pre>
+<p> Notice that the <tt class="code">generate</tt> method of the Java implementation class
+ takes an <tt class="code">Object</tt> parameter called <tt class="code">argument</tt>. This is the same
+ object as the <tt class="code"><img src="images/tag_1.gif" width="24" height="13"/>argument</tt>
+ in the second line of the template. Also, notice how the Java implementation
+ class uses a <tt class="code">StringBuffer</tt> object to collect the resulting generated
+ code. This object can be <img src="images/tag_2.gif" width="24" height="13"/>referenced
+ directly in the template by its name <tt class="code">stringBuffer</tt>. </p>
+
+<h3> Changing the Skeleton of the Translated Implementation Class </h3>
+<p>The <tt class="code">generate</tt> method of the <tt class="code">TranslationDemoTemplate</tt> class
+ above is said to be part of the implementation class &quot;skeleton&quot;. The
+ default skeleton used by the JET engine looks like this: </p>
+<pre class="code">
+ public class CLASS
+ {
+ public String generate(Object argument)
+ {
+ return &quot;&quot;;
+ }
+ }
+
+</pre>
+<p> The skeleton definition looks almost like a normal Java class, except for
+ the class name. The class name (<tt class="code">CLASS</tt>) will be replaced by the value
+ of the <i>class</i> attribute in the <tt class="code">jet</tt> directive. Furthermore, the skeleton
+ definition has the <tt class="code">generate</tt> method that we have seen earlier. By changing
+ the skeleton you can customize a template implementation class, for example
+ make it implement an interface, or change any other feature of the class.</p>
+<p> <img src="images/tryit.gif" width="61" height="13"/>For example, suppose you
+ want all your template implementation classes to implement an interface. The
+ interface could look something like this: </p>
+
+<pre class="code">
+ public interface IGenerator {
+ String generate(Object argument);
+ }</pre>
+<p>We can tell the JET engine that we want to use a custom skeleton by setting
+ the <i>skeleton</i> attribute of the <tt class="code">jet</tt> directive on the first line of the
+ template file. The value of the skeleton attribute is a URI that points to a
+ file where the custom skeleton definition can be found. </p>
+<p>To try this, first create a new file <i>generator.skeleton</i> in the templates
+ directory, as in the image below.</p>
+
+<p><img src="images/generator_skeleton.gif" border="1"/></p>
+<p>Open the <i>generator.skeleton</i> file in a text editor and type or cut-and-paste
+ the following content in it: </p>
+<pre class="code">
+ public class CLASS <img src="images/tag_1.gif" width="24" height="13"/>implements IGenerator
+ {
+<img src="images/tag_2.gif" width="24" height="13"/>/* (non-javadoc)
+ * @see IGenerator#generate(Object)
+ */
+<img src="images/tag_3.gif" width="24" height="13"/>public String generate(Object argument)
+ {
+ return &quot;&quot;;
+ }
+ }
+</pre>
+<p> This file is our custom skeleton. All templates that use this skeleton will
+ be translated to classes that implement the <tt class="code">IGenerator</tt> interface. To
+ use this skeleton, add an attribute <i>skeleton</i> to the <tt class="code">jet</tt> directive of
+ your template, like this: </p>
+
+<pre class="code">
+ <span class="highlight">&lt;%@ jet package=&quot;hello&quot; class=&quot;GreetingTemplate&quot; <b>skeleton=&quot;generator.skeleton&quot;</b> %&gt;</span>
+ Hello, <span class="highlight">&lt;%=argument%&gt;</span>!
+ The current time is <span class="highlight">&lt;%=new java.util.Date()%&gt;</span>.
+
+</pre>
+<p>
+After the JET Builder translates the template, the implementation class looks
+like this:
+</p>
+<pre class="code"><font color="#4444cc">
+</font> package hello;
+
+ public class GreetingTemplate <img src="images/tag_1.gif" width="24" height="13"/>implements IGenerator
+ {
+ protected final String NL = System.getProperties().getProperty(&quot;line.separator&quot;);
+ protected final String TEXT_1 = &quot;Hello, &quot;;
+ protected final String TEXT_2 = &quot;!&quot; + NL + &quot;The current time is &quot;;
+ protected final String TEXT_3 = &quot;.&quot;;
+ protected final String TEXT_4 = NL;
+
+
+<img src="images/tag_2.gif" width="24" height="13"/>/* (non-javadoc)
+ * @see IGenerator#generate(Object)
+ */
+<img src="images/tag_3.gif" width="24" height="13"/>public String generate(Object argument)
+ {
+ StringBuffer stringBuffer = new StringBuffer();
+ stringBuffer.append(TEXT_1);
+ stringBuffer.append(argument);
+ stringBuffer.append(TEXT_2);
+ stringBuffer.append(new java.util.Date());
+ stringBuffer.append(TEXT_3);
+ stringBuffer.append(TEXT_4);
+ return stringBuffer.toString();
+ }
+ }
+</pre>
+<p>Note that the translated template now <img src="images/tag_1.gif" width="24" height="13"/>implements
+ the <tt class="code">IGenerator</tt> interface, and the <tt class="code"><img src="images/tag_3.gif" width="24" height="13"/>generate</tt>
+ method now has <img src="images/tag_2.gif" width="24" height="13"/>the comments
+ we specified in the <i>generator.skeleton</i> file. This is one example of how
+ to customize a translated template with a skeleton definition. Skeleton definitions
+ can also contain extra methods, inner classes, etc. You'll need to experiment
+ a little to see what else is possible.</p>
+<h1> JET Syntax Reference </h1>
+
+<p>If you have used JSP technology before, the JET syntax will probably look very
+ familiar to you. The JET syntax is a subset of the JSP syntax, so there may
+ not be much new here for you.</p>
+<p>This section provides a semi-formal description and reference of the JET syntax.
+</p>
+<h2> The JET Model</h2>
+<p>A JET template is translated into a Java implementation class. This implementation
+ class has a method that can be called to obtain a result string. This method
+ is usually called <tt class="code">generate</tt> (see also the <i>skeleton</i> attribute
+ of the <tt class="code">jet</tt> directive). </p>
+
+<p> If no <i>skeleton</i> attribute is specified in the <tt class="code">jet</tt> directive, the Java
+ implementation class has the following implicit objects, which can be referenced
+ in the JET template: </p>
+<ul>
+ <li> <b>stringBuffer</b> the <tt class="code">java.lang.StringBuffer</tt> object
+ used to build the result string when the <tt class="code">generate</tt> method is invoked</li>
+
+ <li> <b>argument</b> the <tt class="code">java.lang.Object</tt> passed to the <tt class="code">generate</tt>
+ method</li>
+</ul>
+
+<h2> Directives </h2>
+
+<p>Directives are messages to the JET engine. Directives have this syntax:
+</p><p>
+<i>&lt;%@ directive { attr=&quot;value&quot; }* %&gt;</i>
+</p><p>
+There may be optional white space after the &quot;&lt;%@&quot; and before &quot;%&gt;&quot;.
+</p><p>
+Directives affect how a template is translated, but do not produce any output
+in the generated String when the template is invoked.
+</p>
+
+<h3> Jet Directive </h3>
+<p>The <tt class="code">jet</tt> directive defines a number of attributes and communicates
+ these to the JET engine. A JET template file must contain a <tt class="code">jet</tt> directive
+ on the first line of the file, or the template file cannot be translated. Any
+ subsequent <tt class="code">jet</tt> directives are ignored. Unrecognized attributes result
+ in fatal translation errors. </p>
+<p> The following directive indicates that the template should be translated to
+ a Java implementation class called <i>HelloWorldTemplate.java</i> in package
+ <i>hello</i>. The implementation class should import the java.io.* and java.util.*
+ packages. </p>
+
+<pre class="code">
+ &lt;%@ jet package=&quot;hello&quot; class=&quot;HelloWorldTemplate&quot; imports=&quot;java.io.* java.util.*&quot; %&gt;</pre>
+<p>The details of the attributes for the <tt class="code">jet</tt> directive are as follows:
+
+</p>
+<table border="1" cellpadding="3" cellspacing="0">
+ <tr>
+ <td><b>Attribute</b></td>
+ <td><b>Value</b></td>
+ </tr>
+ <tr>
+ <td valign="top">package</td>
+
+ <td>The package name of the Java implementation class that the template is
+ translated to. If this attribute is not present, the Java implementation
+ class is created in the default package.</td>
+ </tr>
+ <tr>
+ <td height="40" valign="top">class</td>
+ <td height="40">The class name of the Java implementation class that the template
+ is translated to. If not present, the Java implementation class is called
+ <tt class="code">CLASS</tt>.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">imports</td>
+ <td>A space-separated list of packages and/or classes to import in the Java
+ template class</td>
+ </tr>
+ <tr>
+ <td valign="top">startTag</td>
+ <td>The string in a JET template that signals the beginning of a scriptlet,
+ expression, or <tt class="code">include</tt> directive. The default is &quot;&lt;%&quot;.
+ This attribute, and its cousin <i>endTag</i> can be very convenient when
+ the syntax of the generated code is similar to the default JET syntax, for
+ example if you use JET to generate JSP pages.</td>
+
+ </tr>
+ <tr>
+ <td valign="top">endTag</td>
+ <td>The string in a JET template that signals the end of a scriptlet, expression,
+ or <tt class="code">include</tt> directive. The default is &quot;%&gt;&quot;. See also
+ <i>startTag</i>.</td>
+
+ </tr>
+ <tr>
+ <td valign="top">skeleton</td>
+ <td>The URI of a file with a skeleton definition of the Java implementation
+ class that the template is translated to. This URI will be resolved similar
+ to the way the <i>file</i> attribute value is resolved in an <tt class="code">include</tt>
+ directive. If no skeleton definition file is specified, the JET engine will
+ use a default skeleton of the form &quot;<tt class="code">public class CLASS\n{\n public
+ String generate(Object argument)\n {\n return \&quot;\&quot;;\n }\n}\n</tt>&quot;.
+ The class name in this skeleton class definition must be <tt class="code">CLASS</tt>.</td>
+
+ </tr>
+ <tr>
+ <td valign="top">nlString</td>
+ <td>The newline string to use in the Java template class. The default is &quot;System.getProperties().getProperty(\&quot;line.separator\&quot;)&quot;</td>
+ </tr>
+</table>
+
+<h3> Include Directive </h3>
+<p>The <tt class="code">include</tt> directive is used to substitute text and/or code at template
+ translation-time. The <tt class="code">&lt;%@ include file=&quot;urlSpec&quot; %&gt;</tt>
+ directive inserts the text of the specified resource into the jet template file.
+ The included file may have JET scripting elements which will also be processed.
+</p>
+<p> This directive has one single attribute, <i>file</i>. The value of this attribute
+ is the URI of the location of the file to include. This URI can be either an
+ absolute path or a relative path. Relative URIs are always interpreted as relative
+ to the folder of the template that contains the include directive.</p>
+
+<p>Example:</p>
+<p> The following example requests the inclusion, at translation time, of a copyright
+ file. </p>
+<pre class="code">
+ &lt;%@ include file=&quot;copyright.jet&quot; %&gt;
+</pre>
+<p><i><img src="images/tip.gif" width="62" height="13"/>Note: JET supports the
+ notion of overriding template paths. It is possible to configure the JET engine
+ to use multiple Template Containers. In that case, the first container takes
+ precedence over the second, the second over the third, and so on. This means
+ that if template files or include files with the same file name exist in multiple
+ Template Containers, the file in the first folder will be used, and the other(s)
+ will be ignored. Clients of a JET-based application can use this mechanism to
+ provide custom include files that override the original include files without
+ modifying the templates of the original application.</i><br/>
+</p>
+<h2>JET Scripting Elements </h2>
+
+<p>JET has two scripting language elements: scriptlets and expressions. A scriptlet
+is a statement fragment, and an expression is a complete Java expression.
+</p><p>
+Each scripting element has a &quot;&lt;%&quot;-based syntax as follows: </p>
+<pre class="code">
+ &lt;% this is a scriptlet %&gt;
+ &lt;%= this is an expression %&gt;
+</pre>
+<p>White space is optional after &quot;&lt;%&quot;, and &quot;&lt;%=&quot;, and before
+
+&quot;%&gt;&quot;.
+</p><p>
+If you want to use the %&gt; character sequence as literal characters in a scriptlet,
+rather than to end the scriptlet, you can escape them by typing %\&gt;. Similarly,
+the &lt;% character sequence can be escaped by using &lt;\%.
+</p>
+<h3> Scriptlets </h3>
+<p>Scriptlets can contain any valid Java code fragment. </p>
+<p> Scriptlets are executed at template invocation time. Whether or not they produce
+ any output into the result String depends on the actual code in the scriptlet.
+ Scriptlets can have side effects, modifying the objects visible in them. </p>
+
+<p> When all scriptlet fragments in a given translation unit are combined in the
+ order they appear in the JET template, they should yield a valid Java statement
+ or sequence of statements. </p>
+Example:
+<pre class="code">
+ &lt;% if (Calendar.getInstance().get(Calendar.AM_PM) == Calendar.AM) {%&gt;
+ Good Morning
+ &lt;% } else { %&gt;
+ Good Afternoon
+ &lt;% } %&gt;
+</pre>
+
+<p> <b><i>Syntax</i></b> </p>
+<p> <i>&lt;% scriptlet %&gt;</i> </p>
+<h3> Expressions </h3>
+<p>A JET expression element is a Java expression that is evaluated and the result
+ is appended to the <tt class="code">StringBuffer</tt> object returned by the <tt class="code">generate</tt>
+ method. Expressions are evaluated at template invocation time. </p>
+
+<p> If the result of the expression cannot be appended to a <tt class="code">StringBuffer</tt>
+ then a translation time error occurs. The content of a JET expression must be
+ a complete Java expression. </p>
+<p> Side-effects in expressions are supported. They take effect when the JET expression
+ is evaluated. JET expressions are evaluated left-to-right in the JET template.</p>
+<p>In the next example, the current date is appended to the <tt class="code">StringBuffer</tt>
+ result.</p>
+<pre class="code">&lt;%= (new java.util.Date()).toLocaleString() %&gt; </pre>
+
+<p><b><i>Syntax</i></b> </p>
+<p><i>&lt;%= expression %&gt;</i> </p>
+<h2>Resources</h2>
+<p><a href="http://www.javaworld.com/javaworld/jw-11-2001/jw-1102-codegen.html" target="_blank">http://www.javaworld.com/javaworld/jw-11-2001/jw-1102-codegen.html</a>
+</p>
+<p> <a href="http://www.eclipse.org/emf/" target="_blank">http://www.eclipse.org/emf/</a>
+</p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the United States, other countries, or both.</small></p>
+</body>
+
+</html>
diff --git a/Article-JET/jet_tutorial1.html_old b/Article-JET/jet_tutorial1.html_old
new file mode 100644
index 0000000..afa872f
--- /dev/null
+++ b/Article-JET/jet_tutorial1.html_old
@@ -0,0 +1,574 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<title>JET Tutorial Part 1</title>
+<link rel="stylesheet" href="default_style.css">
+</head>
+<body link="#0000ff" vlink="#800080" bgcolor="#FFFFFF">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2003 <a href="http://www.azzurri.jp">Azzurri Ltd.</a></font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<h1 align="CENTER">JET Tutorial Part 1 (Introduction to JET) </h1>
+<blockquote> <b>Summary</b> <br>
+ Generating source code can save you time in your projects and can reduce the
+ amount of tedious redundant programming. Generating source code can be powerful,
+ but the program that writes the code can quickly become very complex and hard
+ to understand. One way to reduce complexity and increase readability is to use
+ templates.
+ <p> The Eclipse Modeling Framework (<a href="http://eclipse.org/emf/" target="_blank">EMF</a>)
+ project contains two very powerful tools for generating source code: JET (Java
+ Emitter Templates) and JMerge (Java Merge). With JET you can use a JSP-like
+ syntax (actually a subset of the JSP syntax) that makes it easy to write templates
+ that express the code you want to generate. JET is a generic template engine
+ that can be used to generate SQL, XML, Java source code and other output from
+ templates. It is located in the org.eclipse.emf.codegen plug-in as part of
+ the EMF runtime download. </p>
+ <p>
+ In this article you will learn how to create JET templates, how to use the JET
+ Nature and JET Builder to automatically translate templates into Java classes,
+ and how to use these classes to generate source code. This article also provides
+ a short reference to the JET syntax.
+ </p>
+ <p><b>By Remko Popma, Azzurri Ltd., remko.popma@azzurri.jp</b><br>
+ <font size="-1">July 30, 2003</font></p>
+</blockquote>
+<hr width="100%">
+<h2>Getting Started</h2>
+<p>Before creating our first template, you'll need the EMF plug-in. If you haven't
+ installed it yet, install it now before continuing with this tutorial. I am
+ using EMF version 1.1.0 Build 20030513_0618VL. </p>
+<p>A JET template is a text file with a file name that ends with &quot;jet&quot;.
+ I will follow the EMF convention of appending &quot;jet&quot; to whatever the
+ file extension of the generated code would be, so <i>.javajet</i> implies that
+ the template generates a .java file, <i>.xmljet</i> templates generate XML,
+ templates that generate SQL have the <i>.sqljet</i> extension, and so on.</p>
+<h3> JET Nature and JET Builder </h3>
+<p>
+Let's follow tradition and start with a template that creates the message &quot;Hello,
+world&quot;. We will create our first template using the following four step process: </p>
+<ol>
+ <li> Create a new Java project and give it a &quot;<i>src</i>&quot; source folder</li>
+ <li> Add the JET Nature to the project. This will create a folder called &quot;<i>templates</i>&quot;
+ under the project root</li>
+ <li> Change the JET properties of the project to ensure that templates are translated
+ into the &quot;<i>src</i>&quot; source folder of the project</li>
+ <li> Create a new file called &quot;<i>helloworld.txtjet</i>&quot; and save
+ it in the <i>templates</i> folder</li>
+</ol>
+
+<h4> Step 1. Create a Project </h4>
+From the workbench menu, select File &gt; New &gt; Project to bring up the New
+Project wizard. Create a new Java project and add a source folder to it named
+<i>src</i>.
+<h4> Step 2. Add JET Nature </h4>
+<p>After creating the project, right-click on it in the Package Explorer or Hierarchy
+ view and select &quot;Add JET Nature&quot; from the popup menu as shown in the
+ image below. </p>
+<img src="images/addJetNaturePopup.gif" width="186" height="438">
+<p> Adding the JET Nature to the project will create a <i>templates</i> folder
+ under the project root as shown in the image below. Also, a JET Builder is added
+ to the project that will automatically translate every file in the templates
+ folder with a file name ending in &quot;jet&quot; to a Java class. </p>
+<p> <img src="images/newproject.gif" width="166" height="113" border="1">
+<h4> Step 3. Change JET Settings </h4>
+<p> Before creating our first template, let's make sure that the <i>src</i> source
+ folder of the project is the destination folder of the translated templates.
+ Right-click on the project and select &quot;Properties&quot; from the popup
+ menu. In the Project Properties dialog, select JET Settings on the left-hand
+ menu and enter &quot;src&quot; (the name of your source folder) in the &quot;Source
+ Container&quot; text field. The image below shows the JET Settings properties
+ page of the Project Properties dialog. </p>
+<p>
+<img src="images/projectProperties.gif" width="426" height="284">
+</p>
+<p> <i><img src="images/tip.gif" width="62" height="13">Note: you can specify
+ multiple folders in the Template Containers field, separated by a space or a
+ semicolon. However, if templates in different folders have the same filename,
+ only the template in the first folder will be translated automatically by the
+ JET Builder. If you want all templates to be translated, make sure they have
+ different file names.</i>
+<h4> Step 4. Create a JET Template File </h4>
+<p> The JET builder will now translate all templates to Java source files in the
+ <i>src</i> folder of the project. Now we create our first template. From the
+ workbench menu, select File &gt; New &gt; File to bring up the New File wizard.
+ Select the <i>templates</i> directory as the parent folder, and call the file
+ <i>helloworld.txtjet</i>. You will get the following error when you press the
+ OK button: &quot;The jet directive is missing in 'helloworld.txtjet' at line
+ 1 column 1&quot;, as shown in the image below. </p>
+<p>
+<img src="images/missing_jet_directive.gif" width="443" height="268">
+</p>
+<p> Fortunately, this does not mean that there is a real problem, just that the
+ JET Builder tried to translate our template as soon as we created it, and discovered
+ that it is still empty. Press OK to close the error dialog and Cancel to close
+ the wizard dialog. Open the <i>helloworld.txtjet</i> file and type or cut-and-paste
+ the following contents in the editor. </p>
+<pre>
+ <span class="jet">&lt;%@ jet package=&quot;hello&quot; class=&quot;HelloWorldTemplate&quot; %&gt;</span>
+ Hello, world!</pre>
+<p> When you save the template file, it will automatically be translated by the
+ JET Builder. Because we specified package <i>hello</i> and class <i>HelloWorldTemplate</i>
+ in the first line of the template, the builder creates a <i>hello</i> package
+ in the <i>src</i> folder and saves a Java file <i>HelloWorldTemplate.java</i>
+ in this package, as shown in the image below.</p>
+<p> <img src="images/compiledTemplate.gif" width="234" height="161" border="1">
+</p>
+<p> This Java class is the result of translating the template and is called a
+ <i>template implementation class</i>. This class has a method called <tt>generate</tt>.
+ This is the method that generates the code indicated in the template.</p>
+<p><img src="images/tryit.gif" width="61" height="13">We can create an instance
+ of the <tt>HelloWorldTemplate</tt> template implementation class and invoke
+ its <tt>generate</tt> method like this: </p>
+<pre> HelloWorldTemplate helloworld = new HelloWorldTemplate();
+ String result = helloworld.generate(null);
+ System.out.println(result);
+</pre>
+<p> The code above will print the words &quot;Hello, world!&quot; to the console.
+ Yay!</p>
+<h3> Passing Arguments to the Template </h3>
+<p>To recap, we just created our first template and generated some code with it.
+ The result may not have been very impressive, but now we are all set up and
+ we can start to explore what JET can do for you. The next step is to pass an
+ argument to the template. </p>
+<p><img src="images/tryit.gif" width="61" height="13">Add a new JET template file
+ or change the existing one to the following content: </p>
+<pre>
+ <span class="jet">&lt;%@ jet package=&quot;hello&quot; class=&quot;GreetingTemplate&quot; %&gt;</span>
+ Hello, <span class="jet">&lt;%=argument%&gt;</span>!
+</pre>
+<p> The JET Builder will translate this template to a class <tt>GreetingTemplate</tt>
+ in the <tt>hello</tt> package. Again we create an instance of this template
+ class, but this time we pass a string argument to the <tt>generate</tt> method:
+</p>
+<pre> GreetingTemplate sayHello = new GreetingTemplate();
+ String result = sayHello.generate(&quot;Tutorial Reader&quot;);
+ System.out.println(result);
+</pre>
+<p>
+The code above will print the words &quot;Hello, Tutorial Reader!&quot; to the
+console.
+</p>
+<h3> Importing Packages </h3>
+<p>The argument you pass to a template can be any object. In the previous example
+ we passed a string as the argument to the generate method, but in your application
+ you probably want to pass in your own model object. If the argument is not in
+ the <tt>java.lang</tt> package, or if your template uses any other classes not
+ in the <tt>java.lang</tt> package, you need to import these classes in the template
+ <tt>jet</tt> directive. A <tt>jet</tt> directive with an <img src="images/tag_1.gif" width="24" height="13"><i>imports</i>
+ attribute looks like this: </p>
+<pre>
+ &lt;%@ jet package=&quot;hello&quot; <b><img src="images/tag_1.gif" width="24" height="13">imports=&quot;java.util.*&quot;</b> class=&quot;ImportDemoTemplate&quot; %&gt;
+</pre>
+<p> The JET Syntax Reference section of this article gives more details on the
+ <tt>jet</tt> directive and its attributes.</p>
+<p> In the next example we will create a template that generates XML code. To
+ stick to the EMF convention of appending &quot;jet&quot; to whatever the file
+ extension of the generated code would be, we will save this template to a file
+ called <i>importdemo.xmljet</i>. Note that we pass the template a <tt>java.util.List</tt>
+ object that contains the data to use when generating the XML.</p>
+<pre>
+ <span class="jet">&lt;%@ jet package=&quot;hello&quot; <img src="images/tag_1.gif" width="24" height="13"><b>imports=&quot;java.util.*&quot;</b> class=&quot;XMLDemoTemplate&quot; %&gt;</span>
+<img src="images/tag_2.gif" width="24" height="13"><b class="jet">&lt;% List elementList = (List) argument; %&gt;</b>
+ <b> </b>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+ <b> </b>&lt;demo&gt;
+ <span class="jet">&lt;% for (Iterator i = elementList.iterator(); i.hasNext(); ) { %&gt;</span>
+ &lt;element&gt;<span class="jet">&lt;%=i.next().toString()%&gt;</span>&lt;/element&gt;
+ <span class="jet">&lt;% } %&gt;</span>
+ <b> </b>&lt;/demo&gt;
+</pre>
+<p> The code below shows how to invoke the template instance. We create a <img src="images/tag_2.gif" width="24" height="13">list
+ and <img src="images/tag_3.gif" width="24" height="13">pass it to the <tt>generate</tt>
+ method of the template implementation class:</p>
+<pre><img src="images/tag_2.gif" width="24" height="13">List data = new ArrayList();
+ data.add(&quot;first&quot;);
+ data.add(&quot;second&quot;);
+ data.add(&quot;third&quot;);
+
+ XMLDemoTemplate generateXml = new XMLDemoTemplate();
+ String result = generateXml.generate(<img src="images/tag_3.gif" width="24" height="13">data);
+ System.out.println(result);
+</pre>
+<p>
+This prints the following XML result to the console:
+</p>
+<pre>
+ &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+ &lt;demo&gt;
+ &lt;element&gt;first&lt;/element&gt;
+ &lt;element&gt;second&lt;/element&gt;
+ &lt;element&gt;third&lt;/element&gt;
+ &lt;/demo&gt;
+</pre>
+<p> This is a very simple example that creates very simple XML. Of course you
+ can use JET to create more complex XML, using attributes and namespaces. When
+ you do this, you may find it more convenient to create a special class that
+ is a better model of an XML document than a <tt>java.util.List</tt>. Generally,
+ the more complex your JET template becomes, the more logic you will want to
+ push into the model object that you pass to the template, to keep your templates
+ readable. We will explore this further in Part 2 of this tutorial. </p>
+<h3> Changing Tags </h3>
+<p>A neat feature of JET is that you can change the tags that mark scriptlets
+ in the template file. This is very convenient when the syntax of the code you
+ generate is very similar to the default JET syntax, for example if you use JET
+ to generate JSP pages. </p>
+<p>In the next example we will use JET to generate a simple JSP page. We will
+ change the JET tags to use the &quot;&lt;$&quot; character sequence to start
+ a template tag, and &quot;$&gt;&quot; to end a template tag. The template still
+ contains &quot;&lt;%&quot; and &quot;%&gt;&quot; strings, but the JET engine
+ will not see them as special anymore, and they will be written to the result
+ like any other character sequence.</p>
+<p></p>
+<p> <img src="images/tryit.gif" width="61" height="13">To change the tag markers,
+ add a <i><img src="images/tag_1.gif" width="24" height="13">startTag</i> and
+ an <i><img src="images/tag_2.gif" width="24" height="13">endTag</i> attribute
+ to the JET directive on the first line of the template, like in the example
+ below. </p>
+<pre>
+ <span class="jet">&lt;%@ jet package=&quot;tags.demo&quot; class=&quot;JspTemplate&quot; <img src="images/tag_1.gif" width="24" height="13"><b>startTag=&quot;&lt;$&quot; <img src="images/tag_2.gif" width="24" height="13">endTag=&quot;$&gt;&quot;</b> %&gt;</span>
+ <b><span class="jet">&lt;$</span></b><span class="jet"> String paramName = (String) argument; /* This is an executed scriptlet */ <b>$&gt;</b></span>
+ <b><span class="jet">&lt;$</span></b><span class="jet"> if (paramName != null) { <b>$&gt;</b></span>
+ <img src="images/tag_3.gif" width="24" height="13"> &lt;%= request.getParameter(&quot;<b><span class="jet">&lt;$=</span></b><span class="jet">paramName<b>$&gt;</b></span>&quot;) %&gt; &lt;!-- this is generated JSP --&gt;
+ <b><span class="jet">&lt;$</span></b><span class="jet"> } <b>$&gt;</b></span>
+</pre>
+<p> Again, we invoke this implementation class with a string argument, like below:
+</p>
+<pre> System.out.println(new tags.demo.JspTemplate().generate(&quot;button&quot;));
+</pre>
+The following output will appear on the console. Note that the output contains
+the intact JSP tag: the &quot;&lt;%&quot; and &quot;%&gt;&quot; character strings
+are not interpreted as a JET scriptlet, but are simply inserted in the generated
+code.
+<pre>
+ <img src="images/tag_3.gif" width="24" height="13"> &lt;%= request.getParameter(&quot;button&quot;) %&gt; &lt;!-- this is generated JSP --&gt;
+</pre>
+<h1> Under the Hood </h1>
+<p>In the previous section we have looked at creating JET templates, how to set up
+the JET Nature to automatically translate templates into Java implementation classes,
+and how to use these Java implementation classes to generate code.
+</p>
+<p> In this section we will take a closer look at the Java implementation classes
+ that are the result of translating a template. We will see why we can use the
+ implicit objects <tt>argument</tt> and <tt>stringBuffer</tt> in a template,
+ and also look at customizing the translated implementation class by providing
+ a custom &quot;skeleton&quot;. </p>
+<h3> Translated Templates </h3>
+<p>A JET template is translated to a Java implementation class. There are some
+ objects in the Java implementation class that can be referenced directly in
+ the JET template. The following example demonstrates how the implicit objects
+ <tt>argument</tt> and <tt>stringBuffer</tt> can be used in a template.</p>
+<pre>
+ <span class="jet">&lt;%@ jet package=&quot;hello&quot; class=&quot;TranslationDemoTemplate&quot; %&gt;</span>
+<img src="images/tag_1.gif" width="24" height="13"> Hello, <span class="jet">&lt;%=<b>argument</b>%&gt;</span>!
+<img src="images/tag_2.gif" width="24" height="13"> <span class="jet">&lt;% <b>stringBuffer.append(&quot;Hello again!&quot;);</b> %&gt;</span>
+</pre>
+<p> The template above is translated to a Java implementation class like below:
+</p>
+<pre>
+ package hello;
+
+ public class TranslationDemoTemplate
+ {
+ protected final String NL = System.getProperties().getProperty(&quot;line.separator&quot;);
+ protected final String TEXT_1 = &quot;Hello, &quot;;
+ protected final String TEXT_2 = &quot;!&quot;;
+
+ public String generate(Object <b>argument</b>)
+ {
+ StringBuffer <b>stringBuffer</b> = new StringBuffer();
+ stringBuffer.append(TEXT_1);
+<img src="images/tag_1.gif" width="24" height="13"> stringBuffer.append(<b>argument</b>);
+ stringBuffer.append(TEXT_2);
+<img src="images/tag_2.gif" width="24" height="13"> <b>stringBuffer.append(&quot;Hello again!&quot;);</b>
+ return stringBuffer.toString();
+ }
+ }
+</pre>
+<p> Notice that the <tt>generate</tt> method of the Java implementation class
+ takes an <tt>Object</tt> parameter called <tt>argument</tt>. This is the same
+ object as the <tt><img src="images/tag_1.gif" width="24" height="13">argument</tt>
+ in the second line of the template. Also, notice how the Java implementation
+ class uses a <tt>StringBuffer</tt> object to collect the resulting generated
+ code. This object can be <img src="images/tag_2.gif" width="24" height="13">referenced
+ directly in the template by its name <tt>stringBuffer</tt>. </p>
+<h3> Changing the Skeleton of the Translated Implementation Class </h3>
+<p>The <tt>generate</tt> method of the <tt>TranslationDemoTemplate</tt> class
+ above is said to be part of the implementation class &quot;skeleton&quot;. The
+ default skeleton used by the JET engine looks like this: </p>
+<pre>
+ public class CLASS
+ {
+ public String generate(Object argument)
+ {
+ return &quot;&quot;;
+ }
+ }
+</pre>
+<p> The skeleton definition looks almost like a normal Java class, except for
+ the class name. The class name (<tt>CLASS</tt>) will be replaced by the value
+ of the <i>class</i> attribute in the <tt>jet</tt> directive. Furthermore, the skeleton
+ definition has the <tt>generate</tt> method that we have seen earlier. By changing
+ the skeleton you can customize a template implementation class, for example
+ make it implement an interface, or change any other feature of the class.</p>
+<p> <img src="images/tryit.gif" width="61" height="13">For example, suppose you
+ want all your template implementation classes to implement an interface. The
+ interface could look something like this: </p>
+<pre>
+ public interface IGenerator {
+ String generate(Object argument);
+ }</pre>
+<p>We can tell the JET engine that we want to use a custom skeleton by setting
+ the <i>skeleton</i> attribute of the <tt>jet</tt> directive on the first line of the
+ template file. The value of the skeleton attribute is a URI that points to a
+ file where the custom skeleton definition can be found. </p>
+<p>To try this, first create a new file <i>generator.skeleton</i> in the templates
+ directory, as in the image below.</p>
+<p><img src="images/generator_skeleton.gif" width="251" height="321" border="1"></p>
+<p>Open the <i>generator.skeleton</i> file in a text editor and type or cut-and-paste
+ the following content in it: </p>
+<pre>
+ public class CLASS <img src="images/tag_1.gif" width="24" height="13">implements IGenerator
+ {
+<img src="images/tag_2.gif" width="24" height="13">/* (non-javadoc)
+ * @see IGenerator#generate(Object)
+ */
+<img src="images/tag_3.gif" width="24" height="13">public String generate(Object argument)
+ {
+ return &quot;&quot;;
+ }
+ }
+</pre>
+<p> This file is our custom skeleton. All templates that use this skeleton will
+ be translated to classes that implement the <tt>IGenerator</tt> interface. To
+ use this skeleton, add an attribute <i>skeleton</i> to the <tt>jet</tt> directive of
+ your template, like this: </p>
+<pre>
+ <span class="jet">&lt;%@ jet package=&quot;hello&quot; class=&quot;GreetingTemplate&quot; <b>skeleton=&quot;generator.skeleton&quot;</b> %&gt;</span>
+ Hello, <span class="jet">&lt;%=argument%&gt;</span>!
+ The current time is <span class="jet">&lt;%=new java.util.Date()%&gt;</span>.
+</pre>
+<p>
+After the JET Builder translates the template, the implementation class looks
+like this:
+</p>
+<pre><font color="#4444cc">
+</font> package hello;
+
+ public class GreetingTemplate <img src="images/tag_1.gif" width="24" height="13">implements IGenerator
+ {
+ protected final String NL = System.getProperties().getProperty(&quot;line.separator&quot;);
+ protected final String TEXT_1 = &quot;Hello, &quot;;
+ protected final String TEXT_2 = &quot;!&quot; + NL + &quot;The current time is &quot;;
+ protected final String TEXT_3 = &quot;.&quot;;
+ protected final String TEXT_4 = NL;
+
+<img src="images/tag_2.gif" width="24" height="13">/* (non-javadoc)
+ * @see IGenerator#generate(Object)
+ */
+<img src="images/tag_3.gif" width="24" height="13">public String generate(Object argument)
+ {
+ StringBuffer stringBuffer = new StringBuffer();
+ stringBuffer.append(TEXT_1);
+ stringBuffer.append(argument);
+ stringBuffer.append(TEXT_2);
+ stringBuffer.append(new java.util.Date());
+ stringBuffer.append(TEXT_3);
+ stringBuffer.append(TEXT_4);
+ return stringBuffer.toString();
+ }
+ }
+</pre>
+<p>Note that the translated template now <img src="images/tag_1.gif" width="24" height="13">implements
+ the <tt>IGenerator</tt> interface, and the <tt><img src="images/tag_3.gif" width="24" height="13">generate</tt>
+ method now has <img src="images/tag_2.gif" width="24" height="13">the comments
+ we specified in the <i>generator.skeleton</i> file. This is one example of how
+ to customize a translated template with a skeleton definition. Skeleton definitions
+ can also contain extra methods, inner classes, etc. You'll need to experiment
+ a little to see what else is possible.</p>
+<h1> JET Syntax Reference </h1>
+<p>If you have used JSP technology before, the JET syntax will probably look very
+ familiar to you. The JET syntax is a subset of the JSP syntax, so there may
+ not be much new here for you.</p>
+<p>This section provides a semi-formal description and reference of the JET syntax.
+</p>
+<h2> The JET Model</h2>
+<p>A JET template is translated into a Java implementation class. This implementation
+ class has a method that can be called to obtain a result string. This method
+ is usually called <tt>generate</tt> (see also the <i>skeleton</i> attribute
+ of the <tt>jet</tt> directive). </p>
+<p> If no <i>skeleton</i> attribute is specified in the <tt>jet</tt> directive, the Java
+ implementation class has the following implicit objects, which can be referenced
+ in the JET template: </p>
+<ul>
+ <li> <b>stringBuffer</b> the <tt>java.lang.StringBuffer</tt> object
+ used to build the result string when the <tt>generate</tt> method is invoked</li>
+ <li> <b>argument</b> the <tt>java.lang.Object</tt> passed to the <tt>generate</tt>
+ method</li>
+</ul>
+
+<h2> Directives </h2>
+<p>Directives are messages to the JET engine. Directives have this syntax:
+</p><p>
+<i>&lt;%@ directive { attr=&quot;value&quot; }* %&gt;</i>
+</p><p>
+There may be optional white space after the &quot;&lt;%@&quot; and before &quot;%&gt;&quot;.
+</p><p>
+Directives affect how a template is translated, but do not produce any output
+in the generated String when the template is invoked.
+</p>
+<h3> Jet Directive </h3>
+<p>The <tt>jet</tt> directive defines a number of attributes and communicates
+ these to the JET engine. A JET template file must contain a <tt>jet</tt> directive
+ on the first line of the file, or the template file cannot be translated. Any
+ subsequent <tt>jet</tt> directives are ignored. Unrecognized attributes result
+ in fatal translation errors. </p>
+<p> The following directive indicates that the template should be translated to
+ a Java implementation class called <i>HelloWorldTemplate.java</i> in package
+ <i>hello</i>. The implementation class should import the java.io.* and java.util.*
+ packages. </p>
+<pre>
+ &lt;%@ jet package=&quot;hello&quot; class=&quot;HelloWorldTemplate&quot; imports=&quot;java.io.* java.util.*&quot; %&gt;</pre>
+<p>The details of the attributes for the <tt>jet</tt> directive are as follows:
+</p>
+<table border="1" cellpadding="3" cellspacing="0">
+ <tr>
+ <td><b>Attribute</b></td>
+ <td><b>Value</b></td>
+ </tr>
+ <tr>
+ <td valign="top">package</td>
+ <td>The package name of the Java implementation class that the template is
+ translated to. If this attribute is not present, the Java implementation
+ class is created in the default package.</td>
+ </tr>
+ <tr>
+ <td height="40" valign="top">class</td>
+ <td height="40">The class name of the Java implementation class that the template
+ is translated to. If not present, the Java implementation class is called
+ <tt>CLASS</tt>.</td>
+ </tr>
+ <tr>
+ <td valign="top">imports</td>
+ <td>A space-separated list of packages and/or classes to import in the Java
+ template class</td>
+ </tr>
+ <tr>
+ <td valign="top">startTag</td>
+ <td>The string in a JET template that signals the beginning of a scriptlet,
+ expression, or <tt>include</tt> directive. The default is &quot;&lt;%&quot;.
+ This attribute, and its cousin <i>endTag</i> can be very convenient when
+ the syntax of the generated code is similar to the default JET syntax, for
+ example if you use JET to generate JSP pages.</td>
+ </tr>
+ <tr>
+ <td valign="top">endTag</td>
+ <td>The string in a JET template that signals the end of a scriptlet, expression,
+ or <tt>include</tt> directive. The default is &quot;%&gt;&quot;. See also
+ <i>startTag</i>.</td>
+ </tr>
+ <tr>
+ <td valign="top">skeleton</td>
+ <td>The URI of a file with a skeleton definition of the Java implementation
+ class that the template is translated to. This URI will be resolved similar
+ to the way the <i>file</i> attribute value is resolved in an <tt>include</tt>
+ directive. If no skeleton definition file is specified, the JET engine will
+ use a default skeleton of the form &quot;<tt>public class CLASS\n{\n public
+ String generate(Object argument)\n {\n return \&quot;\&quot;;\n }\n}\n</tt>&quot;.
+ The class name in this skeleton class definition must be <tt>CLASS</tt>.</td>
+ </tr>
+ <tr>
+ <td valign="top">nlString</td>
+ <td>The newline string to use in the Java template class. The default is &quot;System.getProperties().getProperty(\&quot;line.separator\&quot;)&quot;</td>
+ </tr>
+</table>
+
+<h3> Include Directive </h3>
+<p>The <tt>include</tt> directive is used to substitute text and/or code at template
+ translation-time. The <tt>&lt;%@ include file=&quot;urlSpec&quot; %&gt;</tt>
+ directive inserts the text of the specified resource into the jet template file.
+ The included file may have JET scripting elements which will also be processed.
+</p>
+<p> This directive has one single attribute, <i>file</i>. The value of this attribute
+ is the URI of the location of the file to include. This URI can be either an
+ absolute path or a relative path. Relative URIs are always interpreted as relative
+ to the folder of the template that contains the include directive.</p>
+<p>Example:</p>
+<p> The following example requests the inclusion, at translation time, of a copyright
+ file. </p>
+<pre>
+ &lt;%@ include file=&quot;copyright.jet&quot; %&gt;
+</pre>
+<p><i><img src="images/tip.gif" width="62" height="13">Note: JET supports the
+ notion of overriding template paths. It is possible to configure the JET engine
+ to use multiple Template Containers. In that case, the first container takes
+ precedence over the second, the second over the third, and so on. This means
+ that if template files or include files with the same file name exist in multiple
+ Template Containers, the file in the first folder will be used, and the other(s)
+ will be ignored. Clients of a JET-based application can use this mechanism to
+ provide custom include files that override the original include files without
+ modifying the templates of the original application.</i><br>
+</p>
+<h2>JET Scripting Elements </h2>
+<p>JET has two scripting language elements: scriptlets and expressions. A scriptlet
+is a statement fragment, and an expression is a complete Java expression.
+</p><p>
+Each scripting element has a &quot;&lt;%&quot;-based syntax as follows: </p>
+<pre>
+ &lt;% this is a scriptlet %&gt;
+ &lt;%= this is an expression %&gt;
+</pre>
+<p>White space is optional after &quot;&lt;%&quot;, and &quot;&lt;%=&quot;, and before
+&quot;%&gt;&quot;.
+</p><p>
+If you want to use the %&gt; character sequence as literal characters in a scriptlet,
+rather than to end the scriptlet, you can escape them by typing %\&gt;. Similarly,
+the &lt;% character sequence can be escaped by using &lt;\%.
+</p>
+<h3> Scriptlets </h3>
+<p>Scriptlets can contain any valid Java code fragment. </p>
+<p> Scriptlets are executed at template invocation time. Whether or not they produce
+ any output into the result String depends on the actual code in the scriptlet.
+ Scriptlets can have side effects, modifying the objects visible in them. </p>
+<p> When all scriptlet fragments in a given translation unit are combined in the
+ order they appear in the JET template, they should yield a valid Java statement
+ or sequence of statements. </p>
+Example:
+<pre>
+ &lt;% if (Calendar.getInstance().get(Calendar.AM_PM) == Calendar.AM) {%&gt;
+ Good Morning
+ &lt;% } else { %&gt;
+ Good Afternoon
+ &lt;% } %&gt;
+</pre>
+<p> <b><i>Syntax</i></b> </p>
+<p> <i>&lt;% scriptlet %&gt;</i> </p>
+<h3> Expressions </h3>
+<p>A JET expression element is a Java expression that is evaluated and the result
+ is appended to the <tt>StringBuffer</tt> object returned by the <tt>generate</tt>
+ method. Expressions are evaluated at template invocation time. </p>
+<p> If the result of the expression cannot be appended to a <tt>StringBuffer</tt>
+ then a translation time error occurs. The content of a JET expression must be
+ a complete Java expression. </p>
+<p> Side-effects in expressions are supported. They take effect when the JET expression
+ is evaluated. JET expressions are evaluated left-to-right in the JET template.</p>
+<p>In the next example, the current date is appended to the <tt>StringBuffer</tt>
+ result.</p>
+<pre>&lt;%= (new java.util.Date()).toLocaleString() %&gt; </pre>
+<p><b><i>Syntax</i></b> </p>
+<p><i>&lt;%= expression %&gt;</i> </p>
+<h2>Resources</h2>
+<p><a href="http://www.javaworld.com/javaworld/jw-11-2001/jw-1102-codegen.html" target="_blank">http://www.javaworld.com/javaworld/jw-11-2001/jw-1102-codegen.html</a>
+</p>
+<p> <a href="http://www.eclipse.org/emf/" target="_blank">http://www.eclipse.org/emf/</a>
+</p>
+<p></p>
+</body>
+</html>
diff --git a/Article-JET/untitled.htm b/Article-JET/untitled.htm
new file mode 100644
index 0000000..4a465f8
--- /dev/null
+++ b/Article-JET/untitled.htm
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Untitled Document</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<body>
+
+</body>
+</html>
diff --git a/Article-JET2/JETCTask.java b/Article-JET2/JETCTask.java
new file mode 100644
index 0000000..5e966c8
--- /dev/null
+++ b/Article-JET2/JETCTask.java
@@ -0,0 +1,155 @@
+package ch.paranor.epla.structure;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.eclipse.emf.codegen.jet.JETCompiler;
+import org.eclipse.emf.codegen.jet.JETException;
+import org.eclipse.emf.codegen.jet.JETSkeleton;
+
+/**
+ * This task compiles JET templates into Java source files using the EMF JET framework.
+ */
+public class JETCTask extends Task {
+
+ private File destDir;
+
+ private List filesets = new ArrayList();
+ private List templateFiles = new ArrayList();
+
+ private File templateFile;
+ private String packageName;
+ private String className;
+
+ public void execute() throws BuildException {
+ preCheck();
+
+ // check that filename ends in 'jet'?
+ if (templateFile != null) {
+ templateFiles.add(templateFile);
+ }
+ for (Iterator i = filesets.iterator(); i.hasNext();) {
+ FileSet fs = (FileSet) i.next();
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ File fromDir = fs.getDir(getProject());
+
+ String[] includedFiles = ds.getIncludedFiles();
+ for (int j = 0; j < includedFiles.length; j++) {
+ templateFiles.add(project.resolveFile(includedFiles[j]));
+ }
+ }
+
+ try {
+ compileJETTemplates();
+ } catch (Exception e) {
+ throw new BuildException(e, location);
+ }
+ }
+
+ public void setDestdir(File destDir) {
+ this.destDir = destDir;
+ }
+
+ public void setTemplate(File templateFile) {
+ this.templateFile = templateFile;
+ }
+
+ public void setPackage(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public void setClass(String className) {
+ this.className = className;
+ }
+
+ public void addFileset(FileSet fileset) {
+ filesets.add(fileset);
+ }
+
+ private void preCheck() throws BuildException {
+ assertTrue(destDir != null, "No destination directory specified");
+ assertTrue(
+ destDir.isDirectory(),
+ "Specified destination directory does not exist: " + destDir);
+ assertTrue(
+ templateFile != null || filesets.size() > 0,
+ "No template files specified");
+ if (templateFile != null) {
+ assertTrue(
+ templateFile.isFile(),
+ "Specified template does not exist: " + templateFile);
+ } else {
+ assertTrue(
+ className == null && packageName == null,
+ "Attributes \"class\" and \"package\" can only be used together with attribute \"template\"");
+ }
+ }
+
+ private void compileJETTemplates()
+ throws MalformedURLException, JETException, FileNotFoundException {
+ log(
+ "Compiling "
+ + templateFiles.size()
+ + " JET template(s) to "
+ + destDir);
+ for (Iterator i = templateFiles.iterator(); i.hasNext();) {
+ File template = (File) i.next();
+ compileJETTemplate(template, destDir);
+ }
+ }
+
+ private File compileJETTemplate(File template, File outputDir)
+ throws JETException, FileNotFoundException, MalformedURLException {
+ String templateURI = template.getAbsoluteFile().toURL().toString();
+ JETCompiler jetCompiler = new JETCompiler(templateURI);
+ log("Parsing template " + template, Project.MSG_VERBOSE);
+ jetCompiler.parse();
+
+ // initialize skeleton
+ JETSkeleton skeleton = jetCompiler.getSkeleton();
+ if (skeleton == null) {
+ log("JET directive missing in " + templateFile, Project.MSG_WARN);
+ jetCompiler.handleDirective("jet", null, null, new HashMap());
+ skeleton = jetCompiler.getSkeleton();
+ }
+ if (className != null) {
+ skeleton.setClassName(className);
+ }
+ if (packageName != null) {
+ skeleton.setPackageName(packageName);
+ }
+
+ File packageDir =
+ new File(outputDir, skeleton.getPackageName().replace('.', '/'));
+ packageDir.mkdirs();
+ File targetFile =
+ new File(packageDir, skeleton.getClassName() + ".java");
+
+ OutputStream output =
+ new BufferedOutputStream(new FileOutputStream(targetFile));
+ log("Generating java source " + targetFile, Project.MSG_VERBOSE);
+ jetCompiler.generate(output);
+ return targetFile;
+ }
+
+ private void assertTrue(boolean expr, String message)
+ throws BuildException {
+ if (!expr) {
+ throw new BuildException(message, location);
+ }
+ }
+
+}
diff --git a/Article-JET2/default_style.css b/Article-JET2/default_style.css
new file mode 100644
index 0000000..7313fb7
--- /dev/null
+++ b/Article-JET2/default_style.css
@@ -0,0 +1,22 @@
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
+
+li p { margin-top: 10px; margin-bottom: 10px; }
+
+a.footnote:link { text-decoration: none; }
+a.footnote:visited { text-decoration: none; }
+a.footnote:hover { text-decoration: underline; }
+
+tt.code { color: #4444CC; }
+pre.code { color: #4444CC; }
+
+.highlight { background-color: #FFFFCC; }
diff --git a/Article-JET2/images/Idea.jpg b/Article-JET2/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-JET2/images/Idea.jpg
Binary files differ
diff --git a/Article-JET2/images/enum_gui_page1.gif b/Article-JET2/images/enum_gui_page1.gif
new file mode 100644
index 0000000..c3bff4e
--- /dev/null
+++ b/Article-JET2/images/enum_gui_page1.gif
Binary files differ
diff --git a/Article-JET2/images/enum_gui_page2.gif b/Article-JET2/images/enum_gui_page2.gif
new file mode 100644
index 0000000..c7a6799
--- /dev/null
+++ b/Article-JET2/images/enum_gui_page2.gif
Binary files differ
diff --git a/Article-JET2/images/enum_gui_page3.gif b/Article-JET2/images/enum_gui_page3.gif
new file mode 100644
index 0000000..ab42c64
--- /dev/null
+++ b/Article-JET2/images/enum_gui_page3.gif
Binary files differ
diff --git a/Article-JET2/images/jetemitter.gif b/Article-JET2/images/jetemitter.gif
new file mode 100644
index 0000000..4e5c892
--- /dev/null
+++ b/Article-JET2/images/jetemitter.gif
Binary files differ
diff --git a/Article-JET2/images/linux_only.gif b/Article-JET2/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-JET2/images/linux_only.gif
Binary files differ
diff --git a/Article-JET2/images/new_creation_wizard.gif b/Article-JET2/images/new_creation_wizard.gif
new file mode 100644
index 0000000..d9f5a2a
--- /dev/null
+++ b/Article-JET2/images/new_creation_wizard.gif
Binary files differ
diff --git a/Article-JET2/images/new_toolbar.gif b/Article-JET2/images/new_toolbar.gif
new file mode 100644
index 0000000..b6dda01
--- /dev/null
+++ b/Article-JET2/images/new_toolbar.gif
Binary files differ
diff --git a/Article-JET2/images/tag_1.gif b/Article-JET2/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-JET2/images/tag_1.gif
Binary files differ
diff --git a/Article-JET2/images/tag_2.gif b/Article-JET2/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-JET2/images/tag_2.gif
Binary files differ
diff --git a/Article-JET2/images/tag_3.gif b/Article-JET2/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-JET2/images/tag_3.gif
Binary files differ
diff --git a/Article-JET2/images/tag_4.gif b/Article-JET2/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-JET2/images/tag_4.gif
Binary files differ
diff --git a/Article-JET2/images/tag_5.gif b/Article-JET2/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-JET2/images/tag_5.gif
Binary files differ
diff --git a/Article-JET2/images/tag_6.gif b/Article-JET2/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-JET2/images/tag_6.gif
Binary files differ
diff --git a/Article-JET2/images/tag_7.gif b/Article-JET2/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-JET2/images/tag_7.gif
Binary files differ
diff --git a/Article-JET2/images/tip.gif b/Article-JET2/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-JET2/images/tip.gif
Binary files differ
diff --git a/Article-JET2/images/translate_action.gif b/Article-JET2/images/translate_action.gif
new file mode 100644
index 0000000..08eeef9
--- /dev/null
+++ b/Article-JET2/images/translate_action.gif
Binary files differ
diff --git a/Article-JET2/images/tryit.gif b/Article-JET2/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-JET2/images/tryit.gif
Binary files differ
diff --git a/Article-JET2/images/win_only.gif b/Article-JET2/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-JET2/images/win_only.gif
Binary files differ
diff --git a/Article-JET2/jet_tutorial2.html b/Article-JET2/jet_tutorial2.html
new file mode 100644
index 0000000..06c8a16
--- /dev/null
+++ b/Article-JET2/jet_tutorial2.html
@@ -0,0 +1,1033 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>JET Tutorial Part 2 (Write Code that Writes Code)</title>
+<link rel="stylesheet" href="default_style.css">
+</head>
+
+<body lang="EN-US" xml:lang="EN-US">
+
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">&copy;
+ Copyright <a href="http://www.azzurri.jp">Azzurri Ltd.</a> 2003, 2004. All rights
+ reserved</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" align=CENTER width="120" height="86" /></h1>
+</div>
+
+<h1 align="center">JET Tutorial Part 2 (Write Code that Writes Code)</h1>
+
+<blockquote>
+<b>Summary</b>
+
+<br/>
+<p>In Part 2 of this JET (Java Emitter Templates) tutorial, we will take a look
+ at the JET engine API. You will learn how to write plug-ins that use the classes
+ in the JET package to generate Java source code.</p>
+ <p>As a real-world example, we will create a plug-in that takes user input and
+ generates a Typesafe Enumeration class. The generated source code is based
+ on a JET template that can be distributed with the plug-in, allowing users
+ of the plug-in to customize the generated code by editing the template.</p>
+<p>This article also provides a short reference to the JET API.</p>
+ <p>Contributed by Remko Popma, Azzurri Ltd., remko.popma at azzurri dot jp,
+ August 26, 2003. Last update: May 31, 2004 for EMF 2.0 (Eclipse 3.0).</p>
+
+</blockquote>
+
+<hr width="100%"/>
+
+<h2>Source Code </h2>
+<p>To run the example or view the source for code for this article you can unzip
+ <a href="org.eclipse.emf.examples.jet.article2_2.0.0.zip">org.eclipse.emf.examples.jet.article2_2.0.0.zip</a>
+ into your <i>plugins/</i> subdirectory. To use the example plug-in, you will
+ need <a href="http://www.eclipse.org/emf/" target="_blank">EMF</a> plug-in version
+ 2.0 installed.</p>
+
+<h2>Introduction </h2>
+<center>
+ <table border="1" cellspacing="0" width="80%" cellpadding="3">
+ <tbody>
+ <tr>
+ <td>
+ <p><b>Translation vs. Generation</b></p>
+ <p>An aspect of JET templates that is at first confusing is that generating
+ text takes two steps: translation and generation. The first step is
+ translating the template to a template implementation class. The second
+ step is using this template implementation class to generate the text.
+ </p>
+ <p>If your goal with JET is to generate Java source code, it can be confusing
+ that the template translation step also results in Java source code. Remember
+ that this source code is <i>not</i> the generated text. The source code
+ that is the result of the translation step is simply another form of the
+ template. </p>
+
+ <p>If you have used JSP and servlets before, you can think of a JET template
+ as being equivalent to a JSP page. A JET template is translated to a
+ template implementation class, just like a JSP page is translated to
+ a servlet. The second step, where the template implementation class
+ generates text, is equivalent to the servlet creating and returning
+ HTML.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</center>
+
+<p><a href="../Article-JET/jet_tutorial1.html">Part 1</a> of this tutorial introduced
+ JET templates and explained how you can convert a project to a JET project to
+ have the JET Builder automatically translate templates in your project to template
+ implementation classes. </p>
+<p>In part 2 of this tutorial, we will focus on writing a plug-in that uses the
+ classes in the JET package to generate Java source code. A plug-in that generates
+ text from a JET template can no longer rely on the JET Nature and JET Builder
+ to automatically translate templates. This is because JET Nature and JET Builder
+ operate only on workspace projects, not on plug-ins. Plug-ins need to use the
+ classes in the JET package to translate their templates. </p>
+
+<p>The next section will discuss some of the classes in the <tt class="code">org.eclipse.emf.codegen</tt>
+ package. We will see what the steps are to generate source code with JET, and
+ how the JET engine classes fit in. If you are anxious to see some code that
+ shows how to use these classes in practice, you can go straight to <a href="#example_plugin">A
+ Plug-in that Generates Source Code</a>. </p>
+
+<h2>Some JET Classes</h2>
+<p>In this section, we will take a closer look at some of the classes in the JET
+ package. They can roughly be divided into two groups: </p>
+<ul>
+ <li>Lower-level classes dealing with the nuts and bolts of translating a template
+ to a template implementation class. The <tt class="code">JETCompiler</tt> class brings
+ all these lower-level classes together to provide a single API for template
+ translation. </li>
+
+ <li>Higher-level classes that build on top of <tt class="code">JETCompiler</tt> to accomplish
+ user tasks. In Part 1 of this tutorial, we have already seen <tt class="code">JETNature</tt>
+ and <tt class="code">JETBuilder</tt> at work. Other high-level classes are <tt class="code">CodeGen</tt>
+ and <tt class="code">JETEmitter</tt>. </li>
+
+</ul>
+<p>The lower-level classes are not discussed in-depth in this article. For a description
+ of all classes in the <tt class="code">org.eclipse.emf.codegen</tt> plug-in, see the <a href="#jet_api_overview">JET
+ API Overview</a> section below. In the rest of this section, we will focus on
+ a few of the higher-level classes.</p>
+<h4><tt class="code">org.eclipse.emf.codegen.jet.JETCompiler</tt></h4>
+<p><tt class="code">JETCompiler</tt> is the core class for template translation. This class
+ is responsible for translating templates to the Java source code of a template
+ implementation class. The actual translation is delegated to other classes in
+ the same package. Clients create a JETCompiler object for a particular template
+ and then call the <tt class="code">parse</tt> method followed by the <tt class="code">generate</tt>
+ method to write the Java source code for the resulting template implementation
+ class to a specified stream.</p>
+
+<h4><tt class="code">org.eclipse.emf.codegen.jet.JETEmitter</tt></h4>
+<p><tt class="code">JETEmitter</tt> provides a convenient high-level API for users of the
+ JET package. The <tt class="code">generate</tt> method of this class combines template
+ translation and text generation into a single step. By taking care of the gory
+ details of translating templates and compiling the Java source code of the translated
+ template implementation class, JETEmitter lets you focus on the final generator
+ output.</p>
+<p>Another way of looking at JETEmitter is that it abstracts away the translation
+ step and lets you pretend that you can directly generate text with a template.
+ Following the <a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html" target="_blank">Law
+ of Leaky Abstractions</a>, we cannot always get away with this, and the <a href="#jetemitter_gotchas">JETEmitter
+ Gotchas</a> section below points to a few places where you have to be careful.</p>
+<p>JETEmitter is the class we will be using in our plug-in, so we will go into
+ a little more detail here.</p>
+
+<p>A JETEmitter object is constructed with the uri of the template used to generate
+ text. Any type of uri is acceptable as long as a protocol handler is available.
+ This means that <tt class="code">file:/</tt> uris, <tt class="code">ftp:/</tt> uris and <tt class="code">http:/</tt><i>
+ </i>uris can all be used. Eclipse adds special protocol handlers for <tt class="code">platform:/base</tt>/,
+ <tt class="code">platform:/plugin/</tt>, <tt class="code">platform:/fragment/</tt> and <tt class="code">platform:/resource/</tt>
+ uris, so plug-ins can use a uri like <tt class="code">platform:/resource/myproject/myfolder/mytemplate.jet</tt>
+ to specify a template file. Note: Eclipse 3.0 has introduced <tt class="code">bundleentry</tt> to its list
+ of special protocols. It should be used in references to Eclipse elements such as plugins and features.</p>
+
+<p>In our example plug-in, we will distribute our template file together with our
+ plug-in, so the template file will be located in a <i>myplugin/templates/</i>
+ folder under the Eclipse <i>plugins/</i> folder. The following code can then
+ be used to locate and generate a template from this folder:</p>
+<pre class="code"> String pluginId = "myplugin.id";
+ String base = Platform.getBundle(pluginId).getEntry("/").toString();
+ String uri = base + "templates/myTemplate.javajet";
+ JETEmitter emitter = new JETEmitter(uri);
+ String generatedText = emitter.generate(new Object[] {parameter});</pre>
+<p>After constructing a JETEmitter object, clients then call <tt class="code">generate</tt>
+ on it to generate text. The <tt class="code">generate</tt> method will perform the following
+ steps:</p>
+
+<ol>
+ <li>Create a project called <i>.JETEmitters</i> in the workspace </li>
+ <li>Prepare this project by giving it the Java Nature and adding classpath variables
+ to its classpath </li>
+ <li>Translate the template to a template implementation Java source file in
+ the <i>.JETEmitters</i> project </li>
+ <li>Build the project to compile the template implementation source code to
+ a Java <i>.class</i> file </li>
+ <li>Call the <tt class="code">generate</tt> method on the translated Java template implementation
+ class and return the generated text as a String</li>
+</ol>
+<p>* <i>.JETEmitters</i> is the default name for the project that is created during the template
+translation. This value can be changed by the <tt class="code">setProjectName</tt> method.</p>
+
+
+<p>Our example plug-in will use JETEmitter and save the generated text to a Java
+ source file in the workspace. The figure below shows the steps for generating
+ source code using JETEmitter. </p>
+<p><img alt="Using JETEmitter to generate text from a plugin" src="images/jetemitter.gif"/> </p>
+<h3><a name="jetemitter_gotchas"></a>JETEmitter Gotchas</h3>
+<p>The JETEmitter class combines template translation and text generation into
+ a single step, which makes it a very convenient tool. However, it is important
+ that you know what takes place under the hood, otherwise you might be in for
+ some nasty surprises. This section highlights some &quot;gotchas&quot; that
+ I ran into, so that you don't make the same mistakes.</p>
+
+<h4>1. Plug-in Initialization Required </h4>
+<p>It is not easy to use JET outside of Eclipse. JET is designed to run only as
+ a workspace application. Any application using JET must minimally run as an
+ Eclipse &quot;headless&quot; application so that plug-in initialization takes
+ place. (The term headless refers to running Eclipse without the user interface.)</p>
+<p>This means that using JETEmitter from a simple standalone application (a standard
+ Java class with a <tt class="code">main</tt> method) <i>will not work</i>:</p>
+<pre class="code"> // This fails: cannot use JETEmitter from a standalone application
+ public static void main(String[] args) {
+ JETEmitter emitter = new JETEmitter("/myproject/templates/HelloWorld.txtjet");
+
+ // this will throw a NullPointerException
+ String result = emitter.generate(new NullProgressMonitor(), {"hi" });
+
+ System.out.println(result);
+</pre>
+
+<p>Note that this is not a restriction of just the JETEmitter class, many of the
+ classes in the <tt class="code">org.eclipse.emf.codegen</tt> plug-in have dependencies
+ on other plug-ins. The <a href="#appendix">Appendix</a> section below has more
+ details on using JET from standalone applications.</p>
+<p>In the rest of this article we will assume that our code is running from inside
+ a plug-in.</p>
+<h4>2. Classloader Issues </h4>
+<p>You may get a NoClassDefFoundError when you pass a custom object as the argument
+ to the <tt class="code">JETEmitter.generate</tt> method. This can happen if the object
+ you pass as the argument is not one of the java "bootstrap" classes (the bootstrap
+ classes are the runtime classes in rt.jar and internationalization classes in
+ i18n.jar).</p>
+
+<p>To prevent this error you must specify the classloader of your plug-in when
+ using JETEmitter. If no classloader is specified, JETEmitter uses the classloader
+ of its own class, which is usually the classloader for the <tt class="code">org.eclipse.emf.codegen</tt>
+ plug-in, and this classloader can't see much. In recent versions of EMF (since
+ version 1.1.0 build 20030527_0913VL), JETEmitter has a constructor that takes
+ a classloader argument.</p>
+<p>Note that another way to specify a classloader is to subclass JETEmitter in
+ your own project; if no classloader is specified, JETEmitter will use the classloader
+ of this subclass. (If you are using an older version of EMF, there are no constructors
+ that take a classloader argument and you will have no choice but to subclass
+ JETEmitter in your own project.)</p>
+<p>The example below shows an action class that translates and invokes a selected
+ template using JETEmitter. The example shows how a JETEmitter can be constructed
+ <img src="images/tag_1.gif" width="24" height="13"/>with a classloader parameter or by <img src="images/tag_2.gif" width="24" height="13"/>constructing
+ an anonymous subclass.</p>
+<pre class="code">package org.eclipse.emf.examples.jet.article2.actionexample;
+// imports omitted
+public class EmitAction implements IActionDelegate {
+ protected ISelection selection;
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ this.selection = selection;
+ action.setEnabled(true);
+ }
+
+ public void run(IAction action) {
+ List files = (selection instanceof IStructuredSelection)
+ ? ((IStructuredSelection) selection).toList()
+ : Collections.EMPTY_LIST;
+
+ for (Iterator i = files.iterator(); i.hasNext();) {
+ IFile file = (IFile) i.next();
+ IPath fullPath = file.getFullPath();
+
+ String templateURI = "platform:/resource" + fullPath;
+ <b>Class</b><b>Loader classloader = getClass().getClassLoader();</b>
+<img src="images/tag_1.gif" width="24" height="13"/> JETEmitter emitter = new JETEmitter(templateURI, <b>classloader</b>);
+
+ // <b>or: use an anonymous subclass</b>
+
+<img src="images/tag_2.gif" width="24" height="13"/> // emitter = <b>new JETEmitter(templateURI) {}</b>; // notice the brackets
+
+ try {
+ IProgressMonitor monitor = new NullProgressMonitor();
+ String[] arguments = new String[] { "hi" };
+
+ String result = emitter.generate(monitor, arguments);
+
+ saveGenerated(result, file);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ // saveGenerated method omitted
+}
+</pre>
+<h4>3. Classpath Issues </h4>
+<p>JETEmitter translates your templates to Java source files in the <i>.JETEmitters</i>
+ project, and invokes the JavaBuilder to compile these source files. If your
+ templates use classes that are not standard Java classes, or not in the EMF
+ plug-in, you will need to add these classes to the classpath of the <i>.JETEmitters</i>
+ project, or the JavaBuilder cannot compile the template implementation source
+ files. Fortunately, JETEmitter provides a simple way to do this through the method
+ <tt class="code">addVariable</tt> which adds a <i>Classpath Variable</i> to the <i>.JETEmiter</i> project.</p>
+<p>A <i>Classpath Variable</i> is a workspace-wide name that is used in Eclipse to refer to a jar file or
+directory. The list of all such variables can be seen using the Window &gt; Preferences &gt; Java &gt;
+Classpath Variables menua action.. Your program will need to add a classpath variable for each
+ jar file or directory that is needed on the classpath of the <i>.JETEmiter</i> project.</p>
+
+
+<h2><a name="example_plugin"></a>A Plug-in that Generates Source Code </h2>
+<p>In this part of the JET Tutorial, we will write an Eclipse plug-in that uses
+ a JET template to generate Java source code for typesafe enumerations.</p>
+<p>Our plug-in has to perform the following tasks:</p>
+<ol>
+ <li>Collect user input values for the variables in our template: the class name,
+ the type and name of the attributes of the typesafe enumeration class, and
+ the values of these attributes for each instance. We will write a simple GUI
+ to collect these values.</li>
+ <li>Translate the JET template file to a Java template implementation class</li>
+
+ <li>Invoke the template implementation class with an object that contains the
+ user input values collected by the GUI</li>
+ <li>Save the resulting generated source code to a location obtained from the
+ GUI</li>
+</ol>
+<p>In the following sections we will go through the steps above one by one.</p>
+<h3><a name="typesafe_enum_example"></a>Typesafe Enumerations</h3>
+<p>Let's have a look at a typesafe enumeration class to see what kind of source
+ code we want to generate. The Digit class below is an example typesafe enum.</p>
+<pre class="code"> // an example typesafe enum
+ package x.y.z;
+ public class Digit {
+<img src="images/tag_1.gif" width="24" height="13"/> public static final Digit ZERO = new Digit(0, "zero");
+ public static final Digit ONE = new Digit(1, "one");
+ public static final Digit TWO = new Digit(2, "two");
+ public static final Digit THREE = new Digit(3, "three");
+ // ...
+ public static final Digit NINE = new Digit(9, "nine");
+
+ private static final Digit[] ALL =
+ {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE};
+
+
+<img src="images/tag_2.gif" width="24" height="13"/> private final int value;
+ private final String name;
+
+ private Digit(int value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+<img src="images/tag_3.gif" width="24" height="13"/> public static Digit lookup(int key) {
+ for (int i = 0; i &lt; ALL.length; i++) {
+ if (key == ALL[i].getValue()) { return ALL[i]; }
+ }
+ // lookup failed:
+ // we have no default Digit, so we throw an exception
+<img src="images/tag_4.gif" width="24" height="13"/> throw new IllegalArgumentException("No digit exists for " + key);
+ }
+
+ public int getValue() { return value; }
+ public int getName() { return name; }
+ public String toString() { return getName(); }
+ }</pre>
+<p>Let's take a closer look at this class. First of all, the Digit class has several
+ <b><img src="images/tag_1.gif" width="24" height="13"/>instances</b> - the constants
+ ZERO, ONE, TWO, etc. Each instance is defined by its Java variable name, "ZERO",
+ "ONE", "TWO"..., and the values for each <b><img src="images/tag_2.gif" width="24" height="13"/>attribute</b>
+ of the enumeration class. Most typesafe enums have one or more attributes. The
+ Digit class has two attributes: a <tt class="code">value</tt> integer and a <tt class="code">name</tt>
+ String.</p>
+
+<p>Our example Digit class also has a <b><img src="images/tag_3.gif" width="24" height="13"/><tt class="code">lookup</tt></b>
+ method, which returns the instance whose <tt class="code">value</tt> attribute equals
+ the specified int parameter. A lookup method introduces the concept of <b>key
+ attributes</b>. Many typesafe enums have one or more attributes that uniquely
+ distinguish one instance from another.</p>
+<p><i>Note that key attributes are not required: the Java VM guarantees that every
+ newly constructed object is unique, so it is possible to have typesafe enumerations
+ that have no attributes at all, and simply distinguish their instances with
+ the <b>==</b> instance identity operator. This works fine, but often it is convenient
+ to have a key attribute that uniquely identifies an instance, and a <tt class="code">lookup</tt>
+ method that finds an instance for a specified key value.</i></p>
+
+<p>Our template does have a <tt class="code">lookup</tt> method, so we need to decide what
+ to do if <img src="images/tag_4.gif" width="24" height="13"/>no instance is found
+ for the specified key value. Basically there are three options: throwing an
+ Exception, returning a designated &quot;default&quot; instance, or returning
+ <tt class="code">null</tt>. Which option is best depends on the application in which
+ the class is used, so we should probably let the user decide.</p>
+<p>Now that we've studied typesafe enums in more detail, let's summarize what
+ is customizable in a typesafe enumeration:</p>
+<ul>
+ <li>package name </li>
+ <li>class name </li>
+
+ <li>attributes, where each attribute </li>
+ <ul>
+ <li>has a type </li>
+ <li>has a name </li>
+ <li>may be a key attribute </li>
+ </ul>
+ <li>instances, where each instance </li>
+
+ <ul>
+ <li>has a name </li>
+ <li>has a value for every attribute </li>
+ <li>may be the default instance to return for failed lookups</li>
+ </ul>
+</ul>
+<h3><a name="typesafe_enum_model"></a>A Simple Typesafe Enumeration Model </h3>
+<p>A simple model for the customizable parts of a typesafe enum could look something
+ like this:</p>
+<p></p>
+
+<table border="1" cellspacing="0">
+ <tbody>
+ <tr>
+ <td><tt class="code">TypesafeEnum</tt></td>
+ </tr>
+ <tr>
+ <td><tt class="code">getInstances() : Instance[]<br/>
+ getAttributes() : Attribute[]<br/>
+ getKeyAttributes() : Attribute[]<br/>
+
+ getDefaultInstance() : Instance<br/>
+ getPackageName() : String<br/>
+ getClassName() : String</tt></td>
+ </tr>
+ </tbody>
+</table>
+<p></p>
+<table border="1" cellspacing="0">
+ <tbody>
+ <tr>
+ <td><tt class="code">Instance</tt></td>
+
+ </tr>
+ <tr>
+ <td><tt class="code"> getName() : String<br/>
+ getAttributeValues() : Properties<br/>
+ getAttributeValue(Attribute) : String<br/>
+ isDefault() : boolean</tt></td>
+ </tr>
+
+ </tbody>
+</table>
+<p></p>
+<table border="1" cellspacing="0">
+ <tbody>
+ <tr>
+ <td><tt class="code">Attribute</tt></td>
+ </tr>
+ <tr>
+ <td><tt class="code"> getName() : String<br/>
+
+ getType() : String<br/>
+ isKey() : boolean</tt></td>
+ </tr>
+ </tbody>
+</table>
+<p></p>
+<p>In the next section we will use these classes to convert our Digit class to
+ a JET template for typesafe enumerations.</p>
+<h3><a name="typesafe_enum_template"></a>A Typesafe Enumeration Template </h3>
+<p>Now that we have a model, we can take our Digit class and replace all Digit-specific
+ code with JET scriptlets and expressions that call our model classes. The resulting
+ template could look something like this:</p>
+
+<pre class="code"> <span class="highlight"><span class="highlight">&lt;%@ jet package="translated" imports="java.util.* article2.model.*" class="TypeSafeEnumeration" %&gt;</span></span>
+ <span class="highlight"><span class="highlight">&lt;% TypesafeEnum enum = (TypesafeEnum) argument; %&gt;</span></span>
+ package <span class="highlight">&lt;%=enum.getPackageName()%&gt;</span>;
+
+ /**
+ * This final class implements a type-safe enumeration
+ * over the valid instances of a <span class="highlight">&lt;%=enum.getClassName()%&gt;</span>.
+ * Instances of this class are immutable.
+ */
+ public final class <span class="highlight">&lt;%=enum.getClassName()%&gt;</span> {
+
+ <span class="highlight">&lt;% for (Iterator i = enum.instances(); i.hasNext(); ) { %&gt;</span>
+
+ <span class="highlight">&lt;% Instance instance = (Instance) i.next(); %&gt;</span>
+
+ // <b>instance definition</b>
+ public static final <span class="highlight">&lt;%=enum.getClassName()%&gt;</span> <span class="highlight">&lt;%=instance.getName()%&gt;</span> =
+<img src="images/tag_1.gif" width="24" height="13"/> new <span class="highlight">&lt;%=enum.getClassName()%&gt;</span>(<span class="highlight">&lt;%=instance.constructorValues()%&gt;</span>);
+ <span class="highlight">&lt;% } %&gt;</span>
+
+
+ <span class="highlight">&lt;% for (Iterator i = enum.attributes(); i.hasNext(); ) { %&gt;</span>
+ <span class="highlight">&lt;% Attribute attribute = (Attribute) i.next(); %&gt;</span>
+
+ // <b>attribute declaration</b>
+<img src="images/tag_2.gif" width="24" height="13"/> private final <span class="highlight">&lt;%=attribute.getType()%&gt;</span> m<span class="highlight">&lt;%=attribute.getCappedName()%&gt;</span>;
+ <span class="highlight">&lt;% } %&gt;</span>
+
+
+ /**
+ * Private <b>constructor</b>.
+ */
+<img src="images/tag_3.gif" width="24" height="13"/> private <span class="highlight">&lt;%=enum.getClassName()%&gt;</span>(<span class="highlight">&lt;%=enum.constructorParameterDescription()%&gt;</span>) {
+ <span class="highlight">&lt;% for (Iterator i = enum.attributes(); i.hasNext(); ) { %&gt;</span>
+ <span class="highlight">&lt;% Attribute attribute = (Attribute) i.next(); %&gt;</span>
+<img src="images/tag_4.gif" width="24" height="13"/> m<span class="highlight">&lt;%=attribute.getCappedName()%&gt;</span> = <span class="highlight">&lt;%=attribute.getUncappedName()%&gt;</span>;
+ <span class="highlight">&lt;% } %&gt;</span>
+
+ }
+
+ // <b>getter accessor methods</b>
+ <span class="highlight">&lt;% for (Iterator i = enum.attributes(); i.hasNext(); ) { %&gt;</span>
+ <span class="highlight">&lt;% Attribute attribute = (Attribute) i.next(); %&gt;</span>
+ /**
+ * Returns the <span class="highlight">&lt;%=attribute.getName()%&gt;</span>.
+ *
+ * @return the <span class="highlight">&lt;%=attribute.getName()%&gt;</span>.
+ */
+ public <span class="highlight">&lt;%=attribute.getType()%&gt;</span> get<span class="highlight">&lt;%=attribute.getCappedName()%&gt;</span>() {
+ return m<span class="highlight">&lt;%=attribute.getCappedName()%&gt;</span>;
+ }
+
+ <span class="highlight">&lt;% } %&gt;</span>
+
+ // lookup method omitted...
+ }</pre>
+
+<p>As you can see, the template calls some methods that were not in the simple
+ model we introduced earlier. We have added a few convenience methods, like the
+ <tt class="code"><img src="images/tag_2.gif" width="24" height="13"/>Attribute.getCappedName()</tt>
+ and <tt class="code"><img src="images/tag_4.gif" width="24" height="13"/>getUncappedName()</tt>
+ methods. Such methods help to keep the template simple.</p>
+<p>Another example of methods we added to the model are the <tt class="code"><img src="images/tag_3.gif" width="24" height="13"/>TypesafeEnum.constructorParameterDescription()</tt>
+ method and the <tt class="code"><img src="images/tag_1.gif" width="24" height="13"/>Instance.constructorValues()</tt>
+ method. The implementation of the <tt class="code">constructorValues</tt> method is shown
+ below. </p>
+
+<pre class="code">// class Instance
+/**
+ * Convenience method that returns the attribute values of this instance,
+ * in the order expected by the constructor of this instance.
+ *
+ * @return a comma-separated list of all attribute values of this instance,
+ * formatted like <tt class="code">attrib1-value, attrib2-value (, ...)</tt>
+ */
+public String constructorValues() {
+ StringBuffer result = new StringBuffer();
+ for (Iterator i = getType().attributes(); i.hasNext(); ) {
+ Attribute attribute = (Attribute) i.next();
+ result.append(getAttributeValue(attribute));
+ if (i.hasNext()) {
+ result.append(", ");
+ }
+ }
+ return result.toString();
+}
+</pre>
+<p>The <tt class="code">constructorValues</tt> method loops through the attributes of the
+ typesafe enum, looks up the value for each attribute in the instance, and concatenates
+ these values into a string, separated by commas. For example, in our <tt>Digit</tt>
+ typesafe enum class above, this method would return <tt>&quot;0, \&quot;zero\&quot;&quot;</tt>
+ for the &quot;ZERO&quot; instance. </p>
+
+<p>We could have looped through the attribute values in the template, but that
+ would have made the template much more difficult to read. Pushing this logic
+ into the model made the template more readable and easier to maintain. On the
+ other hand, we lost some flexibility because users cannot customize that logic
+ anymore by editing the template. This is a trade-off you have to make. Which
+ is better depends on your template and your application.</p>
+<h3><a name="gui"></a>A GUI to Collect User Input </h3>
+<p>Now that we have a model and a template, we still need two more pieces to finish
+ our plug-in: we need a GUI to collect values from the user to populate our model
+ with, and we need to invoke our template with the populated model to generate
+ source code and save this source code to a location in the workspace.</p>
+<p>Let's start with the GUI. The workbench provides a few wizards that do something
+ similar to what we have in mind, for example the New Class, New Interface and
+ New JUnit TestCase wizards. It probably makes sense to have our GUI look similar
+ to these wizards and make it accessible from the standard menu and toolbar locations.</p>
+<p>Our wizard has three pages. The first page, shown below, looks like a simplified
+ version of the New Class wizard. In fact, we are using the same framework that
+ the New Class wizard uses, the <tt class="code">org.eclipse.jdt.ui.wizards</tt> package.
+ In the first page, we collect the package name and the class name of the typesafe
+ enum, and the location where the result should be saved.</p>
+<p><img alt="GUI wizard page one: class, package and location of the typesafe enum" src="images/enum_gui_page1.gif"/>
+</p>
+<p></p>
+<p>Our second page collects information on the attributes of the typesafe enum
+ class. Every attribute has a name and a type, and may be one of the key attributes.
+ Our second wizard page is shown below:</p>
+
+<p><img alt="GUI wizard page two: attributes of the typesafe enum" src="images/enum_gui_page2.gif"/></p>
+<p></p>
+<p>Our third and last wizard page, shown below, collects information on the instances
+ of the typesafe enum. The user inputs the instance name, and for each instance
+ provides values for all attributes.</p>
+<p>Finally, one of the instances may be the &quot;default&quot; instance, which
+ is the instance returned by the <tt class="code">lookup</tt> method if no instance was
+ found for the specified key attribute values.</p>
+<p><img alt="GUI wizard page three: instances of the typesafe enum" src="images/enum_gui_page3.gif"/></p>
+<h3><a name="invoke_plugin_template"></a>Invoking the Template </h3>
+<p>Now that we have a GUI to populate our model, we can finally use what we learned
+ in the first part of this article, and generate source code with our template.</p>
+
+<p>When a user presses Finish on the wizard, the <tt class="code">performFinish</tt> method
+ in our wizard is called. The code below shows how we <img src="images/tag_1.gif" width="24" height="13"/>use
+ a custom subclass of JETEmitter to <img src="images/tag_2.gif" width="24" height="13"/>add
+ the jar file of our plug-in to the classpath of the <i>.JETEmitters</i> project
+ before we <img src="images/tag_3.gif" width="24" height="13"/>call generate on
+ the JETEmitter. The generated typesafe enum source code is <img src="images/tag_4.gif" width="24" height="13"/>saved
+ to the location in the workspace that the user specified.</p>
+<pre class="code"> // class NewTypesafeEnumCreationWizard
+ protected void finishPage(IProgressMonitor monitor)
+ throws InterruptedException, CoreException {
+
+ String pluginId = "org.eclipse.emf.examples.jet.article2";
+ String base = Platform.getBundle(pluginId).getEntry("/").toString();
+ String relativeUri = "templates/TypeSafeEnumeration.javajet";
+<img src="images/tag_1.gif" width="24" height="13"/> JETEmitter emitter = new JETEmitter(base + relativeUri, getClass().getClassLoader());
+<img src="images/tag_2.gif" width="24" height="13"/> emitter.addClasspathVariable("JET_TUTORIAL", pluginId);
+
+ TypesafeEnum model = mPage1.getTypesafeEnumModel();
+ IProgressMonitor sub = new SubProgressMonitor(monitor, 1);
+
+<img src="images/tag_3.gif" width="24" height="13"/> String result = emitter.generate(sub, new Object[] { model });
+ monitor.worked(1);
+
+<img src="images/tag_4.gif" width="24" height="13"/> IFile file = save(monitor, result.getBytes());
+
+ selectAndReveal(file);
+ openResource(file);
+ }</pre>
+<h3><a name="pluginxml"></a>Registering our Wizard </h3>
+<p>Our final code snippet below shows the part of our <tt class="code">plugin.xml</tt> configuration
+ file where we register our wizard as a contribution to the workbench.</p>
+<pre class="code"> &lt;extension point="org.eclipse.ui.newWizards"&gt;
+ &lt;wizard
+ name="Typesafe Enum"
+ icon="icons/newenum_wiz.gif"
+ category="org.eclipse.jdt.ui.java"
+ id="org.eclipse.emf.examples.jet.article2.ui.NewTypesafeEnumCreationWizard"&gt;
+ &lt;description&gt;
+ Create a Typesafe Enumeration
+ &lt;/description&gt;
+ &lt;class class="org.eclipse.emf.examples.jet.article2.ui.NewTypesafeEnumCreationWizard"&gt;
+<img src="images/tag_1.gif" width="24" height="13"/> &lt;parameter name="javatype" value="true"/&gt;
+ &lt;/class&gt;
+ &lt;/wizard&gt;
+ &lt;/extension&gt;
+</pre>
+<p>Now our wizard is activated when users select File &gt; New &gt; Other &gt;
+ Java &gt; Typesafe Enum from the workbench, as shown in the image below. </p>
+<p><img alt="Typesafe Enum wizard shows up in the New creation wizard" src="images/new_creation_wizard.gif"/>
+</p>
+<p>Note that we set the <tt class="code"><img src="images/tag_1.gif" width="24" height="13"/>javatype</tt>
+ attribute to true in the wizard extension element in the <tt class="code">plugin.xml</tt>
+ file. This will cause our wizard to show up as an action on the toolbar in the
+ Java Perspective, as shown in the image below.</p>
+
+<p><img alt="Typesafe Enum wizard shows up as an action on the toolbar in the Java Perspective" src="images/new_toolbar.gif"/>
+</p>
+<p></p>
+<h2><a name="conclusion"></a>Conclusion </h2>
+JET can be a great help for applications that need to generate text. Templates
+are as much of an improvement to code generation as JSP pages were to old style
+servlets.
+<p>When using JET, you need to decide whether you want to distribute your templates
+ with your application, or distribute only the template implementation classes.</p>
+<p>If your goal is to simplify the text generation capabilities of your application,
+ then using JET Nature and JET Builder to automatically translate your templates
+ is a good choice. See <a href="../Article-JET/jet_tutorial1.html">JET Tutorial
+ Part 1</a> for details. In that case you only need to distribute the translated
+ template implementation classes with your application, not the templates themselves.</p>
+<p>On the other hand, if it is important for your application that users have
+ ultimate control over the generated text, you may want to distribute the template
+ files themselves with your application. In that case, you will need to translate
+ these templates every time you generate text. The plug-in we wrote in this article
+ is an example of this type of application.</p>
+<p>This article explained what classes are available in the JET package to achieve
+ this and showed how to use these classes with an Eclipse plug-in. The appendix
+ below provides an overview of the JET API and shows how it can be used in headless
+ or standalone applications.</p>
+
+<h2><a name="appendix"></a>Appendix</h2>
+<h3><a name="jet_api_overview"></a>JET API Overview </h3>
+<b>Package org.eclipse.emf.codegen</b>
+<p></p>
+<table border="1" cellspacing="0">
+ <tbody>
+ <tr>
+ <td><b>Class</b></td>
+ <td><b>Description</b></td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt class="code">CodeGen</tt></td>
+ <td>
+ <p>The <tt class="code">CodeGen</tt> class can translate a JET template to Java source
+ code and optionally merge the template implementation Java source code
+ with an existing Java class. <tt class="code">CodeGen</tt> can be used as an Eclipse
+ headless application. The <tt class="code">run</tt> method expects a String array parameter
+ of two or three elements: </p>
+
+ <ul>
+ <li> the uri of the template to translate </li>
+ <li>the target path where the translation result should be saved </li>
+ <li>an optional <tt class="code">JMerge</tt> control model file specifying how to merge
+ the new translation result with the source code of an existing Java
+ class</li>
+ </ul>
+
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">CodeGenPlugin</tt></td>
+ <td>The plug-in class for the JET package.</td>
+ </tr>
+ </tbody>
+</table>
+<p></p>
+
+<b>Package org.eclipse.emf.codegen.jet</b>
+<p></p>
+<table border="1" cellspacing="0">
+ <tbody>
+ <tr>
+ <td><b>Class</b></td>
+ <td><b>Description</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">IJETNature</tt></td>
+
+ <td>Interface extending <tt class="code">org.eclipse.core.resources.IProjectNature</tt>.
+ Defines some of the properties that a JET nature has. Implemented by <tt class="code">JETNature</tt>.
+ Used as a filter for project property pages by the <tt class="code">org.eclipse.emf.codegen.ui</tt>
+ plugin.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETAddNatureOperation</tt></td>
+ <td>A <tt class="code">org.eclipse.core.resources.IWorkspaceRunnable</tt> for adding the
+ JET nature to a project in the workspace. Used by the <tt class="code">AddJETNatureAction</tt>
+ in the <tt class="code">org.eclipse.emf.codegen.ui</tt> plug-in.</td>
+
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETBuilder</tt></td>
+ <td>This class extends <tt class="code">org.eclipse.core.resources.IncrementalProjectBuilder</tt>.
+ When its <tt class="code">build</tt> method is invoked, it delegates to <tt class="code">JETCompileTemplateOperation</tt>
+ to translate all templates in the workspace project that have been changed
+ since the previous build. Templates must be located in one of the folders
+ specified as Template Containers in the JET Nature of the project.</td>
+
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETCharDataGenerator</tt></td>
+ <td>Responsible for a part of the template translation process. Generates
+ strings for the character data present in the template file. Used by <tt class="code">JETCompiler</tt>.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETCompiler</tt></td>
+
+ <td>This is the core class for template translation. This class is responsible
+ for translating templates to the Java source code of a template implementation
+ class. The actual translation is delegated to other classes in this package.
+ A <tt class="code">JETParser</tt> is used to parse the template into template elements.
+ <tt class="code">JETCompiler</tt> implements the <tt class="code">JETParseEventListener</tt> interface
+ and registers itself with the parser to be notified when the parser recognizes
+ a template element. For every recognized template element, <tt class="code">JETCompiler</tt>
+ uses a <tt class="code">JETGenerator</tt> to translate the template element to Java source
+ code. When the template parsing is complete, <tt class="code">JETCompiler</tt> uses a
+ <tt class="code">JETSkeleton</tt> to assemble the Java source code elements to a single
+ compilation unit (a Java class).</td>
+
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETCompileTemplateOperation</tt></td>
+ <td>This class implements <tt class="code">org.eclipse.core.resources.IWorkspaceRunnable</tt>
+ so it can execute as a batch operation within the workspace. This operation
+ takes a workspace project, one or more Template Containers and optionally
+ a list of specific template files as constructor parameters. When its <tt class="code">run</tt>
+ method is invoked, it uses a <tt class="code">JETCompiler</tt> to translate the template
+ files in the specified workspace project folders to Java source files for
+ template implementation classes. This operation can optionally be configured
+ to trigger a complete build of the project when it is finished to compile
+ the Java source files to <i>.class</i> files.</td>
+
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETConstantDataGenerator</tt></td>
+ <td>Responsible for a part of the template translation process. Extends <tt class="code">JETCharDataGenerator</tt>
+ to generate constant declarations for the strings with character data present
+ in the template file.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETCoreElement</tt></td>
+
+ <td>Interface for core JET syntax elements (directive, expression, scriptlet
+ and quote-escape). Used by <tt class="code">JETParser</tt>.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETEmitter</tt></td>
+ <td>This class provides a convenient high-level API for users of this package.
+ The <tt class="code">generate</tt> method of this class translates a template to Java
+ source code, compiles this source code to a template implementation class,
+ asks the template class to generate text and finally returns the generated
+ result. This class creates a Java project called <i>.JETEmitters</i> in
+ the workspace, translates the template into this project, and simply calls
+ <tt class="code">build</tt> on the <i>.JETEmitters</i> project to compile the source
+ code. If translation or compilation fails, a <tt class="code">JETException</tt> is thrown.
+ A template implementation Java class is "executed" by calling its <tt class="code">generate</tt>
+ method.</td>
+
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETException</tt></td>
+ <td>Extends <tt class="code">org.eclipse.core.runtime.CoreException</tt>, but provides
+ more convenient constructors.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETExpressionGenerator</tt></td>
+
+ <td>Responsible for a part of the template translation process. Extends <tt class="code">JETScriptletGenerator</tt>
+ to translate JET expressions (<tt class="code">&lt;%= ... %&gt;</tt> stuff) to Java source
+ code.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETGenerator</tt></td>
+ <td>Interface for generators: classes that know how to translate part of a
+ JET template to a Java source code element.</td>
+
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETMark</tt></td>
+ <td>A state object used by the <tt class="code">JETParser</tt> to mark points in the JET
+ character input stream, and delegate the processing of parts of the stream
+ to other objects.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETNature</tt></td>
+
+ <td>
+ <p>This class implements <tt class="code">IJETNature</tt> so that it can configure
+ a workspace project with the JET Nature. When this nature is added to
+ a project, it adds a JET Builder to the front of the build spec of the
+ project. This nature defines two properties: </p>
+ <ul>
+ <li> Template Containers - a list of folders in the project that contain
+ the JET templates to translate. </li>
+ <li>Source Container - the target folder in which to save translated template
+ implementation Java classes. </li>
+ </ul>
+
+ <p>These properties are used by the JET Builder when performing a build.</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETParseEventListener</tt></td>
+ <td>Interface for objects that know how to process parts of a JET character
+ input stream.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETParser</tt></td>
+
+ <td>The main parser class. Has several inner classes for recognizing core
+ JET syntax elements (directive, expression, scriptlet and quote-escape).
+ When a core JET syntax element is recognized, the actual processing of the
+ element is delegated to a <tt class="code">JETParseEventListener</tt>.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETReader</tt></td>
+ <td>An input buffer for the JET parser. Provides a <tt class="code">stackStream</tt> method
+ that others can call with the character stream to an include file. Also
+ provides many other convenience methods for the parser.</td>
+
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETScriptletGenerator</tt></td>
+ <td>Responsible for a part of the template translation process. Translates
+ JET scriptlets (<tt class="code">&lt;% ... %&gt;</tt> stuff) to Java source code.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JETSkeleton</tt></td>
+
+ <td>This class provides an interface for assembling Java source code elements
+ into a single Java compilation unit (a Java class). Java source code elements
+ are assembled according to a class skeleton definition. A skeleton can be
+ used to add boilerplate code to a translated template implementation class.
+ This class provides a default custom template implementation class skeleton
+ definition, but can also assemble Java elements using a custom skeleton.
+ The actual parsing and generation of Java source code is delegated to classes
+ in the <tt class="code">org.eclipse.jdt.core.jdom</tt> package.</td>
+ </tr>
+ </tbody>
+</table>
+<p></p>
+<b>Package org.eclipse.emf.codegen.jmerge</b>
+<p></p>
+<table border="1" cellspacing="0">
+ <tbody>
+ <tr>
+ <td><b>Class</b></td>
+
+ <td><b>Description</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JControlModel</tt></td>
+ <td>A control model that provides dictionaries and rules to drive a merge
+ process.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JMerger</tt></td>
+
+ <td>A class for merging Java source files. Uses classes in the <tt class="code">org.eclipse.jdt.core.jdom</tt>
+ package to parse the source code. This class can be used by application
+ code, but can also be run as an Eclipse headless application.</td>
+ </tr>
+ <tr>
+ <td valign="top"><tt class="code">JPatternDictionary</tt></td>
+ <td>A dictionary of signatures and JDOM nodes.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt class="code">PropertyMerger</tt></td>
+ <td>A class for merging property files. This class can be used by application
+ code, but can also be run as an Eclipse headless application.</td>
+ </tr>
+ </tbody>
+</table>
+<p></p>
+<h3><a name="codegen_headless_application"></a>Running CodeGen as an Eclipse Headless
+ Application </h3>
+<p>The <tt class="code">org.eclipse.emf.codegen.CodeGen</tt> class can translate a JET template to Java source code
+ and optionally merge the template implementation Java source code with an existing
+ Java class. CodeGen can be used as an Eclipse headless application ("headless"
+ means that the Eclipse GUI does not start). The <tt class="code">plugins/org.eclipse.emf.codegen/test</tt>
+ folder in your Eclipse installation contains some scripts for launching the
+ CodeGen class as an Eclipse headless application. These scripts are in Unix
+ format.</p>
+
+<p><img src="images/win_only.gif" width="49" height="13"/> Below is an example
+ script for Windows. Note that we pass two arguments to the CodeGen class:</p>
+<ul>
+ <li>the <img src="images/tag_1.gif" width="24" height="13"/>uri of the template
+ to translate </li>
+ <li>the <img src="images/tag_2.gif" width="24" height="13"/>target path where
+ the translation result should be saved </li>
+</ul>
+<p>If the target path already contains a previous translation result, and you
+ want to merge the new translation result with the existing one, you can specify
+ a <tt class="code">JMerge</tt> control model file as the third argument. The <tt class="code">plugins/org.eclipse.emf.codegen/test</tt>
+ folder in your Eclipse installation contains an example <tt class="code">merge.xml</tt> file.</p>
+
+<pre class="code"> @echo off
+ set ECLIPSE_HOME=C:\eclipse-2.1\eclipse
+ set WORKSPACE=%ECLIPSE_HOME%\workspace
+ set OPTS=-Xmx900M -Djava.compiler=NONE -verify -cp %ECLIPSE_HOME%\startup.jar
+ set MAIN=org.eclipse.core.launcher.Main -noupdate -data %WORKSPACE%
+
+<img src="images/tag_1.gif" width="24" height="13"/>set TEMPLATE_URI=test.javajet
+<img src="images/tag_2.gif" width="24" height="13"/>set TARGET_FOLDER=C:\temp\jetstandalone\MyProject
+ set ARGUMENTS=%TEMPLATE_URI% %TARGET_FOLDER%
+
+ echo Shut down Eclipse before running this script.
+ java %OPTS% %MAIN% -application org.eclipse.emf.codegen.CodeGen %ARGUMENTS%
+</pre>
+<h3><a name="jetc"></a>jetc: An ANT Task for Translating JET Templates Outside
+ of Eclipse </h3>
+<p>Author: Knut Wannheden (knut.wannheden at paranor.ch) </p>
+<p>Binary: <a href="jetc-task.jar">jetc-task.jar</a>. </p>
+<p>The source: <a href="JETCTask.java" target=_blank>JETCTask.java</a>.</p>
+
+<p>Some notes: </p>
+<ul>
+ <li>In the <tt class="code">&lt;taskdef/&gt;</tt> you have to specify the classpath to include
+ both this task as well as the jars of a number of Eclipse plug-ins (see the
+ example buildfile). </li>
+ <li>There are two ways to tell the jetc task which template(s) it should translate:
+ </li>
+ <ul>
+ <li>Use a nested fileset to specify the directory containing the template
+ files. </li>
+
+ <li>Specify the template uri in the "template" attribute of the task. When
+ used this way, the task supports the "class" and "package" attributes which
+ overload the JET directives "class" and "package" in the template. It can
+ also be used if the JET directive is missing altogether. Use this attribute
+ when you want to specify the class to generate outside the template. </li>
+ </ul>
+</ul>
+<p>Here's a simple Ant buildfile (the taskdef classpath assumes you have Eclipse
+ 2.1 and EMF 1.1.0): </p>
+<pre class="code"> &lt;project default="jetc_multiple_templates"&gt;
+
+ &lt;property name="eclipse.plugins.dir" location="C:/eclipse-2.1/eclipse/plugins"/&gt;
+
+ &lt;taskdef name="jetc" classname="ch.paranor.epla.structure.JETCTask"&gt;
+
+ &lt;classpath&gt;
+ &lt;pathelement location="jetc-task.jar"/&gt;
+ &lt;fileset dir="${eclipse.plugins.dir}"&gt;
+ &lt;include name="org.eclipse.core.boot_2.1.0/boot.jar"/&gt;
+ &lt;include name="org.eclipse.core.resources_2.1.0/resources.jar"/&gt;
+ &lt;include name="org.eclipse.core.runtime_2.1.0/runtime.jar"/&gt;
+
+ &lt;include name="org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/&gt;
+ &lt;include name="org.eclipse.jdt.core_2.1.0/jdtcore.jar"/&gt;
+ &lt;/fileset&gt;
+ &lt;/classpath&gt;
+ &lt;/taskdef&gt;
+
+ &lt;!-- Usage example 1: --&gt;
+
+ &lt;!-- Specify the template file in the "template" attribute. --&gt;
+ &lt;!-- You can use the "class" and "package" attributes to override the --&gt;
+ &lt;!-- "class" and "package" attributes in the template file. --&gt;
+ &lt;target name="jetc_single_template"&gt;
+ &lt;mkdir dir="jet-output"/&gt;
+ &lt;jetc template="test.xmljet" package="com.foo" class="Test" destdir="jet-output"/&gt;
+
+ &lt;javac srcdir="jet-output" destdir="classes"/&gt;
+ &lt;/target&gt;
+
+ &lt;!-- Usage example 2: --&gt;
+ &lt;!-- Translate a bunch of template files at once. --&gt;
+ &lt;!-- You cannot use the "class" and "package" attributes when using a fileset. --&gt;
+ &lt;target name="jetc_multiple_templates"&gt;
+
+ &lt;mkdir dir="jet-output"/&gt;
+ &lt;jetc destdir="jet-output"&gt;
+ &lt;fileset dir="jet-templates" includes="*.*jet"/&gt;
+ &lt;/jetc&gt;
+ &lt;javac srcdir="jet-output" destdir="classes"/&gt;
+ &lt;/target&gt;
+
+
+ &lt;/project&gt;</pre>
+<h2>Resources </h2>
+<p><a href="http://developer.java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums" target="_blank">Substitutes
+ for Missing C Constructs</a> (By Joshua Bloch)</p>
+<a href="http://www.javaworld.com/javaworld/javatips/jw-javatip122.html" target="_blank">
+Java Tip 122: Beware of Java typesafe enumerations</a> (By Vladimir Roubtsov)<br/>
+<p><a href="http://www.javaworld.com/javaworld/javatips/jw-javatip133.html" target="_blank">Java
+ Tip 133: More on typesafe enums</a> (By Philip Bishop)</p>
+
+<p><a href="http://www.eclipse.org/emf/">http://www.eclipse.org/emf/ </a></p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the United States, other countries, or both.</small></p>
+</body>
+</html>
diff --git a/Article-JET2/jet_tutorial2.html_old b/Article-JET2/jet_tutorial2.html_old
new file mode 100644
index 0000000..477d340
--- /dev/null
+++ b/Article-JET2/jet_tutorial2.html_old
@@ -0,0 +1,979 @@
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<title>JET Tutorial Part 2 (Write Code that Writes Code)</title>
+<link rel="stylesheet" href="default_style.css">
+<style type="text/css">
+<!--
+.jet { background-color: #FFFFCC}
+pre { color: #4444cc}
+-->
+</style>
+</head>
+
+<body LINK="#0000ff" VLINK="#800080" bgcolor="white">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2003 <a href="http://www.azzurri.jp" target="_blank">Azzurri Ltd.</a></font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">JET Tutorial Part 2 (Write Code that Writes Code)</h1>
+
+<blockquote>
+<b>Summary</b>
+
+<br>
+<p>In Part 2 of this JET (Java Emitter Templates) tutorial, we will take a look
+ at the JET engine API. You will learn how to write plug-ins that use the classes
+ in the JET package to generate Java source code.</p>
+ <p>As a real-world example, we will create a plug-in that takes user input and
+ generates a Typesafe Enumeration class. The generated source code is based
+ on a JET template that can be distributed with the plug-in, allowing users
+ of the plug-in to customize the generated code by editing the template.</p>
+<p>This article also provides a short reference to the JET API.</p>
+<p><b>By Remko Popma, Azzurri Ltd., remko.popma@azzurri.jp</b><br>
+ <font size="-1">August 26, 2003</font></p>
+</blockquote>
+
+<hr width="100%">
+
+<H2>Source Code </H2>
+<p>To run the example or view the source for code for this article you can unzip
+ <a href="jp.azzurri.jet.article2.typesafe_enum_1.0.0.zip">jp.azzurri.jet.article2.typesafe_enum_1.0.0.zip</a>
+ into your <i>plugins/</i> subdirectory. To use the example plug-in, you must
+ have the <a href="http://eclipse.org/emf/" target="_blank">EMF</a> plug-in installed.
+ I am using version 1.1.0 build 20030620_1105VL. <b>Note:</b> <i>More recent
+ versions of EMF will support UTF-8 templates and supply APIs for handling templates
+ in other encodings.</i></p>
+<H2>Introduction </H2>
+<center>
+ <TABLE border="1" cellspacing="0" width="80%" cellpadding="3">
+ <TBODY>
+ <TR>
+ <TD>
+ <p><b>Translation vs. Generation</b></p>
+ <p>An aspect of JET templates that is at first confusing is that generating
+ text takes two steps: translation and generation. The first step is
+ translating the template to a template implementation class. The second
+ step is using this template implementation class to generate the text.
+ </p>
+ <p>If your goal with JET is to generate Java source code, it can be confusing
+ that the template translation step also results in Java source code. Remember
+ that this source code is <i>not</i> the generated text. The source code
+ that is the result of the translation step is simply another form of the
+ template. </p>
+ <p>If you have used JSP and servlets before, you can think of a JET template
+ as being equivalent to a JSP page. A JET template is translated to a
+ template implementation class, just like a JSP page is translated to
+ a servlet. The second step, where the template implementation class
+ generates text, is equivalent to the servlet creating and returning
+ HTML.</p>
+ </TD>
+ </TR>
+ </TBODY>
+</TABLE>
+</center>
+
+<p><a href="../Article-JET/jet_tutorial1.html">Part
+ 1</a> of this tutorial introduced JET templates and explained how you can add
+ the JET Nature to a workspace project to have the JET Builder automatically
+ translate templates in your project to template implementation classes. </p>
+<p>In part 2 of this tutorial, we will focus on writing a plug-in that uses the
+ classes in the JET package to generate Java source code. A plug-in that generates
+ text from a JET template can no longer rely on the JET Nature and JET Builder
+ to automatically translate templates. This is because JET Nature and JET Builder
+ operate only on workspace projects, not on plug-ins. Plug-ins need to use the
+ classes in the JET package to translate their templates. </p>
+<p>The next section will discuss some of the classes in the <code>org.eclipse.emf.codegen</code>
+ package. We will see what the steps are to generate source code with JET, and
+ how the JET engine classes fit in. If you are anxious to see some code that
+ shows how to use these classes in practice, you can go straight to <a href="#example_plugin">A
+ Plug-in that Generates Source Code</a>. </p>
+
+<H2>Some JET Classes</H2>
+<p>In this section, we will take a closer look at some of the classes in the JET
+ package. They can roughly be divided into two groups: </p>
+<UL>
+ <li>Lower-level classes dealing with the nuts and bolts of translating a template
+ to a template implementation class. The <code>JETCompiler</code> class brings
+ all these lower-level classes together to provide a single API for template
+ translation. </li>
+ <li>Higher-level classes that build on top of <code>JETCompiler</code> to accomplish
+ user tasks. In Part 1 of this tutorial, we have already seen <code>JETNature</code>
+ and <code>JETBuilder</code> at work. Other high-level classes are <code>CodeGen</code>
+ and <code>JETEmitter</code>. </li>
+</UL>
+<p>The lower-level classes are not discussed in-depth in this article. For a description
+ of all classes in the <code>org.eclipse.emf.codegen</code> plug-in, see the <a href="#jet_api_overview">JET
+ API Overview</a> section below. In the rest of this section, we will focus on
+ a few of the higher-level classes.</p>
+<H4><code>org.eclipse.emf.codegen.jet.JETCompiler</code></H4>
+<p><code>JETCompiler</code> is the core class for template translation. This class
+ is responsible for translating templates to the Java source code of a template
+ implementation class. The actual translation is delegated to other classes in
+ the same package. Clients create a JETCompiler object for a particular template
+ and then call the <code>parse</code> method followed by the <code>generate</code>
+ method to write the Java source code for the resulting template implementation
+ class to a specified stream.</p>
+<H4><code>org.eclipse.emf.codegen.jet.JETEmitter</code></H4>
+<p><code>JETEmitter</code> provides a convenient high-level API for users of the
+ JET package. The <code>generate</code> method of this class combines template
+ translation and text generation into a single step. By taking care of the gory
+ details of translating templates and compiling the Java source code of the translated
+ template implementation class, JETEmitter lets you focus on the final generator
+ output.</p>
+<p>Another way of looking at JETEmitter is that it abstracts away the translation
+ step and lets you pretend that you can directly generate text with a template.
+ Following the <a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html" target="_blank">Law
+ of Leaky Abstractions</a>, we cannot always get away with this, and the <a href="#jetemitter_gotchas">JETEmitter
+ Gotchas</a> section below points to a few places where you have to be careful.</p>
+<p>JETEmitter is the class we will be using in our plug-in, so we will go into
+ a little more detail here.</p>
+<p>A JETEmitter object is constructed with the uri of the template used to generate
+ text. Any type of uri is acceptable as long as a protocol handler is available.
+ This means that <code>file:/</code> uris, <code>ftp:/</code> uris and <code>http:/</code><i>
+ </i>uris can all be used. Eclipse adds special protocol handlers for <code>platform:/base</code>/,
+ <code>platform:/plugin/</code>, <code>platform:/fragment/</code> and <code>platform:/resource/</code>
+ uris, so plug-ins can use a uri like <code>platform:/resource/myproject/myfolder/mytemplate.jet</code>
+ to specify a template file.</p>
+<p>In our example plug-in, we will distribute our template file together with our
+ plug-in, so the template file will be located in a <i>myplugin/templates/</i>
+ folder under the Eclipse <i>plugins/</i> folder. The following code can then
+ be used to locate and generate a template from this folder:</p>
+<PRE> String pluginId = "myplugin.id";
+ String base = Platform.getPlugin(pluginId).getDescriptor().getInstallURL().toString();
+ String uri = base + "templates/myTemplate.javajet";
+ JETEmitter emitter = new JETEmitter(uri);
+ String generatedText = emitter.generate(new Object[] {parameter});</PRE>
+<p>After constructing a JETEmitter object, clients then call <code>generate</code>
+ on it to generate text. The <code>generate</code> method will perform the following
+ steps:</p>
+<OL>
+ <LI>Create a project called <i>.JETEmitters</i> in the workspace
+ <li>Prepare this project by giving it the Java Nature and adding classpath variables
+ to its classpath </li>
+ <li>Translate the template to a template implementation Java source file in
+ the <i>.JETEmitters</i> project </li>
+ <li>Build the project to compile the template implementation source code to
+ a Java <i>.class</i> file </li>
+ <li>Call the <code>generate</code> method on the translated Java template implementation
+ class and return the generated text as a String</li>
+</OL>
+<p>Our example plug-in will use JETEmitter and save the generated text to a Java
+ source file in the workspace. The figure below shows the steps for generating
+ source code using JETEmitter. </p>
+<p><IMG alt="Using JETEmitter to generate text from a plugin" src="images/jetemitter.gif"> </p>
+<H3><a name="jetemitter_gotchas"></a>JETEmitter Gotchas</H3>
+<p>The JETEmitter class combines template translation and text generation into
+ a single step, which makes it a very convenient tool. However, it is important
+ that you know what takes place under the hood, otherwise you might be in for
+ some nasty surprises. This section highlights some &quot;gotchas&quot; that
+ I ran into, so that you don't make the same mistakes.</p>
+<H4>1. Plug-in Initialization Required </H4>
+<p>It is not easy to use JET outside of Eclipse. JET is designed to run only as
+ a workspace application. Any application using JET must minimally run as an
+ Eclipse &quot;headless&quot; application so that plug-in initialization takes
+ place. (The term headless refers to running Eclipse without the user interface.)</p>
+<p>This means that using JETEmitter from a simple standalone application (a standard
+ Java class with a <code>main</code> method) <i>will not work</i>:</p>
+<PRE> // This fails: cannot use JETEmitter from a standalone application
+ public static void main(String[] args) {
+ JETEmitter emitter = new JETEmitter("/myproject/templates/HelloWorld.txtjet");
+
+ // this will throw a NullPointerException
+ String result = emitter.generate(new NullProgressMonitor(), {"hi" });
+
+ System.out.println(result);
+</PRE>
+<p>Note that this is not a restriction of just the JETEmitter class, many of the
+ classes in the <code>org.eclipse.emf.codegen</code> plug-in have dependencies
+ on other plug-ins. The <a href="#appendix">Appendix</a> section below has more
+ details on using JET from standalone applications.</p>
+<p>In the rest of this article we will assume that our code is running from inside
+ a plug-in.</p>
+<H4>2. Classloader Issues </H4>
+<p>You may get a NoClassDefFoundError when you pass a custom object as the argument
+ to the <code>JETEmitter.generate</code> method. This can happen if the object
+ you pass as the argument is not one of the java "bootstrap" classes (the bootstrap
+ classes are the runtime classes in rt.jar and internationalization classes in
+ i18n.jar).</p>
+<p>To prevent this error you must specify the classloader of your plug-in when
+ using JETEmitter. If no classloader is specified, JETEmitter uses the classloader
+ of its own class, which is usually the classloader for the <code>org.eclipse.emf.codegen</code>
+ plug-in, and this classloader can't see much. In recent versions of EMF (since
+ version 1.1.0 build 20030527_0913VL), JETEmitter has a constructor that takes
+ a classloader argument.</p>
+<p>Note that another way to specify a classloader is to subclass JETEmitter in
+ your own project; if no classloader is specified, JETEmitter will use the classloader
+ of this subclass. (If you are using an older version of EMF, there are no constructors
+ that take a classloader argument and you will have no choice but to subclass
+ JETEmitter in your own project.)</p>
+<p>The example below shows an action class that translates and invokes a selected
+ template using JETEmitter. The example shows how a JETEmitter can be constructed
+ <img src="images/tag_1.gif" width="24" height="13">with a classloader parameter or by <img src="images/tag_2.gif" width="24" height="13">constructing
+ an anonymous subclass.</p>
+<PRE>package jp.azzurri.jet.article2.actionexample;
+// imports omitted
+public class EmitAction implements IActionDelegate {
+ protected ISelection selection;
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ this.selection = selection;
+ action.setEnabled(true);
+ }
+
+ public void run(IAction action) {
+ List files = (selection instanceof IStructuredSelection)
+ ? ((IStructuredSelection) selection).toList()
+ : Collections.EMPTY_LIST;
+
+ for (Iterator i = files.iterator(); i.hasNext();) {
+ IFile file = (IFile) i.next();
+ IPath fullPath = file.getFullPath();
+
+ String templateURI = "platform:/resource" + fullPath;
+ <b>Class</b><b>Loader classloader = getClass().getClassLoader();</b>
+<img src="images/tag_1.gif" width="24" height="13"> JETEmitter emitter = new JETEmitter(templateURI, <b>classloader</b>);
+
+ // <b>or: use an anonymous subclass</b>
+<img src="images/tag_2.gif" width="24" height="13"> // emitter = <b>new JETEmitter(templateURI) {}</b>; // notice the brackets
+
+ try {
+ IProgressMonitor monitor = new NullProgressMonitor();
+ String[] arguments = new String[] { "hi" };
+
+ String result = emitter.generate(monitor, arguments);
+
+ saveGenerated(result, file);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ // saveGenerated method omitted
+}
+</PRE>
+<H4>3. Classpath Issues </H4>
+<p>JETEmitter translates your templates to Java source files in the <i>.JETEmitters</i>
+ project, and invokes the JavaBuilder to compile these source files. If your
+ templates use classes that are not standard Java classes, or not in the EMF
+ plug-in, you will need to add these classes to the classpath of the <i>.JETEmitters</i>
+ project, or the JavaBuilder cannot compile the template implementation source
+ files.</p>
+<p>JETEmitter has a protected method, <code>setVariable</code>, that creates a classpath
+ variable. (Classpath variables are workspace-wide and can be seen with Window
+ &gt; Preferences &gt; Java &gt; Classpath Variables.) The <code>setVariable</code>
+ method loops through the runtime libraries of the specified plug-in, and creates
+ a classpath variable with the specified name that points to the last CODE-type
+ runtime library of the specified plug-in.</p>
+<p>If all the classes your template needs can be found in the runtime library
+ of a plug-in, you probably want to use the <code>setVariable</code> method to create
+ a variable pointing to that <i>.jar</i> file.</p>
+<p>The next step is to add this variable to the classpath of the <i>.JETEmitters</i>
+ project. Unfortunately, JETEmitter does not provide a method to do this, but
+ instead requires you to create a subclass and override the initialize method,
+ for example, to add the required variable(s). You will need to add your variable(s)
+ to the <i>.JETEmitters</i> project classpath without breaking the existing classpath.</p>
+<p><i>This is one place where the JET package is a little EMF-centric; when the
+ .JETEmitters project is created, the JETEmitter class creates a number of EMF-only
+ classpath variables and adds them to the classpath of the .JETEmitters project.
+ There is an outstanding EMF feature request for an API for adding custom classpath
+ variables to the .JETEmitters project.</i></p>
+<p> The example source for this article contains a JETEmitter subclass, <code>MyJETEmitter</code>,
+ which extends JETEmitter to provide a public API for adding classpath entries
+ to the <i>.JETEmitters</i> project. Basically, this class loops through the
+ existing classpath entries of the project, and compares this existing classpath
+ with the added entries, making sure that only missing entries are added. See
+ the example source for this article for details.</p>
+<H2><a name="example_plugin"></a>A Plug-in that Generates Source Code </H2>
+<p>In this part of the JET Tutorial, we will write an Eclipse plug-in that uses
+ a JET template to generate Java source code for typesafe enumerations.</p>
+<p>Our plug-in has to perform the following tasks:</p>
+<OL>
+ <LI>Collect user input values for the variables in our template: the class name,
+ the type and name of the attributes of the typesafe enumeration class, and
+ the values of these attributes for each instance. We will write a simple GUI
+ to collect these values.
+ <li>Translate the JET template file to a Java template implementation class</li>
+ <li>Invoke the template implementation class with an object that contains the
+ user input values collected by the GUI</li>
+ <li>Save the resulting generated source code to a location obtained from the
+ GUI</li>
+</OL>
+<p>In the following sections we will go through the steps above one by one.</p>
+<H3><a name="typesafe_enum_example"></a>Typesafe Enumerations</H3>
+<p>Let's have a look at a typesafe enumeration class to see what kind of source
+ code we want to generate. The Digit class below is an example typesafe enum.</p>
+<PRE> // an example typesafe enum
+ package x.y.z;
+ public class Digit {
+<img src="images/tag_1.gif" width="24" height="13"> public static final Digit ZERO = new Digit(0, "zero");
+ public static final Digit ONE = new Digit(1, "one");
+ public static final Digit TWO = new Digit(2, "two");
+ public static final Digit THREE = new Digit(3, "three");
+ // ...
+ public static final Digit NINE = new Digit(9, "nine");
+
+ private static final Digit[] ALL =
+ {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE};
+
+<img src="images/tag_2.gif" width="24" height="13"> private final int value;
+ private final String name;
+
+ private Digit(int value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+<img src="images/tag_3.gif" width="24" height="13"> public static Digit lookup(int key) {
+ for (int i = 0; i &lt; ALL.length; i++) {
+ if (key == ALL[i].getValue()) { return ALL[i]; }
+ }
+ // lookup failed:
+ // we have no default Digit, so we throw an exception
+<img src="images/tag_4.gif" width="24" height="13"> throw new IllegalArgumentException("No digit exists for " + key);
+ }
+
+ public int getValue() { return value; }
+ public int getName() { return name; }
+ public String toString() { return getName(); }
+ }</PRE>
+<p>Let's take a closer look at this class. First of all, the Digit class has several
+ <b><img src="images/tag_1.gif" width="24" height="13">instances</b> - the constants
+ ZERO, ONE, TWO, etc. Each instance is defined by its Java variable name, "ZERO",
+ "ONE", "TWO"..., and the values for each <b><img src="images/tag_2.gif" width="24" height="13">attribute</b>
+ of the enumeration class. Most typesafe enums have one or more attributes. The
+ Digit class has two attributes: a <code>value</code> integer and a <code>name</code>
+ String.</p>
+<p>Our example Digit class also has a <b><img src="images/tag_3.gif" width="24" height="13"><code>lookup</code></b>
+ method, which returns the instance whose <code>value</code> attribute equals
+ the specified int parameter. A lookup method introduces the concept of <b>key
+ attributes</b>. Many typesafe enums have one or more attributes that uniquely
+ distinguish one instance from another.</p>
+<p><i>Note that key attributes are not required: the Java VM guarantees that every
+ newly constructed object is unique, so it is possible to have typesafe enumerations
+ that have no attributes at all, and simply distinguish their instances with
+ the <b>==</b> instance identity operator. This works fine, but often it is convenient
+ to have a key attribute that uniquely identifies an instance, and a <code>lookup</code>
+ method that finds an instance for a specified key value.</i></p>
+<p>Our template does have a <code>lookup</code> method, so we need to decide what
+ to do if <img src="images/tag_4.gif" width="24" height="13">no instance is found
+ for the specified key value. Basically there are three options: throwing an
+ Exception, returning a designated &quot;default&quot; instance, or returning
+ <code>null</code>. Which option is best depends on the application in which
+ the class is used, so we should probably let the user decide.</p>
+<p>Now that we've studied typesafe enums in more detail, let's summarize what
+ is customizable in a typesafe enumeration:</p>
+<UL>
+ <LI>package name
+ <li>class name </li>
+ <li>attributes, where each attribute </li>
+ <UL>
+ <LI>has a type
+ <li>has a name </li>
+ <li>may be a key attribute </li>
+ </UL>
+ <li>instances, where each instance </li>
+ <UL>
+ <LI>has a name
+ <li>has a value for every attribute </li>
+ <li>may be the default instance to return for failed lookups</li>
+ </UL>
+</UL>
+<H3><a name="typesafe_enum_model"></a>A Simple Typesafe Enumeration Model </H3>
+<p>A simple model for the customizable parts of a typesafe enum could look something
+ like this:</p>
+<P></P>
+<TABLE border="1" cellspacing="0">
+ <TBODY>
+ <TR>
+ <TD><code>TypesafeEnum</code></TD>
+ </TR>
+ <TR>
+ <TD><code>getInstances() : Instance[]<br>
+ getAttributes() : Attribute[]<br>
+ getKeyAttributes() : Attribute[]<br>
+ getDefaultInstance() : Instance<br>
+ getPackageName() : String<br>
+ getClassName() : String</code></TD>
+ </TR>
+ </TBODY>
+</TABLE>
+<P></P>
+<TABLE border="1" cellspacing="0">
+ <TBODY>
+ <TR>
+ <TD><code>Instance</code></TD>
+ </TR>
+ <TR>
+ <TD><code> getName() : String<br>
+ getAttributeValues() : Properties<br>
+ getAttributeValue(Attribute) : String<br>
+ isDefault() : boolean</code></TD>
+ </TR>
+ </TBODY>
+</TABLE>
+<P></P>
+<TABLE border="1" cellspacing="0">
+ <TBODY>
+ <TR>
+ <TD><code>Attribute</code></TD>
+ </TR>
+ <TR>
+ <TD><code> getName() : String<br>
+ getType() : String<br>
+ isKey() : boolean</code></TD>
+ </TR>
+ </TBODY>
+</TABLE>
+<P></P>
+<p>In the next section we will use these classes to convert our Digit class to
+ a JET template for typesafe enumerations.</p>
+<H3><a name="typesafe_enum_template"></a>A Typesafe Enumeration Template </H3>
+<p>Now that we have a model, we can take our Digit class and replace all Digit-specific
+ code with JET scriptlets and expressions that call our model classes. The resulting
+ template could look something like this:</p>
+<PRE> <span class="jet"><span class="jet">&lt;%@ jet package="translated" imports="java.util.* article2.model.*" class="TypeSafeEnumeration" %&gt;</span></span>
+ <span class="jet"><span class="jet">&lt;% TypesafeEnum enum = (TypesafeEnum) argument; %&gt;</span></span>
+ package <span class="jet">&lt;%=enum.getPackageName()%&gt;</span>;
+
+ /**
+ * This final class implements a type-safe enumeration
+ * over the valid instances of a <span class="jet">&lt;%=enum.getClassName()%&gt;</span>.
+ * Instances of this class are immutable.
+ */
+ public final class <span class="jet">&lt;%=enum.getClassName()%&gt;</span> {
+
+ <span class="jet">&lt;% for (Iterator i = enum.instances(); i.hasNext(); ) { %&gt;</span>
+ <span class="jet">&lt;% Instance instance = (Instance) i.next(); %&gt;</span>
+
+ // <b>instance definition</b>
+ public static final <span class="jet">&lt;%=enum.getClassName()%&gt;</span> <span class="jet">&lt;%=instance.getName()%&gt;</span> =
+<img src="images/tag_1.gif" width="24" height="13"> new <span class="jet">&lt;%=enum.getClassName()%&gt;</span>(<span class="jet">&lt;%=instance.constructorValues()%&gt;</span>);
+ <span class="jet">&lt;% } %&gt;</span>
+
+ <span class="jet">&lt;% for (Iterator i = enum.attributes(); i.hasNext(); ) { %&gt;</span>
+ <span class="jet">&lt;% Attribute attribute = (Attribute) i.next(); %&gt;</span>
+
+ // <b>attribute declaration</b>
+<img src="images/tag_2.gif" width="24" height="13"> private final <span class="jet">&lt;%=attribute.getType()%&gt;</span> m<span class="jet">&lt;%=attribute.getCappedName()%&gt;</span>;
+ <span class="jet">&lt;% } %&gt;</span>
+
+ /**
+ * Private <b>constructor</b>.
+ */
+<img src="images/tag_3.gif" width="24" height="13"> private <span class="jet">&lt;%=enum.getClassName()%&gt;</span>(<span class="jet">&lt;%=enum.constructorParameterDescription()%&gt;</span>) {
+ <span class="jet">&lt;% for (Iterator i = enum.attributes(); i.hasNext(); ) { %&gt;</span>
+ <span class="jet">&lt;% Attribute attribute = (Attribute) i.next(); %&gt;</span>
+<img src="images/tag_4.gif" width="24" height="13"> m<span class="jet">&lt;%=attribute.getCappedName()%&gt;</span> = <span class="jet">&lt;%=attribute.getUncappedName()%&gt;</span>;
+ <span class="jet">&lt;% } %&gt;</span>
+ }
+
+ // <b>getter accessor methods</b>
+ <span class="jet">&lt;% for (Iterator i = enum.attributes(); i.hasNext(); ) { %&gt;</span>
+ <span class="jet">&lt;% Attribute attribute = (Attribute) i.next(); %&gt;</span>
+ /**
+ * Returns the <span class="jet">&lt;%=attribute.getName()%&gt;</span>.
+ *
+ * @return the <span class="jet">&lt;%=attribute.getName()%&gt;</span>.
+ */
+ public <span class="jet">&lt;%=attribute.getType()%&gt;</span> get<span class="jet">&lt;%=attribute.getCappedName()%&gt;</span>() {
+ return m<span class="jet">&lt;%=attribute.getCappedName()%&gt;</span>;
+ }
+
+ <span class="jet">&lt;% } %&gt;</span>
+
+ // lookup method omitted...
+ }</PRE>
+<p>As you can see, the template calls some methods that were not in the simple
+ model we introduced earlier. We have added a few convenience methods, like the
+ <code><img src="images/tag_2.gif" width="24" height="13">Attribute.getCappedName()</code>
+ and <code><img src="images/tag_4.gif" width="24" height="13">getUncappedName()</code>
+ methods. Such methods help to keep the template simple.</p>
+<p>Another example of methods we added to the model are the <code><img src="images/tag_3.gif" width="24" height="13">TypesafeEnum.constructorParameterDescription()</code>
+ method and the <code><img src="images/tag_1.gif" width="24" height="13">Instance.constructorValues()</code>
+ method. The implementation of the <code>constructorValues</code> method is shown
+ below. </p>
+<pre>// class Instance
+/**
+ * Convenience method that returns the attribute values of this instance,
+ * in the order expected by the constructor of this instance.
+ *
+ * @return a comma-separated list of all attribute values of this instance,
+ * formatted like <code>attrib1-value, attrib2-value (, ...)</code>
+ */
+public String constructorValues() {
+ StringBuffer result = new StringBuffer();
+ for (Iterator i = getType().attributes(); i.hasNext(); ) {
+ Attribute attribute = (Attribute) i.next();
+ result.append(getAttributeValue(attribute));
+ if (i.hasNext()) {
+ result.append(", ");
+ }
+ }
+ return result.toString();
+}
+</pre>
+<p>The <code>constructorValues</code> method loops through the attributes of the
+ typesafe enum, looks up the value for each attribute in the instance, and concatenates
+ these values into a string, separated by commas. For example, in our <tt>Digit</tt>
+ typesafe enum class above, this method would return <tt>&quot;0, \&quot;zero\&quot;&quot;</tt>
+ for the &quot;ZERO&quot; instance. </p>
+<p>We could have looped through the attribute values in the template, but that
+ would have made the template much more difficult to read. Pushing this logic
+ into the model made the template more readable and easier to maintain. On the
+ other hand, we lost some flexibility because users cannot customize that logic
+ anymore by editing the template. This is a trade-off you have to make. Which
+ is better depends on your template and your application.</p>
+<H3><a name="gui"></a>A GUI to Collect User Input </H3>
+<p>Now that we have a model and a template, we still need two more pieces to finish
+ our plug-in: we need a GUI to collect values from the user to populate our model
+ with, and we need to invoke our template with the populated model to generate
+ source code and save this source code to a location in the workspace.</p>
+<p>Let's start with the GUI. The workbench provides a few wizards that do something
+ similar to what we have in mind, for example the New Class, New Interface and
+ New JUnit TestCase wizards. It probably makes sense to have our GUI look similar
+ to these wizards and make it accessible from the standard menu and toolbar locations.</p>
+<p>Our wizard has three pages. The first page, shown below, looks like a simplified
+ version of the New Class wizard. In fact, we are using the same framework that
+ the New Class wizard uses, the <code>org.eclipse.jdt.ui.wizards</code> package.
+ In the first page, we collect the package name and the class name of the typesafe
+ enum, and the location where the result should be saved.</p>
+<p><IMG alt="GUI wizard page one: class, package and location of the typesafe enum" src="images/enum_gui_page1.gif">
+</p>
+<P></P>
+<p>Our second page collects information on the attributes of the typesafe enum
+ class. Every attribute has a name and a type, and may be one of the key attributes.
+ Our second wizard page is shown below:</p>
+<p><IMG alt="GUI wizard page two: attributes of the typesafe enum" src="images/enum_gui_page2.gif"></p>
+<P></P>
+<p>Our third and last wizard page, shown below, collects information on the instances
+ of the typesafe enum. The user inputs the instance name, and for each instance
+ provides values for all attributes.</p>
+<p>Finally, one of the instances may be the &quot;default&quot; instance, which
+ is the instance returned by the <code>lookup</code> method if no instance was
+ found for the specified key attribute values.</p>
+<p><IMG alt="GUI wizard page three: instances of the typesafe enum" src="images/enum_gui_page3.gif"></p>
+<H3><a name="invoke_plugin_template"></a>Invoking the Template </H3>
+<p>Now that we have a GUI to populate our model, we can finally use what we learned
+ in the first part of this article, and generate source code with our template.</p>
+<p>When a user presses Finish on the wizard, the <code>performFinish</code> method
+ in our wizard is called. The code below shows how we <img src="images/tag_1.gif" width="24" height="13">use
+ a custom subclass of JETEmitter to <img src="images/tag_2.gif" width="24" height="13">add
+ the jar file of our plug-in to the classpath of the <i>.JETEmitters</i> project
+ before we <img src="images/tag_3.gif" width="24" height="13">call generate on
+ the JETEmitter. The generated typesafe enum source code is <img src="images/tag_4.gif" width="24" height="13">saved
+ to the location in the workspace that the user specified.</p>
+<PRE> // class NewTypesafeEnumCreationWizard
+ protected void finishPage(IProgressMonitor monitor)
+ throws InterruptedException, CoreException {
+
+ String pluginId = "jp.azzurri.jet.article2.typesafe_enum";
+ String base = Platform.getPlugin(pluginId).getDescriptor().getInstallURL().toString();
+ String relativeUri = "templates/TypeSafeEnumeration.javajet";
+<img src="images/tag_1.gif" width="24" height="13"> MyJETEmitter emitter = new MyJETEmitter(base + relativeUri);
+<img src="images/tag_2.gif" width="24" height="13"> emitter.addClasspathVariable("JET_TUTORIAL", pluginId);
+
+ TypesafeEnum model = mPage1.getTypesafeEnumModel();
+ IProgressMonitor sub = new SubProgressMonitor(monitor, 1);
+<img src="images/tag_3.gif" width="24" height="13"> String result = emitter.generate(sub, new Object[] { model });
+ monitor.worked(1);
+
+<img src="images/tag_4.gif" width="24" height="13"> IFile file = save(monitor, result.getBytes());
+
+ selectAndReveal(file);
+ openResource(file);
+ }</PRE>
+<H3><a name="pluginxml"></a>Registering our Wizard </H3>
+<p>Our final code snippet below shows the part of our <code>plugin.xml</code> configuration
+ file where we register our wizard as a contribution to the workbench.</p>
+<PRE> &lt;extension point="org.eclipse.ui.newWizards"&gt;
+ &lt;wizard
+<img src="images/tag_1.gif" width="24" height="13"> javatype="true"
+ name="Typesafe Enum"
+ icon="icons/newenum_wiz.gif"
+ category="org.eclipse.jdt.ui.java"
+ class="jp.azzurri.jet.article2.ui.NewTypesafeEnumCreationWizard"
+ id="jp.azzurri.jet.article2.ui.NewTypesafeEnumCreationWizard"&gt;
+ &lt;description&gt;
+ Create a Typesafe Enumeration
+ &lt;/description&gt;
+ &lt;/wizard&gt;
+ &lt;/extension&gt;
+</PRE>
+<p>Now our wizard is activated when users select File &gt; New &gt; Other &gt;
+ Java &gt; Typesafe Enum from the workbench, as shown in the image below. </p>
+<p><IMG alt="Typesafe Enum wizard shows up in the New creation wizard" src="images/new_creation_wizard.gif">
+</p>
+<p>Note that we set the <code><img src="images/tag_1.gif" width="24" height="13">javatype</code>
+ attribute to true in the wizard extension element in the <code>plugin.xml</code>
+ file. This will cause our wizard to show up as an action on the toolbar in the
+ Java Perspective, as shown in the image below.</p>
+<p><IMG alt="Typesafe Enum wizard shows up as an action on the toolbar in the Java Perspective" src="images/new_toolbar.gif">
+</p>
+<P></P>
+<H2><a name="conclusion"></a>Conclusion </H2>
+JET can be a great help for applications that need to generate text. Templates
+are as much of an improvement to code generation as JSP pages were to old style
+servlets.
+<p>When using JET, you need to decide whether you want to distribute your templates
+ with your application, or distribute only the template implementation classes.</p>
+<p>If your goal is to simplify the text generation capabilities of your application,
+ then using JET Nature and JET Builder to automatically translate your templates
+ is a good choice. See <a href="../Article-JET/jet_tutorial1.html">JET Tutorial
+ Part 1</a> for details. In that case you only need to distribute the translated
+ template implementation classes with your application, not the templates themselves.</p>
+<p>On the other hand, if it is important for your application that users have
+ ultimate control over the generated text, you may want to distribute the template
+ files themselves with your application. In that case, you will need to translate
+ these templates every time you generate text. The plug-in we wrote in this article
+ is an example of this type of application.</p>
+<p>This article explained what classes are available in the JET package to achieve
+ this and showed how to use these classes with an Eclipse plug-in. The appendix
+ below provides an overview of the JET API and shows how it can be used in headless
+ or standalone applications.</p>
+<H2><a name="appendix"></a>Appendix</H2>
+<H3><a name="jet_api_overview"></a>JET API Overview </H3>
+<b>Package org.eclipse.emf.codegen</b>
+<P></P>
+<TABLE border="1" cellspacing="0">
+ <TBODY>
+ <TR>
+ <TD><b>Class</b></TD>
+ <TD><b>Description</b></TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>CodeGen</code></TD>
+ <TD>
+ <p>The <code>CodeGen</code> class can translate a JET template to Java source
+ code and optionally merge the template implementation Java source code
+ with an existing Java class. <code>CodeGen</code> can be used as an Eclipse
+ headless application. The <code>run</code> method expects a String array parameter
+ of two or three elements: </p>
+ <ul>
+ <li> the uri of the template to translate </li>
+ <li>the target path where the translation result should be saved </li>
+ <li>an optional <code>JMerge</code> control model file specifying how to merge
+ the new translation result with the source code of an existing Java
+ class</li>
+ </ul>
+ </TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>CodeGenPlugin</code></TD>
+ <TD>The plug-in class for the JET package.</TD>
+ </TR>
+ </TBODY>
+</TABLE>
+<P></P>
+<b>Package org.eclipse.emf.codegen.jet</b>
+<P></P>
+<TABLE border="1" cellspacing="0">
+ <TBODY>
+ <TR>
+ <TD><b>Class</b></TD>
+ <TD><b>Description</b></TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>IJETNature</code></TD>
+ <TD>Interface extending <code>org.eclipse.core.resources.IProjectNature</code>.
+ Defines some of the properties that a JET nature has. Implemented by <code>JETNature</code>.
+ Used as a filter for project property pages by the <code>org.eclipse.emf.codegen.ui</code>
+ plugin.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETAddNatureOperation</code></TD>
+ <TD>A <code>org.eclipse.core.resources.IWorkspaceRunnable</code> for adding the
+ JET nature to a project in the workspace. Used by the <code>AddJETNatureAction</code>
+ in the <code>org.eclipse.emf.codegen.ui</code> plug-in.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETBuilder</code></TD>
+ <TD>This class extends <code>org.eclipse.core.resources.IncrementalProjectBuilder</code>.
+ When its <code>build</code> method is invoked, it delegates to <code>JETCompileTemplateOperation</code>
+ to translate all templates in the workspace project that have been changed
+ since the previous build. Templates must be located in one of the folders
+ specified as Template Containers in the JET Nature of the project.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETCharDataGenerator</code></TD>
+ <TD>Responsible for a part of the template translation process. Generates
+ strings for the character data present in the template file. Used by <code>JETCompiler</code>.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETCompiler</code></TD>
+ <TD>This is the core class for template translation. This class is responsible
+ for translating templates to the Java source code of a template implementation
+ class. The actual translation is delegated to other classes in this package.
+ A <code>JETParser</code> is used to parse the template into template elements.
+ <code>JETCompiler</code> implements the <code>JETParseEventListener</code> interface
+ and registers itself with the parser to be notified when the parser recognizes
+ a template element. For every recognized template element, <code>JETCompiler</code>
+ uses a <code>JETGenerator</code> to translate the template element to Java source
+ code. When the template parsing is complete, <code>JETCompiler</code> uses a
+ <code>JETSkeleton</code> to assemble the Java source code elements to a single
+ compilation unit (a Java class).</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETCompileTemplateOperation</code></TD>
+ <TD>This class implements <code>org.eclipse.core.resources.IWorkspaceRunnable</code>
+ so it can execute as a batch operation within the workspace. This operation
+ takes a workspace project, one or more Template Containers and optionally
+ a list of specific template files as constructor parameters. When its <code>run</code>
+ method is invoked, it uses a <code>JETCompiler</code> to translate the template
+ files in the specified workspace project folders to Java source files for
+ template implementation classes. This operation can optionally be configured
+ to trigger a complete build of the project when it is finished to compile
+ the Java source files to <i>.class</i> files.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETConstantDataGenerator</code></TD>
+ <TD>Responsible for a part of the template translation process. Extends <code>JETCharDataGenerator</code>
+ to generate constant declarations for the strings with character data present
+ in the template file.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETCoreElement</code></TD>
+ <TD>Interface for core JET syntax elements (directive, expression, scriptlet
+ and quote-escape). Used by <code>JETParser</code>.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETEmitter</code></TD>
+ <TD>This class provides a convenient high-level API for users of this package.
+ The <code>generate</code> method of this class translates a template to Java
+ source code, compiles this source code to a template implementation class,
+ asks the template class to generate text and finally returns the generated
+ result. This class creates a Java project called <i>.JETEmitters</i> in
+ the workspace, translates the template into this project, and simply calls
+ <code>build</code> on the <i>.JETEmitters</i> project to compile the source
+ code. If translation or compilation fails, a <code>JETException</code> is thrown.
+ A template implementation Java class is "executed" by calling its <code>generate</code>
+ method.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETException</code></TD>
+ <TD>Extends <code>org.eclipse.core.runtime.CoreException</code>, but provides
+ more convenient constructors.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETExpressionGenerator</code></TD>
+ <TD>Responsible for a part of the template translation process. Extends <code>JETScriptletGenerator</code>
+ to translate JET expressions (<code>&lt;%= ... %&gt;</code> stuff) to Java source
+ code.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETGenerator</code></TD>
+ <TD>Interface for generators: classes that know how to translate part of a
+ JET template to a Java source code element.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETMark</code></TD>
+ <TD>A state object used by the <code>JETParser</code> to mark points in the JET
+ character input stream, and delegate the processing of parts of the stream
+ to other objects.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETNature</code></TD>
+ <TD>
+ <p>This class implements <code>IJETNature</code> so that it can configure
+ a workspace project with the JET Nature. When this nature is added to
+ a project, it adds a JET Builder to the front of the build spec of the
+ project. This nature defines two properties: </p>
+ <ul>
+ <li> Template Containers - a list of folders in the project that contain
+ the JET templates to translate. </li>
+ <li>Source Container - the target folder in which to save translated template
+ implementation Java classes. </li>
+ </ul>
+ <p>These properties are used by the JET Builder when performing a build.</p>
+ </TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETParseEventListener</code></TD>
+ <TD>Interface for objects that know how to process parts of a JET character
+ input stream.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETParser</code></TD>
+ <TD>The main parser class. Has several inner classes for recognizing core
+ JET syntax elements (directive, expression, scriptlet and quote-escape).
+ When a core JET syntax element is recognized, the actual processing of the
+ element is delegated to a <code>JETParseEventListener</code>.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETReader</code></TD>
+ <TD>An input buffer for the JET parser. Provides a <code>stackStream</code> method
+ that others can call with the character stream to an include file. Also
+ provides many other convenience methods for the parser.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETScriptletGenerator</code></TD>
+ <TD>Responsible for a part of the template translation process. Translates
+ JET scriptlets (<code>&lt;% ... %&gt;</code> stuff) to Java source code.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JETSkeleton</code></TD>
+ <TD>This class provides an interface for assembling Java source code elements
+ into a single Java compilation unit (a Java class). Java source code elements
+ are assembled according to a class skeleton definition. A skeleton can be
+ used to add boilerplate code to a translated template implementation class.
+ This class provides a default custom template implementation class skeleton
+ definition, but can also assemble Java elements using a custom skeleton.
+ The actual parsing and generation of Java source code is delegated to classes
+ in the <code>org.eclipse.jdt.core.jdom</code> package.</TD>
+ </TR>
+ </TBODY>
+</TABLE>
+<P></P>
+<b>Package org.eclipse.emf.codegen.jmerge</b>
+<P></P>
+<TABLE border="1" cellspacing="0">
+ <TBODY>
+ <TR>
+ <TD><b>Class</b></TD>
+ <TD><b>Description</b></TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JControlModel</code></TD>
+ <TD>A control model that provides dictionaries and rules to drive a merge
+ process.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JMerger</code></TD>
+ <TD>A class for merging Java source files. Uses classes in the <code>org.eclipse.jdt.core.jdom</code>
+ package to parse the source code. This class can be used by application
+ code, but can also be run as an Eclipse headless application.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>JPatternDictionary</code></TD>
+ <TD>A dictionary of signatures and JDOM nodes.</TD>
+ </TR>
+ <TR>
+ <TD valign="top"><code>PropertyMerger</code></TD>
+ <TD>A class for merging property files. This class can be used by application
+ code, but can also be run as an Eclipse headless application.</TD>
+ </TR>
+ </TBODY>
+</TABLE>
+<P></P>
+<H3><a name="codegen_headless_application"></a>Running CodeGen as an Eclipse Headless
+ Application </H3>
+<p>The <code>org.eclipse.emf.codegen.CodeGen</code> class can translate a JET template to Java source code
+ and optionally merge the template implementation Java source code with an existing
+ Java class. CodeGen can be used as an Eclipse headless application ("headless"
+ means that the Eclipse GUI does not start). The <code>plugins/org.eclipse.emf.codegen/test</code>
+ folder in your Eclipse installation contains some scripts for launching the
+ CodeGen class as an Eclipse headless application. These scripts are in Unix
+ format.</p>
+<p><img src="images/win_only.gif" width="49" height="13"> Below is an example
+ script for Windows. Note that we pass two arguments to the CodeGen class:</p>
+<UL>
+ <li>the <img src="images/tag_1.gif" width="24" height="13">uri of the template
+ to translate </li>
+ <li>the <img src="images/tag_2.gif" width="24" height="13">target path where
+ the translation result should be saved </li>
+</UL>
+<p>If the target path already contains a previous translation result, and you
+ want to merge the new translation result with the existing one, you can specify
+ a <code>JMerge</code> control model file as the third argument. The <code>plugins/org.eclipse.emf.codegen/test</code>
+ folder in your Eclipse installation contains an example <code>merge.xml</code> file.</p>
+<PRE> @echo off
+ set ECLIPSE_HOME=C:\eclipse-2.1\eclipse
+ set WORKSPACE=%ECLIPSE_HOME%\workspace
+ set OPTS=-Xmx900M -Djava.compiler=NONE -verify -cp %ECLIPSE_HOME%\startup.jar
+ set MAIN=org.eclipse.core.launcher.Main -noupdate -data %WORKSPACE%
+
+<img src="images/tag_1.gif" width="24" height="13">set TEMPLATE_URI=test.javajet
+<img src="images/tag_2.gif" width="24" height="13">set TARGET_FOLDER=C:\temp\jetstandalone\MyProject
+ set ARGUMENTS=%TEMPLATE_URI% %TARGET_FOLDER%
+
+ echo Shut down Eclipse before running this script.
+ java %OPTS% %MAIN% -application org.eclipse.emf.codegen.CodeGen %ARGUMENTS%
+</PRE>
+<H3><a name="jetc"></a>jetc: An ANT Task for Translating JET Templates Outside
+ of Eclipse </H3>
+<p>Author: Knut Wannheden (knut.wannheden at paranor.ch) </p>
+<p>Binary: <A href="jetc-task.jar">jetc-task.jar</A>. </p>
+<p>The source: <A href="JETCTask.java" target=_blank>JETCTask.java</A>. </p>
+<p>Some notes: </p>
+<UL>
+ <LI>In the <code>&lt;taskdef/&gt;</code> you have to specify the classpath to include
+ both this task as well as the jars of a number of Eclipse plug-ins (see the
+ example buildfile). </LI>
+ <li>There are two ways to tell the jetc task which template(s) it should translate:
+ </li>
+ <UL>
+ <LI>Use a nested fileset to specify the directory containing the template
+ files. </LI>
+ <li>Specify the template uri in the "template" attribute of the task. When
+ used this way, the task supports the "class" and "package" attributes which
+ overload the JET directives "class" and "package" in the template. It can
+ also be used if the JET directive is missing altogether. Use this attribute
+ when you want to specify the class to generate outside the template. </li>
+ </UL>
+</UL>
+<p>Here's a simple Ant buildfile (the taskdef classpath assumes you have Eclipse
+ 2.1 and EMF 1.1.0): </p>
+<PRE> &lt;project default="jetc_multiple_templates"&gt;
+
+ &lt;property name="eclipse.plugins.dir" location="C:/eclipse-2.1/eclipse/plugins"/&gt;
+
+ &lt;taskdef name="jetc" classname="ch.paranor.epla.structure.JETCTask"&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location="jetc-task.jar"/&gt;
+ &lt;fileset dir="${eclipse.plugins.dir}"&gt;
+ &lt;include name="org.eclipse.core.boot_2.1.0/boot.jar"/&gt;
+ &lt;include name="org.eclipse.core.resources_2.1.0/resources.jar"/&gt;
+ &lt;include name="org.eclipse.core.runtime_2.1.0/runtime.jar"/&gt;
+ &lt;include name="org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/&gt;
+ &lt;include name="org.eclipse.jdt.core_2.1.0/jdtcore.jar"/&gt;
+ &lt;/fileset&gt;
+ &lt;/classpath&gt;
+ &lt;/taskdef&gt;
+
+ &lt;!-- Usage example 1: --&gt;
+ &lt;!-- Specify the template file in the "template" attribute. --&gt;
+ &lt;!-- You can use the "class" and "package" attributes to override the --&gt;
+ &lt;!-- "class" and "package" attributes in the template file. --&gt;
+ &lt;target name="jetc_single_template"&gt;
+ &lt;mkdir dir="jet-output"/&gt;
+ &lt;jetc template="test.xmljet" package="com.foo" class="Test" destdir="jet-output"/&gt;
+ &lt;javac srcdir="jet-output" destdir="classes"/&gt;
+ &lt;/target&gt;
+
+ &lt;!-- Usage example 2: --&gt;
+ &lt;!-- Translate a bunch of template files at once. --&gt;
+ &lt;!-- You cannot use the "class" and "package" attributes when using a fileset. --&gt;
+ &lt;target name="jetc_multiple_templates"&gt;
+ &lt;mkdir dir="jet-output"/&gt;
+ &lt;jetc destdir="jet-output"&gt;
+ &lt;fileset dir="jet-templates" includes="*.*jet"/&gt;
+ &lt;/jetc&gt;
+ &lt;javac srcdir="jet-output" destdir="classes"/&gt;
+ &lt;/target&gt;
+
+ &lt;/project&gt;</PRE>
+<H2>Resources </H2>
+<p><a href="http://developer.java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums" target="_blank">Substitutes
+ for Missing C Constructs</a> (By Joshua Bloch)</p>
+<a href="http://www.javaworld.com/javaworld/javatips/jw-javatip122.html" target="_blank">
+Java Tip 122: Beware of Java typesafe enumerations</a> (By Vladimir Roubtsov)<br>
+<p><a href="http://www.javaworld.com/javaworld/javatips/jw-javatip133.html" target="_blank">Java
+ Tip 133: More on typesafe enums</a> (By Philip Bishop)</p>
+<p><a href="http://www.eclipse.org/emf/">http://www.eclipse.org/emf/ </a></p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the United States, other countries, or both.</small></p>
+</BODY>
+</HTML>
diff --git a/Article-JET2/jetc-task.jar b/Article-JET2/jetc-task.jar
new file mode 100644
index 0000000..3321291
--- /dev/null
+++ b/Article-JET2/jetc-task.jar
Binary files differ
diff --git a/Article-JET2/jp.azzurri.jet.article2.typesafe_enum_1.0.0.zip b/Article-JET2/jp.azzurri.jet.article2.typesafe_enum_1.0.0.zip
new file mode 100644
index 0000000..edc17a6
--- /dev/null
+++ b/Article-JET2/jp.azzurri.jet.article2.typesafe_enum_1.0.0.zip
Binary files differ
diff --git a/Article-JET2/org.eclipse.emf.examples.jet.article2_2.0.0.zip b/Article-JET2/org.eclipse.emf.examples.jet.article2_2.0.0.zip
new file mode 100644
index 0000000..ffc16ea
--- /dev/null
+++ b/Article-JET2/org.eclipse.emf.examples.jet.article2_2.0.0.zip
Binary files differ
diff --git a/Article-JFace Wizards/wizardArticle.html b/Article-JFace Wizards/wizardArticle.html
new file mode 100644
index 0000000..e22e36f
--- /dev/null
+++ b/Article-JFace Wizards/wizardArticle.html
@@ -0,0 +1,484 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML><HEAD><TITLE>Creating JFace Wizards</TITLE>
+<META http-equiv=Content-Type content="text/html; charset=windows-1252">
+<LINK href="../../default_style.css" rel=stylesheet>
+<META content="MSHTML 5.50.4915.500" name=GENERATOR></HEAD>
+<BODY vLink=#800080 link=#0000ff>
+<DIV align=right>&nbsp; <FONT face="Times New Roman, Times, serif"
+size=2>Copyright
+ &copy; 2002 International Business Machines Corp.</FONT>
+<TABLE cellSpacing=0 cellPadding=2 width="100%" border=0>
+ <TBODY>
+ <TR>
+ <TD vAlign=top align=left bgColor=#0080c0 colSpan=2><B><FONT
+ face=Arial,Helvetica><FONT color=#ffffff>&nbsp;Eclipse Corner
+ Article</FONT></FONT></B></TD></TR></TBODY></TABLE></DIV>
+<DIV align=left>
+<H1><IMG height=86 src="wizards_files/Idea.jpg" width=120></H1></DIV>
+<P>&nbsp;</P>
+<H1 align=center>Creating JFace Wizards</H1>
+<BLOCKQUOTE><B>Summary</B> <BR>This article shows you how to implement a wizard using the JFace toolkit and how to contribute your wizard to the Eclipse workbench. A wizard whose page structure changes according to user input is implemented to demonstrate the flexibility of wizard support.<P><B>By Doina Klinger, IBM UK</B>(<FONT
+ face=arial,helvetica,geneva size=-1>dklinger at
+ uk.ibm.com)</FONT><BR>
+ <FONT size=-1>December 16, 2002</FONT> </P>
+</BLOCKQUOTE>
+<HR width="100%">
+
+<H2>Introduction</H2>
+<P>Wizards are used extensively throughout Eclipse. You can use wizards to create a new Java class or new resources
+like Projects, Folders or Files. A well designed wizard can considerably simplify user tasks and increase productivity.</P>
+<P> Wizards are meant to take the hassle out of standard, repetitive, or
+tedious user tasks. For example, the Java New Class wizard can collect
+enough information to generate a skeleton implementation of a user's class,
+including package statements, constructors, inherited methods, and other
+details. Of course, as the wizard developer, you must implement the code
+that makes the wizard useful for your domain.</P>
+
+
+<P>Not only does the platform contain many wizards, but there is a lot of
+support for writing your own. The JFace wizard framework lets you
+concentrate on the specifics of your wizard implementation. You will need to use the <B>org.eclipse.jface.wizard</B> package of JFace. It is very easy to get started while the support is flexible enough to allow you to add more complex logic to your wizards.</P><H2>Wizard sample</H2>
+<P>Our sample wizard will gather some holiday travel choices from the user and collect more information based on the
+user's initial choices. Information about the holiday is kept in a model data object which is manipulated by the wizard page. The user's holiday data will be displayed in an information dialog upon completion of the wizard.</P>
+
+
+<H3>Running the wizard</H3>
+<P>To run the sample or view its source, unzip the <A href="wizardsPlugin.jar">wizardsPlugin.jar</A>
+ into your eclipse root directory and restart the workbench. You can start the
+ sample wizard from the New button or from File-&gt;New menu of the workbench
+ (<A href="#NewMenu">Figure 5</A>). Alternatively, you can select the context
+ menu of a folder (in any perspective) and start the wizard from there (<A href="#PopupMenu">Figure
+ 6</A>).</P>
+<P>
+Let's look at our sample wizard in detail before diving into details of implementing it. On the first page the users can select the dates of travel, the type of transport for their holiday and enter the departure and destination locations:</P>
+<CENTER> <IMG border="0" src="wizards_files/mainPage.gif"><BR>
+Figure 1. Starting page of the wizard</CENTER>
+<P>The next page to be shown depends on the selected mode of transport. If the
+ user has selected travel by plane the following page is displayed which shows
+ the available flights. To keep the example code simple this information will
+ be hard coded, rather than obtained from some database. The user can select
+ the type of seat they want and to ask for the ticket price by pushing the &quot;Get
+ price&quot; button. The base price is hard-coded as well. A discount is offered
+ in conditions explained <A href="#Discount">below</A>.</P>
+<CENTER> <IMG border="0" src="wizards_files/plane.gif"><BR>
+Figure 2. Page displayed when the user has selected the plane</CENTER>
+<P>When the user has selected a flight and a type of seat the wizard can be finished.</P>
+<P>If the user has selected the car as mode of transport, a different page is
+ shown. The user can select the name of a rental company. Based on the company
+ name, the price of the rented car is displayed. Once again, the prices are hard-coded
+ and depend only on the rental company selected but not on dates and destination.
+ The user can select whether to buy insurance from the rental company.</P>
+
+<CENTER> <IMG border="0" src="wizards_files/car.gif"><BR>
+Figure 3. Page displayed when the user has selected the car.</CENTER>
+<P>When the user clicks Finish a message dialog is displayed summarizing the holiday data collected from the user. The wizard
+responds to various events and reports user errors.</P>
+<P>This article explains the following:</P>
+<UL>
+ <LI>how to create, add and initialize wizard pages</LI>
+ <LI>how to listen for events and control errors</LI>
+ <LI>how to change the page order</LI>
+ <LI>what to do on completion of a wizard</LI>
+ <LI>how to start a wizard</LI>
+</UL>
+
+
+<H2>Wizard pages</H2>
+<P>JFace provides the interfaces <B>org.eclipse.jface.wizard.IWizard</B> and <B>org.eclipse.jface.wizard.IWizardPage</B> to describe wizards and corresponding implementation
+classes that handle many of the details of implementing wizards. Our wizard class HolidayWizard extends <B>org.eclipse.jface.wizard.Wizard</B>, which is a useful abstract class to extend.
+Its main responsibilities are to create the pages inside the wizard and perform the work when the wizard is completed.
+</P>
+
+
+<H3><FONT size="+1"><FONT size="+1">Adding pages to a wizard</FONT></FONT></H3>
+
+
+<P> Each page is instantiated and added to the wizard. The order in which we add the pages to the wizard is the default navigation order. The page which is added first will be the starting page when the wizard is
+opened. Later we will look at ways of changing these defaults. The corresponding method on the HolidayWizard class is shown below:</P>
+<BLOCKQUOTE><PRE><CODE>public void addPages()
+{
+ holidayPage = new HolidayMainPage(workbench, selection);
+ addPage(holidayPage);
+ planePage = new PlanePage(&quot;&quot;);
+ addPage(planePage);
+ carPage = new CarPage(&quot;&quot;);
+ addPage(carPage);
+}</CODE></PRE></BLOCKQUOTE>
+<P></P><H3><FONT size="+1">Creating the controls</FONT></H3>
+<P>First you need to decide which controls you want to use and then how they should appear on the wizard page. Here is a quick guideline on common widgets choices:</P>
+<UL>
+ <LI>text fields : use them when you cannot predict what the user will enter. In our example, we let the users type in any holiday destination they want.</LI>
+ <LI>combo boxes : use them to indicate a single selection from several options. The user can select only one type of seat in the plane: window, aisle or center.</LI>
+ <LI>lists: use them to display many options from which one or more can be selected. We show the available flights in a list widget.</LI>
+ <LI>buttons: there are three styles of buttons in SWT.
+ <UL>
+ <LI>checkboxes: use them to show options with clear &quot;yes&quot; or &quot;no&quot; meaning. When you rent a car, you either take the insurance from the rental company or you don't.</LI>
+ <LI>radio buttons: use them when you want the user to select one options from two or more options. In our simplified model, you can either travel by car or by plane.</LI>
+ <LI>push buttons: use them to trigger an event. The button on the plane page retrieves the price for the flight.</LI>
+ </UL>
+ </LI>
+</UL>
+<P>Widgets of type <B>org.eclipse.swt.widgets.Composite</B> are used to hold other widgets. To create a widget of one of the types mentioned above, you call its
+constructor and pass the parent Composite and a mask of bits indicating the
+style. </P>
+
+<P>More information about various widgets can be found in the Javadoc for <strong>org.eclipse.swt.widgets</strong>,
+ and <A
+href="http://dev.eclipse.org/help20/content/help:/org.eclipse.platform.doc.isv/guide/swt.htm" target="_blank">
+ SWT documentation</A>. </P>
+
+<P>You will need to use <I style="mso-bidi-font-style: normal">layouts</I> to
+ give your wizard page a specific look. A layout controls the position and size
+ of children in a Composite. In our sample, we use <SPAN lang="EN-US" style="mso-ansi-language: EN-US"><B>org.eclipse.swt.layout.GridLayout</B>,
+ which is one of the most flexible standard layouts. With a <I></I>GridLayout,
+ the widget children of a Composite are laid out in a grid, left to right, top
+ to bottom. The <I><B style="mso-bidi-font-weight: normal">numColumns</B></I>
+ specifies the number of columns in the grid. GridData is the layout data object
+ associated with GridLayout. With a GridData object you can control things like
+ the widget's alignment, indent or span, horizontally and vertically. Use <I><B>setLayoutData</B></I>
+ method to set the grid data of a widget</SPAN>. For more details on layouts
+ see the <A href="http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm" target="_blank">Understanding
+ Layouts</A> article.</P>
+<P>We start by hand-drawing a rough sketch of each wizard page, to find out the number of columns of the grid and the general look of the page. For a better organization of the information on the page, we use horizontal rules to separate related groups of input fields.</P>
+<P>The place to create the page controls and arrange them on a page is the <I><B>createControl</B></I> method or each wizard page. The method is invoked once for each page when the wizard is first created with a parameter of type Composite. A typical implementation of this method is shown below. It does the
+following tasks::</P>
+<UL>
+ <LI>create a composite using the specified parent (<IMG border="0" src="wizards_files/tag_1.gif">)</LI>
+ <LI>construct the widgets and, if necessary, their layout data objects (<IMG border="0" src="wizards_files/tag_2.gif">)</LI>
+
+ <LI>construct the widgets and, if neccesary, their layout data objects(<IMG border="0" src="wizards_files/tag_3.gif">)</LI>
+ <LI>set the composite as the control associated with the wizard page (<IMG border="0" src="wizards_files/tag_4.gif">).</LI>
+</UL>
+<P>Here is a simplified implementation of the createControl method for the HolidayMainPage. Some details have been omitted for brevity.</P>
+<BLOCKQUOTE><PRE>public void createControl(Composite parent) {
+ // create the composite to hold the widgets
+<IMG border="0" src="wizards_files/tag_1.gif"> Composite composite = new Composite(parent, SWT.NONE);
+ // create the desired layout for this wizard page
+<IMG border="0" src="wizards_files/tag_2.gif"> GridLayout gl = new GridLayout();
+ int ncol = 4;
+ gl.numColumns = ncol;
+ composite.setLayout(gl);
+ // create the widgets and their grid data objects
+ // Date of travel
+<IMG border="0" src="wizards_files/tag_3.gif"> new Label (composite, SWT.NONE).setText("Travel on:");
+ travelDate = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+ GridData gd = new GridData();
+ gd.horizontalAlignment = GridData.BEGINNING;
+ gd.widthHint = 25;
+ travelDate.setLayoutData(gd);
+
+ travelMonth = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+ travelMonth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ travelYear = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+ travelYear.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Similar widgets are constructed for date of return ...
+ createLine(composite, ncol);
+ // Departure
+ new Label (composite, SWT.NONE).setText("From:");
+ fromText = new Text(composite, SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = ncol - 1;
+ fromText.setLayoutData(gd);
+
+ // Similar for Destination ...
+ createLine(composite, ncol);
+
+ // Travel by plane
+ planeButton = new Button(composite, SWT.RADIO);
+ planeButton.setText("Take a plane");
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = ncol;
+ planeButton.setLayoutData(gd);
+ planeButton.setSelection(true);
+
+ // Similar for carButton ...
+ // set the composite as the control for this page
+<IMG border="0" src="wizards_files/tag_4.gif"> setControl(composite);
+}</PRE></BLOCKQUOTE>
+
+<H2><FONT size="+1">Events</FONT></H2>
+<P>Our wizard is not very useful if it is not able to respond to changes and user interaction.
+The simplest way to register events on wizard controls is to use the addListener method to register the wizard page
+itself as the handler of the events.The wizard page must implement the <B>org.eclipse.swt.widgets.Listener</B> interface with its
+handleEvent method.
+Classes which implement this interface are described within SWT as providing the
+<EM>untyped listener</EM> API. <CODE></CODE>The listeners implement a simple <B><I>handleEvent(...)</I></B> method
+that is used internally by SWT to dispatch events. </P>
+<P>In our Plane page we want to know when the user interacts with the &quot;Get price&quot; button, with the list of flights and with the combo box that holds the seats choices. We add listeners in the createControl method for these widgets.The untyped event mechanism uses a constant to identify the type of event. In our case we are interested in Selection type events for the widgets.</P>
+
+<PRE><CODE><BLOCKQUOTE>
+public void createControl(Composite parent) {
+ // ...
+ // price button
+ priceButton = new Button(composite, SWT.PUSH);
+ priceButton.addListener(SWT.Selection, this);
+ // ...
+
+ // flights
+ flightsList = new List(composite, SWT.BORDER | SWT.READ_ONLY );
+ flightsList.addListener(SWT.Selection, this);
+ // ...
+
+ // seat choice
+ seatCombo = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+ seatCombo.addListener(SWT.Selection, this);
+ // ...
+}</BLOCKQUOTE></CODE></PRE>
+
+<P> When the specified event occurs, the handleEvent method is invoked for each registered listener. The
+listener, in our case the WizardPage, implements a "case style" listener in which we check for various fields of the event parameter (like its type or source) and respond accordingly. For the PlanePage, we do some special action if the priceButton has been selected, informing the user of the flight price. </P>
+<P><A name="getPrice"></A></P>
+<PRE><CODE><BLOCKQUOTE>public void handleEvent(Event e)
+{
+ if (e.widget == priceButton) {
+ if (flightsList.getSelectionCount() &gt;0) {
+ if (((HolidayWizard)getWizard()).model.discounted)
+ price *= discountRate;
+ MessageDialog.openInformation(this.getShell(),&quot;&quot;, &quot;Flight price &quot;+ price);
+ }
+ }
+ //...
+}</BLOCKQUOTE></CODE></PRE>
+<H1><FONT size="+1">Processing errors</FONT></H1>
+<P>The data entered by the user on a wizard page can have a number of errors caused by wrong choices or invalid values.
+Where appropriate, we should disable the options which are not valid in order to prevent such errors. Where this is not possible, we need to inform the user of the error. When the user corrects it the error message needs to be cleared. </P>
+<P>In the sample we disallow destinations to be the same as the departures (not much of a holiday, is it?). No travel back in time is allowed either, so the date of return needs to be after the date of travel. We won't check that the dates are correct. Hopefully you will not find any flight on the 30th of February anyway.</P>
+<CENTER> <IMG border="0" src="wizards_files/error.gif"><BR>
+Figure 4. Reporting an error to the user.</CENTER>
+<P>You can use the <B><I>setMessage</I></B> and <B><I>setErrorMessage</I></B> methods to display information or error messages. The user can
+interact with the controls in any order and, consequently, produce or clear various errors.
+A common way to handle errors is to use a status variable for each possible type of event which can create an error, a
+warning or an information message. </P>
+<P>The error handling for the first page is shown below. If the destination or departure fields have triggered the event <IMG border="0" src="wizards_files/tag_5.gif">, the the corresponding <B>org.eclipse.core.runtime.IStatus</B> variable, is either set with an error if the two are the same or cleared. If any of the date fields was modified <IMG border="0" src="wizards_files/tag_6.gif">, we set the timeStatus variable to the right value. At the end of each processing of an event <IMG border="0" src="wizards_files/tag_7.gif">, we update the page to display the most serious error message. This can be the first error or the first warning if there is no error or null if the page is correct. When the page is correct, we should see again the page description. This is how the sample code looks:</P>
+
+<BLOCKQUOTE><PRE><CODE>public void handleEvent(Event event) {
+ // Initialize a variable with the no error status
+ Status status = new Status(IStatus.OK, &quot;not_used&quot;, 0, &quot;&quot;, null);
+ // If the event is triggered by the destination or departure fields
+ // set the corresponding status variable to the right value
+<IMG border="0" src="wizards_files/tag_5.gif"> if ((event.widget == fromText) || (event.widget == toText)) {
+ if (fromText.getText().equals(toText.getText()))
+ status = new Status(IStatus.ERROR, &quot;not_used&quot;, 0,
+ &quot;Departure and destination cannot be the same&quot;, null);
+ destinationStatus = status;
+ }
+ // If the event is triggered by any of the date fields set
+ // corresponding status variable to the right value
+<IMG border="0" src="wizards_files/tag_6.gif"> if ((event.widget == returnDate) || (event.widget == returnMonth)
+ || (event.widget == returnYear) || (event.widget == travelDate)
+ || (event.widget == travelMonth) || (event.widget == travelYear)) {
+ if (isReturnDateSet() &amp;&amp; !validDates())
+ status = new Status(IStatus.ERROR, &quot;not_used&quot;, 0,
+ &quot;Return date cannot be before the travel date&quot;, null);
+ timeStatus = status;
+ }
+
+ // Show the most serious error
+<IMG border="0" src="wizards_files/tag_7.gif"> applyToStatusLine(findMostSevere())
+ // ...
+}
+</CODE></PRE> </BLOCKQUOTE>
+
+<P> </P>
+<H2><FONT size="+1">Navigation buttons</FONT></H2>
+<P>Using the JFace wizard support we can easily manage the navigation buttons on the wizard pages. These buttons can be Finish and Cancel if the wizard has one page, otherwise each wizard page has Back, Next, Finish and Cancel. By default, Next is enabled for all but the last page and Back for all pages but the first. .</P>
+<P>For correct navigation we need to:</P>
+<OL>
+ <LI>implement the <B><I>canFlipToNextPage</I></B> method on the page to return true when the user has selected/entered all the required information on the current page.
+ </LI>
+ <LI>overwrite the <I><B>canFinish</B></I> method of of the wizard to return true when the wizard can be completed</LI>
+ <LI>ensure that the methods from above are called at the right moment to enable/disable the Next and Finish buttons</LI>
+</OL>
+<P>We look at each of these steps in a little more detail.</P>
+<OL>
+ <LI><P>To implement the canFlipToNextPage method for the first page of our wizard, we first prevent the user from moving to the next page when the page has any errors. When there are no errors, the destination and departure fields are filled, the return date is set and a mode of transport is selected, the user can move to the next page.</P><PRE><CODE>
+public Boolean canFlipToNextPage(){
+ if (getErrorMessage() != null) return false;
+ if (isTextNonEmpty(fromText)&amp;&amp; isTextNonEmpty(toText) &amp;&amp; (planeButton.getSelection()
+ || carButton.getSelection()) &amp;&amp; isReturnDateSet())
+ return true;
+ return false;
+}</CODE></PRE>
+
+ </LI>
+ <LI>Overwriting the canFinish method on the wizard class is useful when some fields or entire pages are optional. When we have all the required information for the current path through the wizard, canFinish should true and the wizard can be completed at any moment after this. </LI>
+ <LI> You can force the update of the navigation buttons. The right moment for this depends on your problem and the implementation of canFlipToNextPage and canFinish methods. If we have registered listeners for all type of events that can affect the enabled/disabled status of Next and Finish button, then at the end of the event processing method we force the redraw of the buttons:<PRE><CODE>public void handleEvent(Event event) {
+ //...
+ getWizard().getContainer().updateButtons();
+}
+</CODE></PRE></LI>
+
+</OL>
+
+
+<H1><FONT size="+1">Changing the page order</FONT></H1>
+<P>We can change the order of the wizard pages by overwriting the <B><I>getNextPage</I></B> method of any wizard page.Before leaving the page, we save in the model the values chosen by the user. In our example, depending on the choice of travel the user will next see either the page with flights or the page for travelling by car.</P>
+
+<BLOCKQUOTE><PRE> <CODE>
+<A name="initialize"></A>
+public IWizardPage getNextPage(){
+ saveDataToModel();
+ if (planeButton.getSelection()) {
+ PlanePage page = ((HolidayWizard)getWizard()).planePage;
+<IMG border="0" src="wizards_files/tag_1.gif"> page.onEnterPage();
+ return page;
+ }
+ // Returns the next page depending on the selected button
+ if (carButton.getSelection()) {
+ return ((HolidayWizard)getWizard()).carPage;
+ }
+ return null;
+}
+</CODE></PRE> </BLOCKQUOTE>
+<H1><FONT size="+1">Initializing widgets on wizard pages</FONT></H1>
+<P>The widgets can be initialized based on constants, values available on the start of the wizard or other user choices. We look at each case more closely. </P>
+<UL>
+ <LI>constants: the widgets can be initialized immediately after their creation. In the sample, we initialize the travel date with today's date.</LI>
+ <LI>values available at the start of the wizard.
+ <P><A name="Discount"></A>In our example, if the user starts the wizard when a folder called Discounts is selected, he will get 10% off the price of flights (You would want to get discounts this way, wouldn't you?). To achieve this, we need to overwrite the <B><I>init</I></B> method on the wizard<B></B> class. If the parameter representing the selection is the special folder, we know that we'll offer a discount so we cache this information. </P>
+ <PRE><CODE>
+public void init(IWorkbench workbench, IStructuredSelection selection) {
+ this.workbench = workbench;
+ this.selection = selection;
+ if (selection != null && !selection.isEmpty()) {
+ Object obj = selection.getFirstElement();
+ if (obj instanceof IFolder) {
+ IFolder folder = (IFolder) obj;
+ if (folder.getName().equals("Discounts"))
+ model.discounted = true;
+ }
+ }
+}</CODE></PRE><P>In our example, we initialize the model data based on the selection field and use it when displaying the flight price, see <A href="#getPrice">above</A> . In other examples, we might need to initialize controls on the page with the selection values.The controls are not created when the init method is called, but we can initialize them as soon as they are created with the cached value.</P>
+ <P>For wizards which are started by defining a wizard contribution (see <A href="#startWizard">Starting a wizard</A> section), the init method is called by the platform, otherwise we need to call it explicitly.</P>
+ </LI>
+ <LI>
+ user choices</LI>
+
+
+
+</UL>
+<P>We can initialize the values of some controls based on values for other controls as defined by the user at runtime. For example, in the CarPage we assign the value of the price field based on the rental company that was selected<BLOCKQUOTE><PRE> <CODE>
+public void handleEvent(Event e)
+{
+ if (e.widget == companyCombo) {
+ if (companyCombo.getSelectionIndex() &gt;=0)
+ priceText.setText(&quot;£&quot;+prices[companyCombo.getSelectionIndex()]);
+ }
+// ...
+}</CODE></PRE></BLOCKQUOTE>
+<P>In another example, the source widgets are on one page and the widgets
+whose values are initialized belong to subsequent page. Such is the case
+in our example, where the departure and destination from the first page is
+used to show. </P>
+
+<P>We define a method to do this initialization for the PlanePage, onEnterPage and we invoke this method when moving to the PlanePage, that is in the <A href="#initialize">getNextPage (<IMG border="0" src="wizards_files/tag_1.gif">)</A> method for the first page.</P>
+<H1><FONT size="+2">Actions on completion of the wizard</FONT></H1>
+<P>To complete a wizard, the user can press either the Finish or the Cancel buttons. If the Cancel button is pressed, the
+<B><I>performCancel</I></B> method is called and you should overwrite this to cleanup any resources allocated while running the wizard.
+The real work is done in <B><I>performFinish</I></B>. In our case, this method is quite simple:</P>
+<BLOCKQUOTE><PRE> <CODE>
+public boolean performFinish()
+{
+ String summary = model.toString();
+ MessageDialog.openInformation(workbench.getActiveWorkbenchWindow().getShell(),
+ "Holiday info", summary);
+ return true;
+}
+</CODE></PRE></BLOCKQUOTE>
+
+
+<P>
+If possible, it is always best to subclass from an existing wizard or wizard page
+which performs a similar task.
+A good place to look for such wizards for subclassing are<B> org.eclipse.ui.newresource</B> package which provides standard wizards for creating files, folders, and projects in the workspace and <B>org.eclipse.ui.wizards.datatransfer</B> package for the standard Import and Export wizards for moving resources into and out of the workspace. &nbsp;</P>
+<P>For example, if we want to save the user choices in a file we would have the first page inherit from the class <B>org.eclipse.ui.dialogs.WizardNewFileCreationPage</B>, which is the standard main page for a wizard that creates a file resource. We would inherit the actual file creation from the parent class and could overwrite one of its method getInitialContents() to return the user choices to be saved in the file.</P>
+
+<P>The task to be completed at the end of the wizard could be a complex operation that modifies many workspace resources,
+files, classes or projects. This sort of operation could take a relatively long time. To keep the workbench responsive to
+user input or to give the user the possibility to cancel the operation we might want to run it in a different thread.
+To achieve all these, we create a runnable which performs the task and runs it in the context of the container of the
+wizard.</P>
+<PRE>getContainer().run(forkable, canceleable, runnable);</PRE>
+<P>For more details on this subject see <A
+href="http://dev.eclipse.org/help20/content/help:/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/operation/package-summary.html" target="_blank">
+ JFace operations documentation</A>. </P>
+<H2><A name="startWizard"></A>Starting a wizard</H2>
+<P>You can start a wizard either by defining a wizard contribution to the workbench or explicitly in your code. We will look at each of these methods in turn.</P>
+<H3>Defining a wizard contribution</H3>
+<P>You can contribute to the extension points for wizards that create new resources, import or export resources. When you select the new, import, or export menu or when you press the new wizard button, the workbench uses a wizard selection dialog to display all the wizards that have been contributed for that particular extension point.&nbsp;</P>
+<P><A name="NewMenu"></A></P>
+<CENTER>
+<P><IMG border="0" src="wizards_files/newWizard.gif"></P>
+Figure 5. Starting the wizard from the New</CENTER>
+<P>In our sample, we contribute to the new wizard extension point. The relevant fragment from plugin.xml is :</P>
+<BLOCKQUOTE><PRE><CODE>
+<P>&lt;extension id=&quot;com.xyz.article.wizards&quot;
+ name=&quot;Holiday&quot;
+ point=&quot;org.eclipse.ui.newWizards&quot;&gt;
+ &lt;category
+ name=&quot;Article Wizards&quot;
+ id=&quot;com.xyz.article.wizards.category1&quot;&gt;
+ &lt;/category&gt;
+ &lt;wizard
+ name=&quot;Holiday Document&quot;
+ icon=&quot;icons/create.gif&quot;
+ category=&quot;com.xyz.article.wizards.category1&quot;
+<IMG border="0" src="wizards_files/tag_1.gif"> class=&quot;com.xyz.article.wizards.HolidayDocumentWizard&quot;
+ id=&quot;com.xyz.article.wizards.wizard1&quot;&gt;
+ &lt;description&gt;
+ Creates a holiday document
+ &lt;/description&gt;
+ &lt;/wizard&gt;
+&lt;/extension&gt;</P></CODE></PRE></BLOCKQUOTE>
+<P>We define the category to which we add our wizard, the name, description and icon that will be used. The most important entry in the extension point is the class field( <IMG border="0" src="wizards_files/tag_1.gif">) where we give the name of our wizard class. A class used in this way must implement the (empty) <B>org.eclipse.ui.INewWizard</B> interface. This is all we need to do in this case. Some details are handled by the workbench as we will see below.</P>
+<H3>Starting the wizard explicitly</H3>
+<P> You may want to launch your wizard as a result of some action that you have defined. Typically you use extension points that contribute to various menus and toolbars in the workbench and want the wizard to be started when the user interacts with these, for example when pressing a button or selecting a menu option.</P>
+<P>In our example, we use the popupMenu extension point for a folder to start the wizard. </P>
+<P><A name="PopupMenu"></A></P><CENTER>
+<P><IMG border="0" src="wizards_files/popup.gif"></P>
+<P>Figure 6. Starting the wizard from the popup menu</P>
+</CENTER>
+<P>In the plugin.xml we have:</P><PRE><CODE>
+<P> &lt;extension point=&quot;org.eclipse.ui.popupMenus&quot;&gt;
+ &lt;objectContribution
+<IMG border="0" src="wizards_files/tag_2.gif"> objectClass=&quot;org.eclipse.core.resources.IFolder&quot;
+ id=&quot;com.xyz.article.wizards.popup1&quot;&gt;
+ &lt;action
+ label=&quot;Create holiday document&quot;
+ icon=&quot;icons/create.gif&quot;
+<IMG border="0" src="wizards_files/tag_3.gif"> class=&quot;com.xyz.article.wizards.CreateWizardAction&quot;
+ id=&quot;com.xyz.article.wizards.action1&quot;&gt;
+ &lt;/action&gt;
+ &lt;/objectContribution&gt;
+&lt;/extension&gt;</P></CODE></PRE><P>The objectClass entry (<IMG border="0" src="wizards_files/tag_2.gif">) defines the type of objects to which this popupMenu will be added to, in our case a Folder. The real work is done by the action class defined on <CODE><IMG border="0" src="wizards_files/tag_3.gif"></CODE>. Its run method is executed when the user selects this new item from the popup menu of a folder. The other two methods on the action class, <B><I>setActivePart</I></B> and <B><I>selectionChanged</I></B> cache the workbench part and the selection fields respectively for use when the wizard is started, see <IMG border="0" src="wizards_files/tag_4.gif"> below. For more details on the popup menu extension point see the documentation.</P>
+<P>When you are launching your own wizard, you need to wrap the wizard in a <A href=http://dev.eclipse.org/help20/content/help:/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/wizard/WizardDialog.html target="_blank"><B>org.eclipse.jface.wizard.WizardDialog</B></A>.
+ A WizardDialog is a container that can host a wizard and display wizard pages.
+ It has a standard layout: an area at the top containing the wizard's title,
+ description, and image; the actual wizard page appears in the middle; below
+ it is a progress indicator; and at the bottom is an area with a message line
+ and a button bar containing Next, Back, Finish, Cancel, and Help buttons.</P>
+<P>The relevant code to start the wizard is:</P>
+<PRE> // Instantiates and initializes the wizard
+ HolidayWizard wizard = new HolidayWizard();
+<IMG border="0" src="wizards_files/tag_4.gif"> wizard.init(part.getSite().getWorkbenchWindow().getWorkbench(),
+ (IStructuredSelection)selection);
+ // Instantiates the wizard container with the wizard and opens it
+ WizardDialog dialog = new WizardDialog(shell, wizard);
+ dialog.create();
+ dialog.open();</PRE>
+<H1><FONT size="+2">Resources</FONT></H1>
+<P>
+We have seen how to implement a wizard, initialize its contents, and
+perform actions on its completion. For further information about wizards
+and controls, see the following resources:
+
+<P><A href="http://dev.eclipse.org/help20/content/help:/org.eclipse.platform.doc.isv/guide/swt.htm" target="_blank">Eclipse
+ Platform Plug-in Developer Guide: Standard Widget Toolkit (SWT)</A><BR>
+ <A href="http://dev.eclipse.org/help20/content/help:/org.eclipse.platform.doc.isv/guide/jface.htm" target="_blank">Eclipse
+ Platform Plug-in Developer Guide: JFace UI Framework</A><br>
+ <A href="http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm" target="_blank">Article:
+ Understanding Layouts in SWT (Revised for 2.0)</A><BR>
+ </P>
+</BODY></HTML>
diff --git a/Article-JFace Wizards/wizardsPlugin.jar b/Article-JFace Wizards/wizardsPlugin.jar
new file mode 100644
index 0000000..240bdfd
--- /dev/null
+++ b/Article-JFace Wizards/wizardsPlugin.jar
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/Idea.jpg b/Article-JFace Wizards/wizards_files/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/Idea.jpg
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/car.gif b/Article-JFace Wizards/wizards_files/car.gif
new file mode 100644
index 0000000..0574c51
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/car.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/error.gif b/Article-JFace Wizards/wizards_files/error.gif
new file mode 100644
index 0000000..45f06b1
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/error.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/linux_only.gif b/Article-JFace Wizards/wizards_files/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/linux_only.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/mainPage.gif b/Article-JFace Wizards/wizards_files/mainPage.gif
new file mode 100644
index 0000000..10b89b9
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/mainPage.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/newWizard.gif b/Article-JFace Wizards/wizards_files/newWizard.gif
new file mode 100644
index 0000000..b733b16
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/newWizard.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/plane.gif b/Article-JFace Wizards/wizards_files/plane.gif
new file mode 100644
index 0000000..2155d22
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/plane.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/popup.gif b/Article-JFace Wizards/wizards_files/popup.gif
new file mode 100644
index 0000000..a96a3ec
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/popup.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_1.gif b/Article-JFace Wizards/wizards_files/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/tag_1.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_2.gif b/Article-JFace Wizards/wizards_files/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/tag_2.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_3.gif b/Article-JFace Wizards/wizards_files/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/tag_3.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_4.gif b/Article-JFace Wizards/wizards_files/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/tag_4.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_5.gif b/Article-JFace Wizards/wizards_files/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/tag_5.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_6.gif b/Article-JFace Wizards/wizards_files/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/tag_6.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_7.gif b/Article-JFace Wizards/wizards_files/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/tag_7.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tip.gif b/Article-JFace Wizards/wizards_files/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/tip.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tryit.gif b/Article-JFace Wizards/wizards_files/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/tryit.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/win_only.gif b/Article-JFace Wizards/wizards_files/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-JFace Wizards/wizards_files/win_only.gif
Binary files differ
diff --git a/Article-Java-launch/images/Idea.jpg b/Article-Java-launch/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Java-launch/images/Idea.jpg
Binary files differ
diff --git a/Article-Java-launch/images/linux_only.gif b/Article-Java-launch/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Java-launch/images/linux_only.gif
Binary files differ
diff --git a/Article-Java-launch/images/tag_1.gif b/Article-Java-launch/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Java-launch/images/tag_1.gif
Binary files differ
diff --git a/Article-Java-launch/images/tag_2.gif b/Article-Java-launch/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Java-launch/images/tag_2.gif
Binary files differ
diff --git a/Article-Java-launch/images/tag_3.gif b/Article-Java-launch/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Java-launch/images/tag_3.gif
Binary files differ
diff --git a/Article-Java-launch/images/tag_4.gif b/Article-Java-launch/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Java-launch/images/tag_4.gif
Binary files differ
diff --git a/Article-Java-launch/images/tag_5.gif b/Article-Java-launch/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Java-launch/images/tag_5.gif
Binary files differ
diff --git a/Article-Java-launch/images/tag_6.gif b/Article-Java-launch/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Java-launch/images/tag_6.gif
Binary files differ
diff --git a/Article-Java-launch/images/tag_7.gif b/Article-Java-launch/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Java-launch/images/tag_7.gif
Binary files differ
diff --git a/Article-Java-launch/images/tip.gif b/Article-Java-launch/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Java-launch/images/tip.gif
Binary files differ
diff --git a/Article-Java-launch/images/tryit.gif b/Article-Java-launch/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Java-launch/images/tryit.gif
Binary files differ
diff --git a/Article-Java-launch/images/win_only.gif b/Article-Java-launch/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Java-launch/images/win_only.gif
Binary files differ
diff --git a/Article-Java-launch/launching-java.html b/Article-Java-launch/launching-java.html
new file mode 100644
index 0000000..03f3b54
--- /dev/null
+++ b/Article-Java-launch/launching-java.html
@@ -0,0 +1,444 @@
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<title>Launching Java Applications</title>
+<link rel="stylesheet" href="../default_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2003 International Business Machines Corp.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">Launching Java Applications Programmatically</h1>
+
+<blockquote>
+<b>Summary</b>
+
+<br>
+ Application developers require the ability to run and debug code in order to
+ test it. Tool developers require the ability to launch Java&#153; applications
+ that assist in application development - for example, starting and stopping
+ a Web server on which servlets, JSPs, and HTML pages can be tested; or launching
+ a VM on which scrapbook evaluations can be performed. This article focuses on
+ the high-level API provided by the Java launching plug-in that tool developers
+ can leverage for the programmatic launching of local Java applications.
+ <p><b> By Darin Wright, IBM OTI Labs</b> <br>
+ <font size="-1">August 26, 2003</font> </p>
+</blockquote>
+
+<hr width="100%">
+<h2>Prerequisites</h2>
+<p>To get the most out of this article, the reader should have a basic understanding
+ of the Eclipse plug-in architecture, Java programming, and launching Java programs
+ from the command line. A basic understanding of the Eclipse launching framework
+ is also helpful - see the article <a href="http://www.eclipse.org/articles/Article-Launch-Framework/launch.html">We
+ Have Lift-off: The Launching Framework in Eclipse</a>, by Joe Szurzsewski. Knowledge
+ of Tomcat is useful, but not required, as the examples are based on launching
+ a Tomcat server.</p>
+<h2>Introduction</h2>
+<p>Application developers require the ability to run and debug code in order to
+ test it. This is, of course, the primary use of the Java launching support in
+ the Eclipse SDK - to launch applications being developed in the IDE. However,
+ tool developers also require the ability to launch Java applications that assist
+ in application development - for example, starting and stopping a Web server
+ on which servlets, JSPs, and HTML pages can be tested; or launching a VM on
+ which scrapbook evaluations can be performed.</p>
+<p>In the Eclipse SDK, there are a variety of mechanisms available to Java developers
+ for launching Java VMs. At the most basic level, <code>java.lang.Runtime</code>
+ provides an API to launch a system process by specifying a raw command line.
+ At a slightly higher level, the Java launching plug-in provides an API to launch
+ a particular JRE (defined in the workspace preferences), with a specified raw
+ classpath, boot path, program arguments, VM arguments, and a main type name.
+ At the highest level, the Java launching plug-in provides Java launch configurations.
+ Java launch configurations leverage the debug platform's launching framework,
+ providing persistence and visibility in the Eclipse user interface - i.e. processes
+ appear in the debug view, have console I/O, and launched applications appear
+ in the launch history and launch configuration dialog. Java launch configurations
+ use high-level abstractions that insulate developers from many of the tedious
+ details involved in the lower level APIs.</p>
+<h2>Launching a Web Server</h2>
+<p>To illustrate the use of Java launch configurations, this article steps through
+ an example of translating a command line used to start Tomcat into an equivalent
+ launch configuration. To run the example you need the following.</p>
+<ul>
+ <li>a local installation of Tomcat, version 4.1.24 (available <a href="http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.1.24/">here</a>)</li>
+ <li>a Java Development Kit (JDK, version 1.3.1 or higher, available <a href="http://java.sun.com/j2se/">here</a>)</li>
+ <li>an environment variable, <code>JAVA_HOME</code>, set to the installation
+ location of your JDK</li>
+ <li>an Eclipse SDK, with <a href="org.eclipse.jdt.launching.examples.tomcat.zip">this
+ example plug-in</a> unzipped into its plugins directory</li>
+ <li>a classpath variable (Preferences &gt; Java &gt; Classpath Variables) named
+ <code>TOMCAT_HOME</code>, that points to your Tomcat installation directory</li>
+</ul>
+<h3>First a Disclaimer</h3>
+<p>The example used in this article is <b>not</b> <b>intended to be a style guide</b>
+ for integrating server or application launching into the Eclipse IDE. The sole
+ intent is to demonstrate the Java launch API.</p>
+<h3>Launching Tomcat from the Command Line</h3>
+<p>The simplest way to launch Tomcat is to use the <code>startup</code> command
+ provided with the sever. For example, from a DOS prompt, in the <code>bin</code>
+ directory of your Tomcat installation, type <code>startup</code>. This will
+ execute the batch file which starts the server. A second DOS shell will appear,
+ labeled Tomcat, and output messages will appear in the shell as the server starts.
+ To ensure the server has started properly, you can open a Web browser on this
+ address <code><a href="http://localhost:8080/">http://localhost:8080</a></code>.
+ The server can be shut down by using the <code>shutdown</code> command from
+ the bin directory of the Tomcat installation. The server will be stopped, and
+ the associated DOS window will close.</p>
+<p>Examining the <code>startup</code> batch file reveals that Tomcat is ultimately
+ started by launching a Java application. </p>
+<p><img src="images/tryit.gif" width="61" height="13"> From the <code>bin</code>
+ directory of your Tomcat installation, enter a command line similar to the following.
+ You will need to substitute the proper location for <code>tools.jar</code> specified
+ in the classpath parameter, based on the location of your JDK (in this example,
+ it is found in <code>d:\jdk1.4.1_02\lib\tools.jar</code>).</p>
+<pre>java -Djava.endorsed.dirs=&quot;..\common\endorsed&quot;<br> -classpath &quot;d:\jdk1.4.1_02\lib\tools.jar;..\bin\bootstrap.jar&quot;<br> -Dcatalina.base=&quot;..&quot;<br> -Dcatalina.home=&quot;..&quot;<br> -Djava.io.tmpdir=&quot;..\temp&quot;<br> org.apache.catalina.startup.Bootstrap start
+</pre>
+<p>This has the same effect as running the <code>startup</code> batch file, except
+ this time, the startup messages appear in the same DOS window. Once again, we
+ can verify the server has started properly by opening a Web browser on this
+ address <code><a href="http://localhost:8080/">http://localhost:8080</a></code>.
+ Examining the command line that was entered, we notice the following.</p>
+<ul>
+ <li>a Java VM is launched</li>
+ <li>the main type is <code>org.apache.catalina.startup.Bootstrap</code></li>
+ <li>the main type is passed one program argument - <code>start</code></li>
+ <li>the classpath includes <code>tools.jar</code> from the JDK installation,
+ and <code>bootstrap.jar</code> from the Tomcat installation</li>
+ <li>several system properties are set - <code>java.endorsed.dirs</code>, <code>catalina.base</code>,
+ <code>catalina.home</code>, and <code>java.io.tmpdir</code></li>
+</ul>
+<p>The server can be shut down by using the <code>shutdown</code> command (from
+ another DOS shell). Note that the <code>shutdown</code> command actually results
+ in the same Java application being launched, with a different program argument
+ - i.e. <code>stop</code>. Thus, you can also stop the server by entering a command
+ line similar to the following, from the <code>bin</code> directory of the Tomcat
+ installation. Once again, you need to substitute the proper location of <code>tools.jar</code>.</p>
+<pre>java -Djava.endorsed.dirs=&quot;..\common\endorsed&quot;<br> -classpath &quot;d:\jdk1.4.1_02\lib\tools.jar;..\bin\bootstrap.jar&quot;<br> -Dcatalina.base=&quot;..&quot;<br> -Dcatalina.home=&quot;..&quot;<br> -Djava.io.tmpdir=&quot;..\temp&quot;<br> org.apache.catalina.startup.Bootstrap stop</pre>
+<h3>Launching Tomcat from Eclipse</h3>
+<p>Now let's translate the command line used to start Tomcat from the system command
+ prompt into a launch configuration that can be used to launch Tomcat from within
+ Eclipse. To do this, we will create an instance of a local Java application
+ launch configuration, set various attributes on the configuration corresponding
+ to our command line, and then launch the configuration.</p>
+<p>The example plug-in provides sample actions to start and stop Tomcat, available
+ on a Tomcat menu (on window menu bar). The <b>Start Tomcat</b> action provides
+ a cascading menu of all JREs defined in the workspace. When a JRE is selected,
+ Tomcat is launched on that JRE. The code snippets below refer to code in the
+ sample action <code>org.eclipse.jdt.launching.examples.tomcat.StartAction</code>,
+ which launches Tomcat on a specific JRE.</p>
+<h4>Creating a Launch Configuration</h4>
+<p>The first step is to create an instance of a launch configuration, used for
+ launching local Java applications.</p>
+
+<pre>
+<img src="images/tag_1.gif" width=24 align=CENTER>ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();<br> ILaunchConfigurationType type =<br> manager.getLaunchConfigurationType(ID_JAVA_APPLICATION);<br><img src="images/tag_2.gif" width=24 align=CENTER>ILaunchConfiguration[] configurations =<br> manager.getLaunchConfigurations(type);<br> for (int i = 0; i &lt; configurations.length; i++) {<br> ILaunchConfiguration configuration = configurations[i];<br> if (configuration.getName().equals(&quot;Start Tomcat&quot;)) {<br> configuration.delete();<br> break;<br> }<br> }<br><img src="images/tag_3.gif" width=24 align=CENTER>ILaunchConfigurationWorkingCopy workingCopy =<br> type.newInstance(null, &quot;Start Tomcat&quot;);<p></p>
+</pre>
+<ol>
+ <li>The Java Application launch configuration type is retrieved. A launch configuration
+ type represents a class of launch configurations (much like a type in Java
+ represents a class of objects, also known as the Type Object pattern). Launch
+ configuration types are stored with the launch manager in the debug platform.
+ Each launch configuration type is defined as an extension in plug-in XML,
+ and has a unique identifier which can be used to access it. The constants
+ associated with the Java Application launch configuration are defined in <code>org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants</code>.</li>
+ <li>This example deletes any existing launch configuration with the name &quot;<code>Start
+ Tomcat</code>&quot;. This is done by iterating through all Java application
+ launch configurations, in search of a configuration with that name, and deleting
+ it if one is found. A real application might reuse an existing launch configuration,
+ but for the purposes of this example, we simply delete any previously created
+ configuration.</li>
+ <li>An instance of a Java Application launch configuration is created and named
+ &quot;<code>Start Tomcat</code>&quot;. Instances are created as working copies,
+ which are read-write. In this example, the launch configuration will be persisted
+ with the workspace metadata. The <code>newInstance</code> method accepts an
+ <code>IContainer</code> in which to create the launch configuration, and the
+ name of the configuration to create. When null is specified as the container,
+ the configuration will be persisted with the workspace metadata. Alternatively,
+ a workspace project or folder could be specified - in which case the configuration
+ would be stored as a file in the workspace.</li>
+</ol>
+<p>Launch configurations are simply containers of attribute-value pairs that can
+ be persisted. Each launch configuration type extension provides a launch delegate
+ that is capable of interpreting the attributes of a launch configuration and
+ launching an associated process. </p>
+<h4>Specifying a JRE</h4>
+<p>The JRE used to execute a Java application is, by default, the JRE on the build
+ path of the project being launched. If a launch configuration is not associated
+ with a project (as in this example), the workspace default JRE is used. A specific
+ JRE may be specified on a Java launch configuration, to refer to one of the
+ JREs defined in the workspace. A workspace may have any number of JREs defined,
+ which can be configured and displayed on the <b>Java &gt; Installed JREs</b>
+ preference page.</p>
+<p>The Java launching plug-in allows for different types of JREs, as there are
+ many vendors and versions of JREs. A type of JRE is represented by the interface
+ <code>IVMInstallType</code>. For example, VMs which conform to the standard
+ Sun command line options are represented by one type of JRE. A specific instance
+ or installation of a type of JRE, is represented by the interface <code>IVMInstall</code>.
+ (Once again, we see the Type Object pattern).</p>
+<p>The VM install types defined in a workspace can be retrieved from the <code>JavaRuntime</code>
+ class in the Java launching plug-in (<code>org.eclipse.jdt.launching</code>).
+ The instances or installations of each VM type, are retrieved from the VM type.
+ Our cascading sample menu <b>Start Tomcat, </b>loops through each VM install
+ within each VM type, and populates a submenu of actions - one for each VM install
+ in the workspace, as shown in the following code snippet from <code>StartMenuAction</code>.</p>
+<pre>IVMInstallType[] types = JavaRuntime.getVMInstallTypes();<br>for (int i = 0; i &lt; types.length; i++) {<br> IVMInstallType type = types[i];<br> IVMInstall[] jres = type.getVMInstalls();<br> for (int j = 0; j &lt; jres.length; j++) {<br> IAction action = new StartAction(jres[j]);<br> ActionContributionItem item = new ActionContributionItem(action);<br> item.fill(menu, -1);<br> }<br>}</pre>
+<p>Thus, each <code>StartAction</code> is created to launch Tomcat with a specific
+ JRE, and uses the following code to specify the JRE on the launch configuration.</p>
+<pre>workingCopy.setAttribute(ATTR_VM_INSTALL_NAME, jre.getName());
+workingCopy.setAttribute(ATTR_VM_INSTALL_TYPE, jre.getVMInstallType().getId());</pre>
+<p>The JRE name and type are specified via the attributes <code>ATTR_VM_INSTALL_NAME</code>
+ and <code>ATTR_VM_INSTALL_TYPE</code>, respectively. Each VM install type has
+ an associated identifier that uniquely identifies it among other VM install
+ types, and this identifier is used to specify the VM type. The actual VM installation
+ is specified by the name of the JRE. Although a JRE also has a unique identifier,
+ the name of a JRE is used to identify it instead. The identifier for a specific
+ VM install may be different between workspaces, and has little meaning to a
+ user (as it is simply a number). Thus, the name is more descriptive and portable
+ when sharing a launch configuration with other users.</p>
+<h4>Specifying a Main Type and Program Arguments</h4>
+<p>The next step is to specify the main type we want to launch and the arguments
+ to pass to the main type.</p>
+<pre><img src="images/tag_1.gif" width=24 align=CENTER>workingCopy.setAttribute(ATTR_MAIN_TYPE_NAME,<br> &quot;org.apache.catalina.startup.Bootstrap&quot;);<br><img src="images/tag_2.gif" width=24 align=CENTER>workingCopy.setAttribute(ATTR_PROGRAM_ARGUMENTS, &quot;start&quot;);</pre>
+<ol>
+ <li>To specify a main type, we simply set the main type attribute - <code>ATTR_MAIN_TYPE_NAME</code>.
+ The value is a string containing the fully qualified name of the main type.</li>
+ <li>To specify program arguments, the <code>ATTR_PROGRAM_ARGUMENTS</code> attribute
+ is used. Its value is a string containing the raw command line arguments to
+ pass to the main type.</li>
+</ol>
+<h4>Specifying a Classpath</h4>
+<p>By default, the project associated with a Java application launch configuration
+ is used to determine a runtime classpath for the application (which is specified
+ by the <code>ATTR_PROJECT_NAME</code> attribute). Generally, the build path
+ specified for a project in the workspace corresponds to the desired runtime
+ classpath. Thus, when a classpath is not explicitly specified on a launch configuration,
+ a default runtime classpath is computed from the associated project's build
+ path. However, our example launch configuration is not associated with a project
+ in the workspace - we are launching an application external to the workspace.
+ Thus, we must specify the runtime classpath to use.</p>
+<p><img src="images/tip.gif" width="62" height="13"> In the Eclipse SDK, the command
+ line used to launch a Java application can be viewed by selecting the associated
+ process or debug target in the <b>Debug View</b>, and selecting <b>Properties</b>
+ from the context menu. This displays a dialog containing the command line (including
+ the classpath option) generated to launch a Java application. Examining the
+ command used to launch a process can be useful when diagnosing launch problems.</p>
+<p>In the Eclipse SDK, the runtime classpath can be configured via the <b>Classpath</b>
+ tab of a Java application launch configuration. On this tab, the user can specify
+ the order of projects, system libraries, jars, folders, and variables to be
+ placed on the classpath. Entries can be added to the user application classpath
+ or the boot path. Similarly, a classpath can be programmatically specified on
+ a Java application launch configuration as an ordered list of classpath entries.
+ The attribute used to specify a classpath is <code>ATTR_CLASSPATH</code>,
+ and its value is a list of <code>String</code>s,
+ each of which is a memento for an <code>IRuntimeClasspathEntry</code>.</p>
+<p>An <code>IRuntimeClasspathEntry</code> can
+ be used to describe any of the following:</p>
+<ul>
+ <li>a project in the workspace</li>
+ <li>an archive (jar or zip file) in the workspace</li>
+ <li> an archive in the local file system</li>
+ <li>a folder in the workspace</li>
+ <li>a folder in the local file system</li>
+ <li>a classpath variable with an optional extension</li>
+ <li>a system library (also known as a classpath container, which is a related
+ group of archives, such as the jars associated with a JDK)</li>
+</ul>
+<p>The classpath specified on a launch configuration is specified in an unresolved
+ format, and is resolved by the launch delegate at run time. For example, a project
+ entry on the classpath is resolved to the output locations of that project (i.e.
+ the folder or folders that contain the compiled class files for the project).
+ Specifying an unresolved classpath on the launch configuration makes the classpath
+ portable between workspaces and shareable among users. When a classpath is specified
+ on a launch configuration, it must be specified completely - that is, including boot path
+ and user classpath entries.</p>
+<p>Our example requires two entries on the user application classpath - <code>tools.jar
+ </code>and <code>bootstrap.jar</code>.</p>
+<pre><img src="images/tag_1.gif" width=24 align=CENTER>IVMInstall jre = JavaRuntime.getDefaultVMInstall(); <br> File jdkHome = jre.getInstallLocation();<br> IPath toolsPath = new Path(jdkHome.getAbsolutePath())<br> .append(&quot;lib&quot;)<br> .append(&quot;tools.jar&quot;);<br> IRuntimeClasspathEntry toolsEntry =<br> JavaRuntime.newArchiveRuntimeClasspathEntry(toolsPath);<br> toolsEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES);<br><img src="images/tag_2.gif" width=24 align=CENTER>IPath bootstrapPath = new Path(&quot;TOMCAT_HOME&quot;)<br> .append(&quot;bin&quot;)<br> .append(&quot;bootstrap.jar&quot;);<br> IRuntimeClasspathEntry bootstrapEntry = <br> JavaRuntime.newVariableRuntimeClasspathEntry(bootstrapPath);<br> bootstrapEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES); <br><img src="images/tag_3.gif" width=24 align=CENTER>IPath systemLibsPath = new Path(JavaRuntime.JRE_CONTAINER);<br> IRuntimeClasspathEntry systemLibsEntry =<br> JavaRuntime.newRuntimeContainerClasspathEntry(systemLibsPath,<br> IRuntimeClasspathEntry.STANDARD_CLASSES);<br><img src="images/tag_4.gif" width=24 align=CENTER>List classpath = new ArrayList();<br> classpath.add(toolsEntry.getMemento());<br> classpath.add(bootstrapEntry.getMemento());<br> classpath.add(systemLibsEntry.getMemento());<br> workingCopy.setAttribute(ATTR_CLASSPATH, classpath);<br> workingCopy.setAttribute(ATTR_DEFAULT_CLASSPATH, false);</pre>
+<ol>
+ <li>The first entry on our classpath is <code>tools.jar</code> from the JDK
+ install. (This example assumes you have set your workspace default JRE to
+ a JDK install containing <code>tools.jar</code> in the <code>lib</code> directory).
+ We create a classpath entry that points to an archive in the local file system,
+ with an absolute path. We build the path relative to the install location
+ of the workspace default JRE. The entry's classpath property is set to <code>USER_CLASSES</code>,
+ to indicate that the classpath entry is to appear on the user application
+ portion of the classpath.</li>
+ <li>Next, a classpath entry for Tomcat's <code>bootstrap.jar</code> is created.
+ (This example assumes you have defined a classpath variable, <code>TOMCAT_HOME</code>,
+ that points to the install location of Tomcat). This entry is created relative
+ to the Tomcat install location, by creating a variable entry with an extension
+ of &quot;<code>bin\bootstrap.jar</code>&quot;. This entry is also set to appear
+ on the user application portion of the classpath.</li>
+ <li>When launching Tomcat from the command line, we did not specify a boot path
+ (the default boot path was used). However, when specifying a classpath on
+ a Java launch configuration, the complete path must be specified. Thus, an
+ entry is created that refers to the system libraries associated with the default
+ JRE. The classpath property of this entry is set to <code>STANDARD_CLASSES</code>,
+ indicating that the entry refers to a set of archives that normally appear
+ on the boot path by default. The Java application launch delegate only generates
+ a boot path argument when non-default entries appear on the boot path. However,
+ we must still specify all entries.</li>
+ <li>The classpath attribute is created and set - an <b>ordered</b> list of runtime
+ classpath entry <b>mementos</b>. It is also important to note that the <code>ATTR_DEFAULT_CLASSPATH</code>
+ attribute is also set to <code>false</code>. When this attribute is omitted
+ or set to <code>true</code>, a default classpath is used, rather than the
+ classpath specified on the launch configuration.</li>
+</ol>
+<h4>Specifying System Properties</h4>
+<p>Next we specify system properties.</p>
+<pre><img src="images/tag_1.gif" width=24 align=CENTER>workingCopy.setAttribute(ATTR_VM_ARGUMENTS,<br> &quot;-Djava.endorsed.dirs=\&quot;..\\common\\endorsed\&quot;&quot;<br> + &quot;-Dcatalina.base=\&quot;..\&quot;&quot;<br> + &quot;-Dcatalina.home=\&quot;..\&quot;&quot;<br> + &quot;-Djava.io.tmpdir=\&quot;..\\temp\&quot;&quot;);</pre>
+<ol>
+ <li>System properties are specified as VM arguments, using the <code>ATTR_VM_ARGUMENTS</code>
+ attribute. The value is a string of raw arguments, as they would appear on
+ the command line.</li>
+</ol>
+<h4>Specifying a Working Directory</h4>
+<p>The working directory associated with a Java runtime can be retrieved at run
+ time via the system property <code>user.dir</code> (that is, <code>System.getProperty(&quot;user.dir&quot;)</code>).
+ At run time, file operations are performed relative to the working directory
+ when absolute paths are not specified. When launching a Java program from the
+ command line, the working directory is initialized to the location in the file
+ system from which the VM is launched. When launching a Java program from within
+ Eclipse, the working directory must be specified. When a working directory is
+ not specified, it is, by default, the location in the local file system that
+ corresponds to the directory of the project being launched. When a project is
+ not associated with a launch configuration, the default working directory is
+ the directory from which the Eclipse SDK was started.</p>
+<p>When we launched Tomcat from the command line, the working directory was the
+ <code>bin</code> directory of the Tomcat install - i.e. the directory from which
+ the command was given. Since we have specified system properties relative to
+ the working directory, we must also specify the working directory that should
+ be used on our launch configuration.</p>
+<pre><img src="images/tag_1.gif" width=24 align=CENTER>File workingDir = JavaCore.getClasspathVariable(&quot;TOMCAT_HOME&quot;)<br> .append(&quot;bin&quot;).toFile();<br> workingCopy.setAttribute(ATTR_WORKING_DIRECTORY,<br> workingDir.getAbsolutePath());</pre>
+<ol>
+ <li>The value of the working directory attribute is a string representing a
+ path. If the path is absolute (that is, begins with a device or path separator),
+ the path is interpreted as a location in the local file system. If the path
+ is relative (does not begin with a device or path separator), the path is
+ interpreted as relative to the workspace root. Our example specifies an absolute
+ path in the local file system - the <code>bin</code> directory of the Tomcat
+ install.</li>
+</ol>
+<h4>Launching a Configuration</h4>
+<p>Now we are ready to launch our configuration.</p>
+<pre><img src="images/tag_1.gif" width=24 align=CENTER>ILaunchConfiguration configuration = workingCopy.doSave();<br><img src="images/tag_2.gif" width=24 align=CENTER>DebugUITools.launch(configuration, ILaunchManager.RUN_MODE);</pre>
+<ol>
+ <li>First, the working copy launch configuration is saved. This persists the
+ launch configuration locally with the workspace metadata.</li>
+ <li>Next, the configuration is launched. This example launches the configuration
+ in run mode, using the launch API provided by the debug UI plug-in. This convenience
+ API has several advantages. According to workspace preferences any unsaved
+ editors are saved, the workspace is built, and then the configuration is launched,
+ all while displaying a progress dialog.</li>
+</ol>
+<p><img src="images/tip.gif" width="62" height="13"> You can also launch a configuration
+ via the API <code>ILaunchConfiguration.launch(String mode, IProgressMonitor
+ monitor)</code>. This avoids saving editors and building the workspace, but
+ it requires you to provide a progress monitor.</p>
+<p><img src="images/tryit.gif" width="61" height="13"> Display the <b>Tomcat </b>action
+ set by selecting <b>Window &gt; Customize Perspective</b>, and then checking
+ the <b>Tomcat Example</b> action set. Run the example by selecting the <b>Start
+ Tomcat</b> action from the <b>Tomcat</b> menu our example plug-in provides,
+ and selecting a JRE from the cascading menu. Note that you must choose a JRE
+ that is a JDK containing a <code>tools.jar</code>. Output will appear in the
+ console as the server is launched. You can verify the server is up and running
+ by opening a Web browser on this address <code><a href="http://localhost:8080/">http://localhost:8080</a></code>.
+ Notice that the launch configuration we created also appears in the launch history
+ (drop down <b>Run</b> and <b>Debug</b> menus), and the launch configuration
+ also appears in the launch configuration dialog.</p>
+<p><img src="images/tip.gif" width="62" height="13"> We could avoid having the
+ launch configuration appear in the launch dialog and launch history by marking
+ our launch configuration as private. The debug plug-in defines an attribute
+ common to all launch configurations to control this - <code>IDebugUIConstants.ATTR_PRIVATE</code>.
+ The value is a boolean indicating if the launch configuration is private, and
+ the default value is <code>false</code> (i.e. when unspecified).</p>
+<h3>Stopping the Server</h3>
+<p>A <b>Stop Tomcat</b> action is provided to shut down Tomcat as well - available
+ from the <b>Tomcat</b> menu. This action is almost identical to the start action,
+ except it creates a launch configuration with a different name (<code>Stop Tomcat</code>),
+ and specifies the <code>stop</code> argument in place of <code>start</code>.</p>
+<p><img src="images/tryit.gif" width="61" height="13">Shut down the server by
+ selecting the <b>Stop Tomcat</b> action. You will notice another process is
+ launched and then both processes (the Tomcat server and the newly launched process)
+ eventually terminate. </p>
+<h3>Debugging the Server</h3>
+<p>The example has shown how to launch Tomcat in run mode. The VM used to run
+ Tomcat can also be launched in debug mode, simply by changing the mode specified
+ in the following line.</p>
+<pre>DebugUITools.launch(configuration, ILaunchManager.DEBUG_MODE);</pre>
+<p><img src="images/tryit.gif" width="61" height="13"> Another way to launch Tomcat
+ in debug mode is to re-launch Tomcat from the debug drop down menu, or from
+ the launch configuration dialog when opened in debug mode. Tomcat will launch,
+ and its process, debug target, and threads will be displayed in the debug view.</p>
+<h2>Other Launch Options</h2>
+<p>Our Tomcat example demonstrates many of the common features/attributes required
+ for launching Java applications programmatically. However, there are other aspects
+ of the launch that can be controlled by attributes that were not used in our
+ example. The following list provides a summary of the options not covered by
+ the example, and when you might want to use them.</p>
+<ul>
+ <li><code>ATTR_PROJECT_NAME</code> - This attribute specifies the name of a
+ Java project associated with a launch configuration. When this attribute is
+ specified, the launch delegate uses the associated project to compute default
+ values for a launch - such as runtime classpath, working directory, JRE, and
+ source lookup path.</li>
+ <li><code>ATTR_STOP_IN_MAIN</code> - This attribute is a boolean indicating
+ whether an application should suspend when the <code>main</code> method is
+ entered on startup. The default value is <code>false</code>, and this attribute
+ is only effective when a configuration is launched in debug mode.</li>
+ <li><code>ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP</code> - This attribute is
+ a map of attribute-value pairs. The interpretation of the attributes is specific
+ to a VM install type. For example, the Standard VM install type supports the
+ specification of the name of the executable used to launch a VM - i.e. java,
+ javaw, etc. This value is specified by the <code>ATTR_JAVA_COMMAND</code>
+ attribute with in this attribute map. An extension point (<code>org.eclipse.jdt.debug.ui.vmInstallTypePage</code>)
+ exists for clients to contribute a user interface control to the JRE tab of
+ a Java application launch configuration, to display and edit JRE specific
+ attributes.</li>
+ <li><code>ATTR_SOURCE_PATH</code> - This attribute is analogous to the classpath
+ attribute, except that it specifies where source should be be located. The
+ value is an ordered list of runtime classpath entry mementos. This attribute
+ is used mostly in debug mode when stepping through source code, but is also
+ useful in run mode when navigating from stack traces in the console to corresponding
+ source.</li>
+ <li><code>ATTR_DEFAULT_SOURCE_PATH</code> - This boolean attribute (analogous
+ to <code>ATTR_DEFAULT_CLASSPATH</code>) indicates whether a default source
+ path should be used, based on the default classpath. When unspecified or <code>true</code>,
+ any explicitly specified source path is ignored.</li>
+ <li><code>ATTR_CLASSPATH_PROVIDER</code> - This attribute specifies an identifier
+ of a classpath provider extension (extensions of type <code>org.eclipse.jdt.launching.classpathProviders</code>).
+ When specified, the associated classpath provider is consulted to compute
+ and resolve a runtime classpath for a launch configuration. This provides
+ clients with a hook for generating and resolving runtime classpaths.</li>
+ <li><code>ATTR_SOURCE_PATH_PROVIDER</code> - This attribute is analogous to
+ <code>ATTR_CLASSPATH_PROVIDER</code>, except that it specifies an extension
+ used to compute and resolve the source lookup path.</li>
+</ul>
+<h2>Summary</h2>
+<p>Launch configurations provide a high-level API for programmatically launching
+ Java applications. Just as a user can create, modify and launch an application
+ from the Eclipse user interface, configurations can be created, modified, and
+ launched programmatically. Java VM command line options correspond to Java launch
+ configuration attributes. Launch configurations leverage features of the debug
+ platform launching framework - persistence, launch history, console I/O, and
+ visibility in the launch configuration dialog.</p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+ trademarks of Sun Microsystems, Inc. in the United States, other countries,
+ or both.</small></p>
+<p><small>Other company, product, and service names may be trademarks or service marks
+ of others.</small></p>
+</body>
+</html>
diff --git a/Article-Java-launch/org.eclipse.jdt.launching.examples.tomcat.zip b/Article-Java-launch/org.eclipse.jdt.launching.examples.tomcat.zip
new file mode 100644
index 0000000..668ab4f
--- /dev/null
+++ b/Article-Java-launch/org.eclipse.jdt.launching.examples.tomcat.zip
Binary files differ
diff --git a/Article-Launch-Framework/images/Idea.jpg b/Article-Launch-Framework/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Launch-Framework/images/Idea.jpg
Binary files differ
diff --git a/Article-Launch-Framework/images/Screenshot1.gif b/Article-Launch-Framework/images/Screenshot1.gif
new file mode 100644
index 0000000..a209b3d
--- /dev/null
+++ b/Article-Launch-Framework/images/Screenshot1.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/Screenshot2.gif b/Article-Launch-Framework/images/Screenshot2.gif
new file mode 100644
index 0000000..08be336
--- /dev/null
+++ b/Article-Launch-Framework/images/Screenshot2.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/tag_1.gif b/Article-Launch-Framework/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Launch-Framework/images/tag_1.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/tag_2.gif b/Article-Launch-Framework/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Launch-Framework/images/tag_2.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/tag_3.gif b/Article-Launch-Framework/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Launch-Framework/images/tag_3.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/tag_4.gif b/Article-Launch-Framework/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Launch-Framework/images/tag_4.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/tag_5.gif b/Article-Launch-Framework/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Launch-Framework/images/tag_5.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/tag_6.gif b/Article-Launch-Framework/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Launch-Framework/images/tag_6.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/tag_7.gif b/Article-Launch-Framework/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Launch-Framework/images/tag_7.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/tip.gif b/Article-Launch-Framework/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Launch-Framework/images/tip.gif
Binary files differ
diff --git a/Article-Launch-Framework/images/tryit.gif b/Article-Launch-Framework/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Launch-Framework/images/tryit.gif
Binary files differ
diff --git a/Article-Launch-Framework/launch.html b/Article-Launch-Framework/launch.html
new file mode 100644
index 0000000..e7f0c59
--- /dev/null
+++ b/Article-Launch-Framework/launch.html
@@ -0,0 +1,1151 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+ <meta name="Author" content="Joe Szurszewski">
+ <title>We Have Lift-off: The Launching Framework in Eclipse</title>
+ <link type="text/css" rel="stylesheet" href="../../default_style.css">
+ </head>
+ <body link="#0000ff" vlink="#800080">
+
+<div align="right"> &nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ © 2003 International Business Machines Corp.</font>
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr>
+
+ <td align="LEFT" valign="TOP" bgcolor="#0080C0"> <b><font face="Arial,Helvetica" color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></b> </td>
+ </tr>
+ </table>
+ </div>
+ <div align="left">
+ <h1>
+ <img src="images/Idea.jpg" height="86" width="120" align="CENTER">
+ </h1>
+ </div>
+ <p>&nbsp;
+
+ </p>
+
+<h1 align="CENTER"> We Have Lift-off: The Launching Framework in Eclipse </h1>
+ <blockquote>
+ <b>Summary</b><br>
+ The ability to launch (run or debug) code under development is fundamental to
+ an IDE. But because Eclipse is more of a tools platform than a tool itself,
+ Eclipse's launching capabilities depend entirely on the current set of installed
+ plug-ins. This article describes the API available to build launching plug-ins
+ and works through developing an example launcher using this API.
+ <p> <b>By Joe Szurszewski, IBM OTI Labs</b><br>
+ <font size="-1">January 8, 2003</font></p>
+ </blockquote>
+ <hr width="100%">
+<h2>Prerequisites</h2>
+To get the most out of this article, the reader should have a basic understanding
+of the Eclipse plug-in architecture and the structure of <code>plugin.xml</code>
+files. In addition, some knowledge of Java and Java terminology (VM, classpath,
+etc.) is helpful, though not necessary.
+<h2>In the beginning, there was nothing </h2>
+<p>For purposes of this article, <i>launching</i> is defined as running or debugging
+ a program from within Eclipse, and a <i>launcher</i> is a set of Java classes
+ that live in an Eclipse plug-in that performs launching. As with most things
+ in Eclipse, there is no 'built-in' launching functionality. The base Eclipse
+ workbench can't launch a thing. It is only through plug-ins that Eclipse gains
+ the ability to launch. The Eclipse SDK does ship with a set of useful launchers
+ for launching local Java applications &amp; Java applets, connecting to remote
+ Java applications, launching JUnit test suites and starting an Eclipse workbench,
+ but if none of these satisfy your needs and you can't find a plug-in someone
+ else has written to do the job, you will need to write your own launcher. </p>
+<h2>A little history</h2>
+<p>Prior to 2.0, launching in Eclipse was somewhat inflexible and decentralized.
+ For these reasons and many others, the launching framework was overhauled for
+ 2.0. The primary issues addressed were:</p>
+<ul>
+ <li>Allow developers to easily contribute launchers that are tightly integrated
+ with the platform.</li>
+ <li>Break the launcher/resource dependency. Previously, launchers only worked
+ on workspace resources.</li>
+ <li>Centralize the collection of launch-related attributes.</li>
+ <li>Allow users to save sets of launching attributes for reuse.</li>
+</ul>
+<p>The downside of all these improvements is that there is no backward compatibility.
+ Eclipse 1.0 plug-ins that do launching will have to be reworked for 2.0. However,
+ such conversions are relatively painless, and should result in much improved
+ functionality.</p>
+<h2>
+ Let there be framework
+ </h2>
+
+<p> If you've decided to write your own launcher, you're in luck. Eclipse 2.0
+ plug-in developers have a rich API at their disposal to build plug-ins with
+ launching behavior. In 2.0, launching is centered around two main entities,
+ <b>LaunchConfigurations</b> and <b>LaunchConfigurationTypes</b>. At the simplest
+ level, LaunchConfigurationTypes are cookie cutters, and LaunchConfigurations
+ are the cookies made from these cookie cutters. When you as a plug-in developer
+ decide to create a launcher, what you are really doing is creating a specific
+ kind of cookie cutter that will allow your users to stamp out as many cookies
+ as they need. In slightly more technical terms, a LaunchConfigurationType (henceforth,
+ a 'config type') is an entity that knows how to launch certain types of launch
+ configurations, and determines what the user-specifiable parameters to such
+ a launch may be. Launch configurations (henceforth, 'configs') are entities
+ that contain all information necessary to perform a specific launch. For example,
+ a config to launch a HelloWorld Java application would contain the name of the
+ main class ('HelloWorld'), the JRE to use (JDK1.4.1, for example), any program
+ or VM arguments, the classpath to use and so on. When a config is said to be
+ 'of type local Java Application', this means that the local Java application
+ cookie cutter was used to make this config and that only this config type knows
+ how to make sense of this config and how to launch it. </p>
+<h2>Configs and working copies</h2>
+<p> Plug-in developers don't need to directly concern themselves with the launch
+ configuration lifecycle. Once you've implemented a config type, the launching
+ infrastructure contributed by the Debug core plug-in (<code>org.eclipse.debug.core</code>)
+ takes care of creating and persisting configs on behalf of the config type,
+ and infrastructure provided by the Debug UI plug-in ( <code>org.eclipse.debug.ui</code>)
+ provides a dialog to manage configs (the 'LaunchConfigurationDialog'), as well
+ as other launching-related UI.</p>
+<p>However, plug-in developers do need to know how to interact with configs. All
+ config objects implement the <code>org.eclipse.debug.core.ILaunchConfiguration</code>
+ interface which defines methods for retrieving information about the config,
+ but no methods for changing the config. This is because objects implementing
+ <code>ILaunchConfiguration</code> are immutable and cannot be changed. If you
+ wish to change a config, you must have a reference to an object that implements
+ the <code>org.eclipse.debug.core.ILaunchConfigurationWorkingCopy</code> interface.
+ This interface extends <code>ILaunchConfiguration</code>, but adds methods for
+ changing the contents of the config. The contents of a config consist of name/value
+ pairs called 'attributes'. An attribute specifies one discrete piece of information
+ about a config, for example the JRE to use when launching a Java-oriented config.
+ By looking at the API defined by <code>ILaunchConfiguration</code> and <code>ILaunchConfigurationWorkingCopy</code>,
+ you can see that attribute values must be one of 5 types:</p>
+<ul>
+ <li><b>boolean</b></li>
+ <li><b>int</b></li>
+ <li><code>java.lang.String</code></li>
+ <li><code>java.util.List</code> (all elements must be of type <code>java.lang.String</code>)</li>
+ <li><code>java.util.Map</code> (all keys &amp; values must be of type <code>java.lang.String</code>)</li>
+</ul>
+<p>This may seem limiting, but in practice, developers create <code>String</code>
+ mementos for complex data types and store these. </p>
+<p> <img src="images/tip.gif" width="62" height="13"> <i>When referencing attribute
+ names in code, you should always use publicly available constants. This allows
+ other developers to access your attributes. </i></p>
+<h2>Separating model and UI</h2>
+
+<p> To use the launcher API, your plug-in must make some import declarations in
+ its <code>plugin.xml</code> file. If your plug-in declares a config type, it
+ <b>must</b> import <code>org.eclipse.debug.core</code>, and if your plug-in
+ declares anything related to launching UI, it <b>must</b> import <code>org.eclipse.debug.ui</code>.
+ In general, it is recommended that the UI and non-UI aspects of your launcher
+ be handled by two <i>different</i> plug-ins. Note that it is not required for
+ a launcher to have <i>any</i> associated UI. In this case, the launcher can
+ only be used programmatically from within code, not by a user (see the forthcoming
+ related article &quot;How to Launch Java Applications Programmatically&quot;
+ by Darin Wright). Even if your launcher has an associated UI, there may be times
+ when you or someone else wants to use your launcher programmatically. Without
+ a clean separation between UI &amp; non-UI code, a plug-in wishing to use your
+ launcher programmatically would have to import the standard UI plug-ins, which
+ may be inconvenient, inefficient or impossible. </p>
+<h2>The Java applet example</h2>
+<p>The rest of this article is concerned with developing a launcher for Java applets.
+ This launcher is actually part of the Eclipse SDK (as of version 2.1), so all
+ of the source code presented here can be viewed by downloading the SDK. The
+ non-UI parts of this launcher live in the <code>org.eclipse.jdt.launching</code>
+ plug-in, and the UI parts are contained in the <code>org.eclipse.jdt.debug.ui</code>
+ plug-in. Each XML declaration that follows is marked as being UI or non-UI in
+ nature. This is to help you separate out the UI components in launchers you
+ create.</p>
+
+<h2>
+ Declaring a launch configuration type
+ </h2>
+ <p>
+ The first step in creating our applet launcher is declaring a
+ config type, as shown in the following snippet of XML from our
+ plug-in's <code>plugin.xml</code> file:
+ </p>
+
+<h5> <u>Non-UI declaration</u> </h5>
+<pre>
+&lt;extension point=&quot;org.eclipse.debug.core.launchConfigurationTypes&quot;&gt;
+ &lt;launchConfigurationType
+ name=&quot;Java Applet&quot;
+ delegate=&quot;org.eclipse.jdt.internal.launching.JavaAppletLaunchConfigurationDelegate&quot;
+ modes=&quot;run, debug&quot;
+ id=&quot;org.eclipse.jdt.launching.javaApplet&quot;&gt;
+ &lt;/launchConfigurationType&gt;
+&lt;/extension&gt;
+</pre>
+<p>
+ The most important part of this declaration is the
+ <code>delegate</code> attribute which specifies the
+ fully-qualified name of a class that implements the interface
+ <code>org.eclipse.debug.core.model.ILaunchConfigurationDelegate</code>.
+ The delegate is the brains of the launcher, and implements the
+ <code>launch()</code> method which launches a specified
+ config.
+ </p>
+
+<p> The <code>modes</code> attribute specifies one or both of <code>run</code>
+ &amp; <code>debug</code>. The debug infrastructure only supports these two modes
+ of launching, and to be useful, your config type must support at least one of
+ these. Among other things, this value tells the workbench where configs of your
+ type may appear in the UI. For example, if the launch configuration dialog is
+ opened in run mode, but your config type is for debug mode only, then your config
+ type and any associated configs will not appear. Note that if your config type
+ declares both modes, it is your delegate's responsibility in the <code>launch()</code>
+ method to handle both modes. </p>
+<p>An optional attribute not present in the above declaration is <code>private</code>.
+ This is a boolean attribute that indicates whether the config type should appear
+ in the UI, if there is one. Setting this attribute to <code>true</code> effectively
+ makes your launcher usable for programmatic launching only. The default value,
+ if this attribute is omitted, is <code>false</code>.</p>
+
+<p>Another optional attribute not shown above is <code>category</code>. This string-valued
+ attribute will be discussed later in the section on launch groups.</p>
+
+<h2>Implementing a launch configuration type </h2>
+<table border="1" cellspacing="0" bordercolor="#0000FF">
+ <tr>
+ <td bgcolor="#FFFFCC" bordercolor="white">
+ <p> <b><font size="2">Source: <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaAppletLaunchConfigurationDelegate.java">org.eclipse.jdt.internal.launching.JavaAppletLaunchConfigurationDelegate</a></font></b>
+ </p>
+ </td>
+ </tr>
+</table>
+<p> As noted above, the work of implementing a config type boils down to creating
+ a delegate class that implements the interface <code>org.eclipse.debug.core.ILaunchConfigurationDelegate</code>.
+ The only method on this interface is: </p>
+<pre>
+public void launch(ILaunchConfiguration configuration,
+ String mode,
+ ILaunch launch,
+ IProgressMonitor monitor) throws CoreException;
+</pre>
+<p> The first argument, <code>configuration</code>, is the most important. This
+ specifies the config to be launched. The Debug UI framework ensures that your
+ delegate is never asked to launch a config of the wrong type, however there
+ is no such guarantee for programmatic launching, so you may want to verify the
+ type of the <code>config</code> argument. In simple terms, the job of the <code>launch()</code>
+ method is to extract all of the pertinent information from this config and then
+ act upon it. For our applet launcher, this information includes things such
+ as the name of the Applet class, the JRE to use, the width &amp; height of the
+ applet panel viewing area, the classpath to use and so on. Once this information
+ has been extracted from the config and checked for validity, it is used to first
+ generate an HTML file and then to launch an instance of the <code>appletviewer</code>
+ utility on this HTML file. </p>
+<p> The <code>mode</code> attribute has a value of either ' <code>run</code>'
+ or ' <code>debug</code> ' . Once again, the Debug UI framework makes sure your
+ delegate is not asked to launch in a mode it can't handle, but with programmatic
+ launching, any developer can ask your delegate to do anything, so some sanity
+ checking is a good idea. </p>
+<p> <img src="images/tip.gif" width="62" height="13"> <em>When specifying a launch
+ mode in code, you should never use a hard-coded <code>String</code>. Instead,
+ use one of the constants defined in <code>org.eclipse.debug.core.ILaunchManager</code>.</em>
+</p>
+<p> The third argument, <code>launch</code>, is the top-level debug model artifact
+ that represents a launch. This object is created before the <code>launch()</code>
+ method is called. The delegate's responsibility with respect to this argument
+ is to add the debug targets and/or processes that result from launching to it.
+ In our applet launcher, this is done inside the <code>IVMRunner.run()</code>
+ call. </p>
+<p> The last argument, <code>monitor</code>, is the progress monitor you should
+ update during any long-running operations you perform. In addition, you should
+ periodically check this monitor to see if the user has requested that the launch
+ be canceled. This can be done via <code>monitor.isCanceled()</code>. Doing this
+ allows your users the chance to change their minds, which makes your launcher
+ much friendlier. Note that <code>monitor</code> may be <code>null</code> (for
+ example, during a programmatic launch). </p>
+<p> The implementation of the <code>launch()</code> method for our applet launcher
+ delegate is made easier by that fact that the delegate extends <code>org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate</code>.
+ This class provides common functionality that most Java-oriented launchers will
+ need. For example, it has methods to retrieve and verify Java-related config
+ attributes such as the main type, classpath, bootpath and VM. In addition, our
+ applet launcher takes advantage of some Java launching infrastructure in the
+ form of <code>org.eclipse.jdt.launching.IVMRunner</code>. The VMRunner's job
+ is simply to build a command line to launch the Java program, call <code>Runtime.exec()</code>
+ on this command line and add the resulting debug targets/processes to the ILaunch
+ object. The reason <code>IVMRunner</code> is an interface with several implementors
+ is that each VM type (1.1.x, 1.3/1.4, J9, etc.) has its own idiosyncrasies.
+ Also, there are different VMRunners for run &amp; debug modes. </p>
+<p> <img src="images/tip.gif" width="62" height="13"> <em>If you are writing a
+ launcher that fires up a JVM, you should seriously consider making your delegate
+ extend <code>AbstractJavaLaunchConfigurationDelegate</code>. Also, you should
+ take advantage of the <code>IVMRunner</code> infrastructure as much as possible.</em>
+</p>
+<p>The following code fragment is taken from the <code>beginning of the launch()</code>
+ method of <code>JavaAppletLaunchConfigurationDelegate</code>:</p>
+<pre><img src="images/tag_1.gif" width="24" height="13">&nbsp;String mainTypeName = verifyMainTypeName(configuration);
+&nbsp;&nbsp;&nbsp;&nbsp;IJavaProject javaProject = getJavaProject(configuration);
+<img src="images/tag_2.gif" width="24" height="13">&nbsp;IType type = JavaLaunchConfigurationUtils.getMainType(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mainTypeName, javaProject);
+&nbsp;&nbsp;&nbsp;&nbsp;ITypeHierarchy hierarchy = type.newSupertypeHierarchy(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new NullProgressMonitor());
+&nbsp;&nbsp;&nbsp;&nbsp;IType javaLangApplet = JavaLaunchConfigurationUtils.getMainType(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;java.applet.Applet&quot;, javaProject);
+<img src="images/tag_3.gif" width="24" height="13">&nbsp;if (!hierarchy.contains(javaLangApplet)) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;abort(&quot;The applet type is not a subclass of java.applet.Applet.&quot;);
+&nbsp;&nbsp;&nbsp;&nbsp;}
+<img src="images/tag_4.gif" width="24" height="13">&nbsp;IVMInstall vm = verifyVMInstall(configuration);
+<img src="images/tag_5.gif" width="24" height="13">&nbsp;IVMRunner runner = vm.getVMRunner(mode);</pre>
+<p>This code snippet is typical of the verification done by the <code>launch()</code>
+ method:<br>
+ <img src="images/tag_1.gif" width="24" height="13"> Use a framework method to
+ verify &amp; return the name of the 'main type', which in our case is the class
+ that extends <code> java.applet.Applet</code>.<br>
+ <img src="images/tag_2.gif" width="24" height="13"> Use a utility method to
+ return the <code>org.eclipse.jdt.core.IType</code> object for the Applet class.<br>
+ <img src="images/tag_3.gif" width="24" height="13"> Make sure that the specified
+ applet class really does extend <code>java.applet.Applet</code>.<br>
+ <img src="images/tag_4.gif" width="24" height="13"> Verify &amp; return the
+ <code>org.eclipse.jdt.launching.IVMInstall</code> object that corresponds to
+ the JRE specified in the configuration.<br>
+ <img src="images/tag_5.gif" width="24" height="13"> Ask the installed VM for
+ a VMRunner appropriate to the specified mode.</p>
+<p>Further along in the <code>launch()</code> method is this snippet of code:</p>
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;// Create VM config
+<img src="images/tag_1.gif" width="24" height="13">&nbsp;VMRunnerConfiguration runConfig = new VMRunnerConfiguration(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;sun.applet.AppletViewer&quot;, classpath);
+&nbsp;&nbsp;&nbsp;&nbsp;runConfig.setProgramArguments(new String[] {buildHTMLFile(configuration)});
+&nbsp;&nbsp;&nbsp;&nbsp;String[] vmArgs = execArgs.getVMArgumentsArray();
+&nbsp;&nbsp;&nbsp;&nbsp;String[] realArgs = new String[vmArgs.length+1];
+&nbsp;&nbsp;&nbsp;&nbsp;System.arraycopy(vmArgs, 0, realArgs, 1, vmArgs.length);
+&nbsp;&nbsp;&nbsp;&nbsp;realArgs[0] = javaPolicy;
+<img src="images/tag_2.gif" width="24" height="13">&nbsp;runConfig.setVMArguments(realArgs);
+
+&nbsp;&nbsp;&nbsp;&nbsp;runConfig.setWorkingDirectory(workingDirName);</pre>
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;// Bootpath
+&nbsp;&nbsp;&nbsp;&nbsp;String[] bootpath = getBootpath(configuration);
+<img src="images/tag_3.gif" width="24" height="13">&nbsp;runConfig.setBootClassPath(bootpath);
+
+&nbsp;&nbsp;&nbsp;&nbsp;// Launch the configuration
+&nbsp;&nbsp;&nbsp;&nbsp;this.fCurrentLaunchConfiguration = configuration;
+<img src="images/tag_4.gif" width="24" height="13">&nbsp;runner.run(runConfig, launch, monitor); </pre>
+<p>This is the code that actually performs the launch:<br>
+ <img src="images/tag_1.gif" width="24" height="13"> Create a <code>VMRunnerConfiguration</code>,
+ which is just a convenience holder of various launch parameters. Notice the
+ program being launched is the <code>appletviewer</code> utility.<br>
+ <img src="images/tag_2.gif" width="24" height="13"> Resolve the VM arguments
+ and set them on the VMRunnerConfiguration.<br>
+ <img src="images/tag_3.gif" width="24" height="13"> Set the Java bootpath on
+ the VMRunnerConfiguration.<br>
+ <img src="images/tag_4.gif" width="24" height="13"> Ask the VMRunner to launch.
+ All information necessary to perform the launch is now contained in <code>runConfig</code>.
+ This method call will result in building a command line and passing it to <code>Runtime.exec()</code>.
+ If the launch mode was 'run', the resulting process is registered with the debug
+ infrastructure. If the launch mode was 'debug', the resulting process is used
+ to create a 'debug target', which is also registered. </p>
+<p>On a Win32 machine, the command line built by the VMRunner to run a HelloWorld
+ applet with our applet launcher might look like:</p>
+<pre>
+C:\Java\jdk1.4.1\bin\javaw.exe
+ -Djava.security.policy=java.policy.applet
+ -classpath C:\TargetWorkspaces\eclipse\MyApplets
+ sun.applet.AppletViewer HelloWorldApplet1030633365864.html
+</pre>
+<p> Debugging the same applet would result in the following command line: </p>
+<pre>
+C:\Java\jdk1.4.1\bin\javaw.exe
+ -Djava.security.policy=java.policy.applet
+ -classpath C:\TargetWorkspaces\eclipse\MyApplets
+ -Xdebug -Xnoagent
+ -Djava.compiler=NONE
+ -Xrunjdwp:transport=dt_socket,suspend=y,address=localhost:14983
+ sun.applet.AppletViewer HelloWorldApplet1030634748522.html
+</pre>
+<p> <img src="images/tip.gif" width="62" height="13"> <em>You can always see the
+ command line used to initiate a launch by right-clicking the resulting process
+ in the Debug View and selecting Properties. This is useful for debugging your
+ delegate.</em> </p>
+<p> To summarize, implementing a config type (Java or otherwise) means implementing
+ the <code>launch()</code> method on your launch configuration delegate. This
+ method has 2 main tasks to perform: </p>
+<ol>
+ <li> Construct a command line and pass it to <code>Runtime.exec()</code> </li>
+ <li> Create debug targets/processes and add these to the ILaunch object </li>
+</ol>
+<p> Note that the first task may sometimes <i>not</i> involve calling <code>Runtime.exec()</code>.
+ For example, the Remote Java Debug delegate does not need to execute anything
+ in the OS because the program to be debugged is already running (possibly on
+ another machine). In general though, if your delegate is launching something
+ under development in the Eclipse workspace, you will probably want to use <code>Runtime.exec()</code>.
+</p>
+<h2>Declaring a launch configuration type icon </h2>
+
+<p> Now that we have a declared and implemented a config type, the next step is
+ to flesh out the various UI elements associated with the config type. First
+ up is an icon for the applet config type: </p>
+<h5> <u>UI declaration</u></h5>
+<pre>
+&lt;extension point=&quot;org.eclipse.debug.ui.launchConfigurationTypeImages&quot;&gt;
+ &lt;launchConfigurationTypeImage
+ icon=&quot;icons/full/ctool16/java_applet.gif&quot;
+ configTypeID=&quot;org.eclipse.jdt.launching.javaApplet&quot;
+ id=&quot;org.eclipse.jdt.debug.ui.launchConfigurationTypeImage.javaApplet&quot;&gt;
+ &lt;/launchConfigurationTypeImage&gt;
+&lt;/extension&gt;
+</pre>
+<p> Note that the <code>id</code> attribute is just a unique identifier, whereas
+ the <code>configTypeID</code> attribute should have the same value as the <code>id</code>
+ attribute for our config type declaration. Notice that the icon is declared
+ via a separate extension point instead of just being an attribute on the config
+ type declaration. This is in keeping with the goal of not forcing launcher contributors
+ to provide a UI.</p>
+
+<h2>Implementing a launch configuration type icon </h2>
+<p>There is no code to write when implementing a config type icon, you simply
+ need to create the icon. The icon should be 16x16, contain no more than 256
+ colors, and have a transparent background.</p>
+<h2>
+ Declaring a tab group
+ </h2>
+
+<p> The most important piece of UI to consider when developing a new launcher
+ is the 'tab group'. To understand how tab groups work, we need a little background
+ on the LaunchConfigurationDialog provided by the Debug UI plug-in. This dialog
+ (henceforth known as the 'LCD') is a central point for creating, managing, deleting
+ and launching configs of any config type. If you have used any 2.0 or later
+ version of Eclipse, you have probably seen the LCD: </p>
+ <p>
+ <img src="images/Screenshot1.gif" width="663" height="560">
+ </p>
+ <p>
+ The LCD is broken into two main regions:
+ </p>
+
+<p> <img src="images/tag_1.gif" width="24" height="13"> The config tree shows
+ all configs currently defined in the workspace, grouped by config type. </p>
+ <p>
+ <img src="images/tag_2.gif" width="24" height="13"> The tabbed
+ folder lets users edit attributes of the config currently
+ selected in the tree. The contents of this tabbed folder are
+ specified when you declare a tab group.
+ </p>
+ <p>
+ The 6 tabs in the above figure show the launching attributes
+ for <b>HelloWorldApplet</b>. These same 6 tabs would appear if
+ either of the other two configs of type <b>JavaApplet</b> were
+ selected, though of course they would show different values.
+ If <b>InfiniteLoop</b> were selected, it would show a
+ <i>different</i> set of tabs because this config is of a
+ different config type. When you declare a tab group, you are
+ telling the LCD to use the tabs specified in your tab group
+ for configs of your config type. This makes perfect sense
+ because if your config type requires width &amp; height
+ attributes (for example) in order to launch properly, the only
+ way to get values for these attributes is via a set of tabs
+ that appear when a config of your type is selected in the LCD.
+ Another way to look at this is that if your config type
+ requires some attribute X in order to function, then somewhere
+ on a tab specified in your tab group, there better be some UI
+ widget that collects a value for X.
+ </p>
+ <p>
+ Here is the XML for declaring a tab group:
+ </p>
+
+<h5> <u>UI declaration</u></h5>
+<pre>
+&lt;extension point=&quot;org.eclipse.debug.ui.launchConfigurationTabGroups&quot;&gt;
+ &lt;launchConfigurationTabGroup
+ type=&quot;org.eclipse.jdt.launching.javaApplet&quot;
+ class=&quot;org.eclipse.jdt.internal.debug.ui.launcher.JavaAppletTabGroup&quot;
+ id=&quot;org.eclipse.jdt.debug.ui.launchConfigurationTabGroup.javaApplet&quot;&gt;
+ &lt;/launchConfigurationTabGroup&gt;
+&lt;/extension&gt;
+</pre>
+<p> All that this declaration really does is associate a tab group implementation
+ (a class that implements the interface <code>org.eclipse.debug.ui.ILaunchConfigurationTabGroup</code>)
+ with a config type. Any time a config of the specified type is selected in the
+ LCD, the class named by the <code>class</code> attribute will be used to provide
+ the content of the tabbed folder.</p>
+
+<h2>Implementing tab groups </h2>
+<table border="1" cellspacing="0" bordercolor="#FFFFFF">
+ <tr>
+ <td bgcolor="#FFFFCC" bordercolor="#0000FF">
+ <p> <b><font size="2">Source: <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/JavaAppletTabGroup.java">org.eclipse.jdt.internal.debug.ui.launcher.JavaAppletTabGroup</a></font></b>
+ </p>
+ </td>
+ </tr>
+</table>
+<p> The main job of a tab group is to specify the tabs that will appear in the
+ LCD and set their order. &nbsp;These tabs may have been specially written for
+ the&nbsp;particular config type in question, or they may be general purpose
+ tabs that appear for multiple config types. &nbsp;The tab group for our applet
+ launcher&nbsp;creates 6 tabs, of which 4&nbsp;already existed (<code>JavaArgumentsTab,
+ JavaJRETab, JavaClasspathTab, CommonTab</code>) and 2&nbsp;which were written
+ just for our applet launcher (<code>AppletMainTab </code>and<code> AppletParametersTab</code>):</p>
+<pre>public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
+ new AppletMainTab(),
+ new AppletParametersTab(),
+ new JavaArgumentsTab(),
+ new JavaJRETab(),
+ new JavaClasspathTab(),
+ new CommonTab()
+ };
+ setTabs(tabs);
+}</pre>
+<p>A tab group is free to mix &amp;&nbsp;match any combination of existing and
+ custom-written tabs. &nbsp;The only proviso is that tabs you wish to reuse must
+ be in public (not internal) packages. &nbsp;In the simplest case, <i>all</i>
+ of the tabs would be preexisting tabs and the work of providing a UI for our
+ config type in the LCD would be done&nbsp;once we had defined a class similar
+ to <code>JavaAppletTabGroup</code>. &nbsp;</p>
+<p><img src="images/tip.gif" width="62" height="13" border="0"> <i>If you are
+ implementing a tab group for a Java-oriented config type, you should consider
+ reusing some or all of the Java tabs in the <code>org.eclipse.jdt.debug.ui.launchConfigurations</code>
+ package.</i></p>
+<p><img src="images/tip.gif" width="62" height="13" border="0"> <i><u>All</u>
+ tab groups should include <code>org.eclipse.debug.ui.CommonTab</code>. &nbsp;This
+ tab contains UI that allows users to make their configs 'local' or 'shared',
+ mark configs as 'favorites' and control perspective switching when launching.
+ &nbsp;By convention, this tab is the last tab in the tab group.</i></p>
+<p>If you decide that you need to write one or more of your own tabs, you need
+ to understand the tab lifecycle defined by <code>org.eclipse.debug.ui.ILaunchConfigurationTab</code>,
+ an interface which all tabs must implement. &nbsp;There is a convenience abstract
+ class, <code>org.eclipse.debug.ui.AbstractLaunchConfigurationTab</code> that
+ implements this interface and provides useful implementations of many of its
+ methods. Whenever possible, you should extend this abstract class.</p>
+<p>The first two events in a tab's life cycle are calls to <code>setLaunchConfigurationDialog(ILaunchConfigurationDialog)</code>and
+ <code>createControl()</code> in that order.&nbsp;The first simply notifies the
+ tab of the LCD object that owns it. Tabs make frequent calls to methods on the
+ LCD, so a&nbsp;tab needs to have a reference to it. &nbsp;The second method
+ creates&nbsp;the GUI widgetry for the tab and lays it&nbsp;out. &nbsp;</p>
+<table border="1" cellspacing="0" bordercolor="#FFFFFF" width="503">
+ <tr>
+ <td bgcolor="#FFFFCC" bordercolor="#0000FF"> <p> <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/AppletParametersTab.java"><b><font size="2">Source:
+ org.eclipse.jdt.debug.ui.launchConfigurations.AppletParametersTab</font></b>
+ </a></p></td>
+ </tr>
+</table>
+<p>To illustrate the rest of the methods on <code>ILaunchConfigurationTab</code>,
+ the <code>AppletParametersTab</code> implementation will be discussed. This
+ class makes three field declarations you need to be aware of:</p>
+<ul>
+ <li> <code>private Text widthText;</code></li>
+ <li><code>private Text heightText;</code></li>
+ <li><code>private Text nameText;</code>
+ </li>
+</ul>
+<p>where <code>Text</code> is the SWT text-field widget.</p>
+<p>The three most important methods on a tab are the following 'value copying'
+ methods:</p>
+<ul type="disc">
+ <li><code>public void setDefaults(ILaunchConfigurationWorkingCopy configuration);</code></li>
+ <li><code>public void performApply(ILaunchConfigurationWorkingCopy configuration);</code></li>
+ <li><code>public void initializeFrom(ILaunchConfiguration configuration);</code></li>
+</ul>
+<p>In general terms, the first two methods copy&nbsp;values from the tab to a
+ working copy,&nbsp;while the third method copies&nbsp;values from&nbsp;a working
+ copy&nbsp;to&nbsp;the tab. &nbsp;The <code>setDefaults()</code> method is called
+ when a new config is&nbsp;created. &nbsp;This method&nbsp;sets default values
+ for all attributes it understands on the working copy argument. &nbsp;This is
+ done differently depending on the nature of the attributes collected by the
+ tab. &nbsp;The <code>AppletMainTab</code> checks the current workbench selection
+ or active editor to determine default values for the Project &amp; Applet class
+ attributes. &nbsp;The <code>CommonTab</code> sets hard-coded defaults, and the
+ <code>JavaJRETab</code> sets the default JRE to be the JRE marked as the workbench
+ default in the Java preferences. </p>
+<p>The <code>performApply()</code> method reads current values from the GUI widgets
+ on the tab and sets the corresponding attribute values on the working copy argument:</p>
+<pre>public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(
+ IJavaLaunchConfigurationConstants.ATTR_APPLET_WIDTH,
+ (String)widthText.getText());
+ configuration.setAttribute(
+ IJavaLaunchConfigurationConstants.ATTR_APPLET_HEIGHT,
+ (String)heightText.getText());
+ configuration.setAttribute(
+ IJavaLaunchConfigurationConstants.ATTR_APPLET_NAME,
+ (String)nameText.getText());
+ configuration.setAttribute(
+ IJavaLaunchConfigurationConstants.ATTR_APPLET_PARAMETERS,
+ getMapFromParametersTable());
+}</pre>
+<p>The <code>initializeFrom()</code> method does the opposite of the <code>performApply()</code>
+ method. &nbsp;It reads attribute values out of the config argument, and sets
+ these values in the corresponding GUI widgets:</p>
+<pre>public void initializeFrom(ILaunchConfiguration config) {
+&nbsp;&nbsp;&nbsp;&nbsp;try {
+<img src="images/tag_1.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fWidthText.setText(Integer.toString(config.getAttribute(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IJavaLaunchConfigurationConstants.ATTR_APPLET_WIDTH, &quot;200&quot;)));
+&nbsp;&nbsp;&nbsp;&nbsp;} catch(CoreException ce) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fWidthText.setText(Integer.toString(DEFAULT_APPLET_WIDTH));
+&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;try {
+<img src="images/tag_2.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fHeightText.setText(Integer.toString(config.getAttribute(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IJavaLaunchConfigurationConstants.ATTR_APPLET_HEIGHT, &quot;200&quot;)));
+&nbsp;&nbsp;&nbsp;&nbsp;} catch(CoreException CE) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fHeightText.setText(Integer.toString(DEFAULT_APPLET_HEIGHT));
+&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;try {
+<img src="images/tag_3.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fNameText.setText(config.getAttribute(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IJavaLaunchConfigurationConstants.ATTR_APPLET_NAME, &quot;&quot;));
+&nbsp;&nbsp;&nbsp;&nbsp;} catch(CoreException CE) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fNameText.setText(&quot;&quot;);
+&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;updateParametersFromConfig(config);
+}</pre>
+<p><img src="images/tag_1.gif" width="24" height="13"> Extract the value of the
+ width attribute from the config and put it in the corresponding <code>Text</code>
+ widget.<br>
+ <img src="images/tag_2.gif" width="24" height="13"> Extract the value of the
+ height attribute from the config and put it in the corresponding <code>Text</code>
+ widget.<br>
+ <img src="images/tag_3.gif" width="24" height="13"> Extract the value of the
+ name attribute from the config and put it in the corresponding <code>Text</code>
+ widget.<br>
+ In all cases, if there is an error retrieving the attribute value, the <code>Text</code>
+ widget is filled with a default value.</p>
+<p>Both <code>performApply(</code>) and <code>initializeFrom()</code> are&nbsp;called
+ frequently, for example, whenever the user selects a new tab. &nbsp;Thus, they
+ should not perform long-running operations.</p>
+<p>The remaining methods on <code>ILaunchConfigurationTab</code> are also fairly
+ straightforward. The <code>isValid(ILaunchConfiguration)</code> method returns
+ <code>true</code> if all of the attributes in the tab currently have values
+ that permit launching, within the context of the specified config:</p>
+<pre>public boolean isValid(ILaunchConfiguration launchConfig) {
+&nbsp;&nbsp;&nbsp;&nbsp;setErrorMessage(null);
+&nbsp;&nbsp;&nbsp;&nbsp;try {
+<img src="images/tag_1.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Integer.parseInt(fWidthText.getText().trim());
+&nbsp;&nbsp;&nbsp;&nbsp;} catch(NumberFormatException nfe) {
+<img src="images/tag_2.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setErrorMessage(&quot;Width is not an integer&quot;);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
+&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;try {
+<img src="images/tag_1.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Integer.parseInt(fHeightText.getText()Trim());
+&nbsp;&nbsp;&nbsp;&nbsp;} catch(NumberFormatException nfe) {
+<img src="images/tag_2.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setErrorMessage(&quot;Height is not an integer&quot;);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
+&nbsp;&nbsp;&nbsp;&nbsp;}
+<img src="images/tag_3.gif" width="24" height="13">&nbsp;return true;
+}
+</pre>
+<p><img src="images/tag_1.gif" width="24" height="13"> The config can be launched
+ only when both the <code>width</code> &amp; <code>height</code> attributes have
+ valid integer values. <br>
+ <img src="images/tag_2.gif" width="24" height="13"> The appropriate response
+ to a validation failure is calling <code>AbstractLaunchConfigurationTab.setErrorMessage(String)</code>
+ with a description of the failure and returning <code>false</code>.<br>
+ <img src="images/tag_3.gif" width="24" height="13"> The other attribute values
+ this tab is responsible for cannot be checked for validity, so at this point
+ we declare the tab valid.</p>
+<p> The <code>canSave()</code> method is similar to <code>isValid()</code>, and
+ returns <code>true</code> if all of the attributes in the tab have values that
+ permit saving. </p>
+<p><img src="images/tip.gif" width="62" height="13" border="0"> <i>If you implement
+ your own tab, consider making it public API so that others can&nbsp;reuse it.</i></p>
+<p>If you compare the API on <code>ILaunchConfigurationTabGroup</code> and <code>ILaunchConfiguration</code>,
+ you will see a number of similarities. In particular, the following methods
+ are common:</p>
+<ul>
+ <li> <code>public void initializeFrom(ILaunchConfiguration configuration);
+ </code></li>
+ <li><code>public void performApply(ILaunchConfigurationWorkingCopy configuration);
+ </code></li>
+ <li><code>public void setDefaults(ILaunchConfigurationWorkingCopy configuration);</code>
+ </li>
+ <li><code>public void launched(ILaunch launch);
+ </code></li>
+</ul>
+<p>You will recognize the 3 'value copying' lifecycle methods for tabs, along
+ with <code>launched(ILaunch)</code> which is simply a callback that happens
+ when a successful launch has occurred. In most cases, the tab group is not interested
+ in these calls and simply forwards them on to its tabs. When this is true, you
+ should make your tab group extend <code>org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup</code>.
+ This abstract class implements these 4 methods to simply loop through all owned
+ tabs and make the corresponding call on each. The applet launcher tab group
+ extends this abstract class. However, there are situations when you might want
+ to implement some of these methods at the tab group level. Suppose you are reusing
+ someone else's tab that specifies a default value for an attribute you don't
+ like. You can change this default value and still reuse the tab by implementing
+ the <code>setDefaults()</code> method on your tab group to first call <code>setDefaults()</code>
+ on the tab in question (which sets the undesirable default value), then directly
+ set the attribute in question to the value you prefer. In this way, you 'override'
+ the one value you care about, while leaving the others as specified in the tab.</p>
+<h2>Declaring launch shortcuts </h2>
+
+<p> As useful as the LCD is, there are many times when users don't want to bother
+ with it. They simply want to launch a program. This is where 'launch shortcuts'
+ come in. A launch shortcut allows users to identify a resource in the workbench
+ (either via selection or the active editor) and launch that resource with a
+ single click <i>without</i> bringing up the LCD. Launch shortcuts are <i>not</i>
+ useful when a user needs to tweak launch configuration attributes because the
+ user gets no chance to set these. Launch shortcuts <i>are</i> useful when the
+ user is happy with default values for all config attributes and wants to launch
+ in a hurry. </p>
+ <p>
+ The following figure shows how launch shortcuts appear in the
+ UI:
+ </p>
+ <p>
+ <img src="images/Screenshot2.gif" width="685" height="355">
+ </p>
+
+<p> <img src="images/tag_1.gif" width="24" height="13"> The 'Run As' sub-menu
+ of the 'Run' drop-down menu shows all config types that have registered a launch
+ shortcut in the current perspective. Selecting one of the 'Run As' sub-menu
+ choices activates the corresponding launch shortcut. </p>
+
+<p> This is the XML to declare the applet launch shortcut: </p>
+
+<h5> <u>UI declaration</u></h5>
+<pre>
+&lt;extension point=&quot;org.eclipse.debug.ui.launchShortcuts&quot;&gt;
+ &lt;shortcut
+ id=&quot;org.eclipse.jdt.debug.ui.javaAppletShortcut&quot;
+ class=&quot;org.eclipse.jdt.internal.debug.ui.launcher.JavaAppletLaunchShortcut&quot;
+ label=&quot;Java Applet&quot;
+ icon=&quot;icons/full/ctool16/java_applet.gif&quot;
+ modes=&quot;run, debug&quot;&gt;
+ &lt;perspective id=&quot;org.eclipse.jdt.ui.JavaPerspective&quot;/&gt;
+ &lt;perspective id=&quot;org.eclipse.jdt.ui.JavaHierarchyPerspective&quot;/&gt;
+ &lt;perspective id=&quot;org.eclipse.jdt.ui.JavaBrowsingPerspective&quot;/&gt;
+ &lt;perspective id=&quot;org.eclipse.debug.ui.DebugPerspective&quot;/&gt;
+ &lt;/shortcut&gt;
+&lt;/extension&gt;
+</pre>
+<p> Though the screenshot showed only the 'Run' shortcuts, launch shortcuts apply
+ equally to both modes. The <code>modes</code> attribute specifies which of the
+ drop-down menus include the shortcut. In addition to being mode sensitive, launch
+ shortcuts can also be configured to only appear in certain perspectives. The
+ <code>perspective</code> sub-elements list each perspective in which the shortcut
+ will be available. Only those perspectives that make sense for a particular
+ shortcut should be specified. For example, specifying a C++ perspective for
+ the Java applet launcher wouldn't be generally useful. Following this rule of
+ thumb leads to better UI scalability.</p>
+
+<h2>Implementing launch shortcuts </h2>
+<table border="1" cellspacing="0" bordercolor="#0000FF" width="504">
+ <tr>
+ <td bgcolor="#FFFFCC" bordercolor="#FFFFFF">
+ <p> <b><font size="2">Source: <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/JavaAppletLaunchShortcut.java">org.eclipse.jdt.internal.debug.ui.launcher.JavaAppletLaunchShortcut</a></font></b>
+ </p>
+ </td>
+ </tr>
+</table>
+<p> The first step in implementing a launch shortcut is determining if you even
+ need to. &nbsp;Launch shortcuts are strictly conveniences that make user's lives
+ easier by allowing them to create a config, set all attributes to default values
+ and launch that config in a single mouse click. &nbsp;If you don't provide a
+ shortcut for your config type, users can always bring up the LCD 'manually',
+ create a config of the desired type and launch it. &nbsp; </p>
+<p><img src="images/tip.gif" width="62" height="13"> <i>There are two ways to
+ bring up the LCD: (1) Choose Run... or Debug... from the drop-down menus to
+ bring up the LCD on the last launched config or (2) As of 2.1, you can Ctrl
+ click a favorite or history item in the drop-down menus to bring up the LCD
+ on the corresponding config.</i></p>
+<p>Launch shortcut classes&nbsp;must implement the <code>org.eclipse.debug.ui.ILaunchShortcut</code>
+ interface. &nbsp;This interface defines two <code>launch()</code> methods: </p>
+<ul type="disc">
+ <li> <code>public void launch(ISelection selection, String mode);</code> </li>
+ <li> <code>public void launch(IEditorPart editor, String mode);</code> </li>
+</ul>
+<p> The only difference between them is how the entity to be launched is specified.
+ &nbsp;In the first method, it's via a workbench selection, in the second it's
+ as an editor part. &nbsp;Typically, both of these methods will defer the real
+ work of creating a config and launching it to a helper method once the entity
+ to be launched has been resolved:</p>
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;public void launch(IEditorPart editor, String mode) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IEditorInput input = editor.getEditorInput();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IJavaElement javaElement =
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(IJavaElement) input.getAdapter(IJavaElement.class);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (javaElement != null) {
+<img src="images/tag_1.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchAndLaunch(new Object[] {javaElement}, mode);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;}</pre>
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;public void launch(ISelection selection, String mode) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (selection instanceof IStructuredSelection) {
+<img src="images/tag_1.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchAndLaunch(((IStructuredSelection)selection).toArray(), mode);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;}
+
+
+&nbsp;&nbsp;&nbsp;&nbsp;protected void searchAndLaunch(Object[] search, String mode) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IType[] types = null;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (search != null) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {
+<img src="images/tag_2.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;types = AppletLaunchConfigurationUtils.findApplets(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new ProgressMonitorDialog(getShell()), search);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (Exception e) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Handle exceptions */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IType type = null;
+<img src="images/tag_3.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (types.length == 0) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageDialog.openInformation(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getShell(), &quot;Applet Launch&quot;, &quot;No applets found.&quot;};
+<img src="images/tag_4.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if (types.length &gt; 1) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type = chooseType(types, mode);
+<img src="images/tag_5.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type = types[0];
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (type != null) {
+<img src="images/tag_6.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;launch(type, mode);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;}
+
+&nbsp;&nbsp;&nbsp;&nbsp;protected void launch(IType type, String mode) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ILaunchConfiguration config = findLaunchConfiguration(type, mode);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (config != null) {
+<img src="images/tag_7.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;config.launch(mode, null);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (CoreException e) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Handle exceptions*/
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;}</pre>
+<p><img src="images/tag_1.gif" width="24" height="13"> Both <code>launch()</code>
+ methods from the <code>ILaunchShortcut</code> interface defer the real work
+ to <code>searchAndLaunch()</code>. Notice that in the first <code>launch()</code>
+ method, we have to resolve the entity to launch from the editor, whereas in
+ the second, the selection contains the candidate entities to launch.<br>
+ <img src="images/tag_2.gif" width="24" height="13"> Since there may be more
+ than one candidate entity to launch, we first filter out any that aren't applets.<br>
+ <img src="images/tag_3.gif" width="24" height="13"> We handle the case of no
+ applets to launch by showing an informational dialog.<br>
+ <img src="images/tag_4.gif" width="24" height="13"> If there is more than one
+ applet available to launch, ask the user to choose one.<br>
+ <img src="images/tag_5.gif" width="24" height="13"> Otherwise, there's exactly
+ one applet.<br>
+ <img src="images/tag_6.gif" width="24" height="13"> If there's an applet to
+ launch, do so.<br>
+ <img src="images/tag_7.gif" width="24" height="13"> Launch a config corresponding
+ to the applet. The <code>findLaunchConfiguration()</code> method first attempts
+ to find an existing config for the applet. Failing this, a new config is created
+ and returned. Note that the actual launching happens by just calling <code>launch()</code>
+ on the config. </p>
+<p>In most cases, a launch shortcut is maximally useful if it performs the following
+ steps: </p>
+<ol type="1">
+ <li> Resolve something to launch from the specified selection or editor </li>
+ <li> Check to see if there is an existing config based on the resolved entity,
+ if there is launch it </li>
+ <li> Otherwise, create a new config and populate it with default attribute values,
+ except for those directly related to the resolved entity </li>
+ <li> Launch the new config </li>
+</ol>
+<p> However, there is nothing in the <code>ILaunchShortcut</code> interface that
+ requires you to follow these steps. &nbsp;For example, you could create a launch
+ shortcut implementation that skipped step 2. &nbsp;This way, <i>every</i> time
+ the shortcut was invoked, a new config would be created. &nbsp;This would normally&nbsp;lead
+ to a flood of duplicate configs, however if the default value for an&nbsp;attribute
+ was somehow time-dependent, this could be useful. &nbsp;Another variation might
+ be to open the LCD on the newly created config. This might be necessary if some
+ attribute has no reasonable default value and must be specified by the user.
+ Note that even in this case, the shortcut saves time and keystrokes by creating
+ a config and populating most of its attributes with appropriate values. The
+ user only has to supply the required attribute(s), then click Run or Debug.</p>
+<p> In summary, launch shortcuts are optional. &nbsp;If you choose to implement
+ one, you should consider making it as useful as possible to your users. This
+ might mean avoiding duplicate configs, or saving as many keystrokes as possible.
+ &nbsp;In the end though, the <code>ILaunchShortcut</code> contract is very flexible
+ and just&nbsp;provides a way to insert an action into a particular place in
+ the UI.</p>
+<h2>Declaring a launch group</h2>
+<p><img src="images/tip.gif" width="62" height="13"> <i>Most developers writing
+ launchers will not need to worry about 'launch groups', but they are covered
+ here for completeness. </i></p>
+<p>Launch groups (introduced in Eclipse 2.1) are an organizational construct for
+ config types whose primary purpose is to provide a way to filter configs &amp;
+ configs types in the UI. Standard UI components supplied by the launching framework
+ such as the LCD are set up to always filter their contents with a single active
+ launch group. In addition, the workbench tracks separate launch histories for
+ each launch group. The Eclipse SDK provides two default launch groups, a standard
+ 'Run' launch group and a standard 'Debug' launch group. When you open the LCD
+ by choosing 'Debug...' from the debug drop-down menu, you are actually asking
+ the LCD to open and display only configs that satisfy the filtering criteria
+ specified by the standard 'Debug' launch group. </p>
+<p>The filtering criteria of a launch group are specified in two pieces, a <code>mode</code>
+ attribute (run or debug) and an optional <code>category</code> attribute. Remember
+ that the config type declaration also included an optional <code>category</code>
+ attribute. The purpose of this attribute is now clear - it serves to associate
+ config types with launch groups. If a launch group specifies a value for its
+ <code>category</code> attribute, then only config types that specify the same
+ value for their <code>category</code> attributes are considered to belong to
+ that launch group. The <code>mode</code> attribute serves to further refine
+ which configs &amp; config types belong to a specific launch group. Recall that
+ config types declare their support for one or both of the allowable modes, run
+ and debug. A launch group must specify exactly one of these modes in its declaration.
+ We can now specify the complete filtering algorithm used to apply launch groups
+ to UI elements such as the LCD:</p>
+<ul>
+ <li> A config type is visible if it supports the mode of the currently active
+ launch group <i><b>and</b></i> specifies the same category as the currently
+ active launch group.</li>
+ <li> A config is visible if its config type is visible.</li>
+</ul>
+<p>This is the XML declaration of the standard 'Run' &amp; 'Debug' launch groups:</p>
+<h5> <u>UI declaration</u></h5>
+<pre>&lt;extension point = &quot;org.eclipse.debug.ui.launchGroups&quot;&gt;
+ &lt;launchGroup
+ id = &quot;org.eclipse.debug.ui.launchGroup.debug&quot;
+ mode = &quot;debug&quot;
+ label =&quot;Debug&quot;
+ image = &quot;icons/full/ctool16/debug_exc.gif&quot;
+ bannerImage = &quot;icons/full/wizban/debug_wiz.gif&quot;&gt;
+ &lt;/launchGroup&gt;
+ &lt;launchGroup
+ id = &quot;org.eclipse.debug.ui.launchGroup.run&quot;
+ mode = &quot;run&quot;
+ label = &quot;Run&quot;
+ image = &quot;icons/full/ctool16/run_exc.gif&quot;
+ bannerImage = &quot;icons/full/wizban/run_wiz.gif&quot;&gt;
+ &lt;/launchGroup&gt;
+&lt;/extension&gt;</pre>
+<p>Notice that neither declaration specifies a <code>category</code>. This means
+ that only config types that also do not specify a category attribute will be
+ visible when one of these launch groups is active in the UI. All of the standard
+ launchers included in the SDK fall into this category: Java Application, Java
+ Applet, Remote Java Application, JUnit &amp; Run-time Workbench. </p>
+<p>The rest of the available options for a launch group declaration are straightforward.
+ The <code>id</code>, as always, is merely a unique identifier for the launch
+ group, <code>label</code> is a human-readable description of the launch group,
+ and <code>image</code> and <code>bannerImage</code> are a 16x16 icon and a larger
+ image suitable for placing at the top of a wizard or dialog. Not shown above
+ is an optional <code>public</code> attribute that controls whether the launch
+ group's history is editable by the user in the workbench Debug preferences.
+ The default value if this attribute is not specified is <code>true</code>.</p>
+<p>Given that the standard toolbar drop down actions always open the LCD with
+ one of the two default launch groups active, you might wonder about the usefulness
+ of launch groups. In other words, if all of the standard SDK launchers belong
+ to the empty category, and the LCD always opens on either the empty debug or
+ empty run launch group, what is the point? The answer is that unless you are
+ trying to use the launch config framework in new and clever ways, launch groups
+ aren't of much interest. However, if you want to use the launch config framework
+ to do things other than launch code under development, launch groups can be
+ useful. </p>
+<p>As an example of a <i>useful</i> application of launch groups, we will look
+ at the external tools plug-ins. The purpose of the external tools plug-ins is
+ to allow developers to run things <i>other</i> than the code they are currently
+ developing. Sometimes these programs are tangential to the development process,
+ such as an MP3 player or a mail client. Other times, developers might want to
+ launch Ant scripts that build or deploy projects. This type of launching is
+ different from the launching discussed so far in this article, but it does have
+ many similarities. Because of the similarities, the launch config framework
+ was used as the basis of the launching-related pieces of the external tools
+ plug-ins. </p>
+<p>Below is the declaration of two launch groups associated with external tools:</p>
+<h5> <u>UI declaration</u></h5>
+<pre>&lt;extension point = &quot;org.eclipse.debug.ui.launchGroups&quot;&gt;
+ &lt;launchGroup
+ id = &quot;org.eclipse.ui.externaltools.launchGroup&quot;
+ mode = &quot;run&quot;
+ category = &quot;org.eclipse.ui.externaltools&quot;
+ label = &quot;&amp;External Tools&quot;
+ image = &quot;icons/full/obj16/external_tools.gif&quot;
+ bannerImage = &quot;icons/full/wizban/ext_tools_wiz.gif&quot;&gt;
+ &lt;/launchGroup&gt;
+ &lt;launchGroup
+ id = &quot;org.eclipse.ui.externaltools.launchGroup.builder&quot;
+ mode = &quot;run&quot;
+ category = &quot;org.eclipse.ui.externaltools.builder&quot;
+ label = &quot;&amp;External Tools&quot;
+ image = &quot;icons/full/obj16/external_tools.gif&quot;
+ bannerImage = &quot;icons/full/wizban/ext_tools_wiz.gif&quot;
+ public = &quot;false&quot;&gt;
+ &lt;/launchGroup&gt;
+&lt;/extension&gt;
+ </pre>
+<p>Notice that each launch group specifies its own <code>category</code>. This
+ is so that UI components don't display 'regular' external tool configs and 'builder'
+ external tool configs at the same time. It also means that there are two different
+ launch histories for these configs (though the 'builder' history is not public
+ so it does not appear in the Debug preferences). In addition, this means that
+ the external tools plug-ins are free to create launch configs as they see fit,
+ without fear that these configs might show up in the LCD when the user is trying
+ to run code they are developing. Finally, this means that the external tools
+ plug-ins can implement their own relaunching actions and not worry about accidentally
+ launching a program under development.</p>
+<h2>Implementing a launch group</h2>
+<table border="1" cellspacing="0" bordercolor="#0000FF" width="398">
+ <tr>
+ <td bgcolor="#FFFFCC" bordercolor="#FFFFFF">
+ <p> <b><font size="2">Source: <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java">org.eclipse.debug.ui.DebugUITools</a></font></b></p>
+ </td>
+ </tr>
+</table>
+
+<p>Implementing a launch group does not require implementing any API. A launch
+ group exists simply as an XML declaration with no associated classes. However,
+ there is some launch group-related API you should be aware of. This API allows
+ developers to bring up the LCD with a specified launch group actively filtering
+ its contents. It is worth repeating that this is <b><i>not</i></b> something
+ most launcher developers need to worry about. It is only useful if you have
+ a need to show configs of a specific config type and mode separately from all
+ other configs. </p>
+<p>The <code>DebugUITools</code> class defines the following two launch group-related
+ methods:</p>
+<pre><img src="images/tag_1.gif" width="24" height="13">&nbsp;public static int openLaunchConfigurationDialogOnGroup(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Shell shell, IStructuredSelection selection, String groupIdentifier);
+<img src="images/tag_2.gif" width="24" height="13">&nbsp;public static int openLaunchConfigurationPropertiesDialog(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Shell shell, ILaunchConfiguration configuration, String groupIdentifier);</pre>
+
+<p>Both of these methods are used to bring up UI components subject to filtering
+ provided by the specified launch group. In both cases, <code>groupIdentifier</code>
+ is the value of the <code>id</code> attribute in a launch group XML declaration,
+ and <code>shell</code> is just the SWT Shell that will be the parent of the
+ new UI component. </p>
+<img src="images/tag_1.gif" width="24" height="13"> This method opens the LCD
+and sets the tree selection to the specified selection, which may contain any
+combination of <code>ILaunchConfigurationType</code>s and <code>ILaunchConfiguration</code>s.
+<br>
+<img src="images/tag_2.gif" width="24" height="13"> While the previous method
+opens the entire LCD, this method opens just the tabbed folder properties area
+for the specified config; the tree is not shown. This is useful for allowing the
+user to edit a single config without any extraneous UI.
+<p>One other related method on <code>DebugUITools</code> is:</p>
+<pre>public static int openLaunchConfigurationDialog(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Shell shell, IStructuredSelection selection, String mode);</pre>
+<p>This method opens the LCD much as method <img src="images/tag_1.gif" width="24" height="13">
+ did above, except that the launch group used for filtering is based on the value
+ of <code>mode</code>. If <code>mode</code> is '<code>debug</code>', the LCD
+ is opened on the empty 'Debug' launch group, otherwise it is opened on the empty
+ 'Run' launch group. This can be useful even if you aren't defining launch groups,
+ since it allows developers to pop up the LCD with an arbitrary selection. </p>
+<p>To summarize, most launcher developers will never need to concern themselves
+ with launch groups. They are a technique for filtering configs and config types
+ in the UI that is hidden from the user, in other words, the user has no way
+ to control which launch group is active in the UI. Launch groups are useful
+ when a developer uses the launch configuration framework to do something <i>other</i>
+ than write a launcher that launches user code under development.</p>
+
+<h2>Declaring a launch configuration comparator</h2>
+<p>The following discussion of launch configuration comparators is somewhat more
+ advanced than the previous sections, and the implementation example requires
+ a bit more knowledge of Java and the Eclipse JDT plug-ins (however launch configuration
+ comparators are <i><b>not</b></i> Java-specific and can be implemented for any
+ debug model). Launch configuration comparators are an entirely optional feature
+ of launchers, so this section and the following section on implementation can
+ be safely skipped.</p>
+<p>Because all attributes on a config are defined by the developer, the Debug
+ core &amp; Debug UI infrastructures have no knowledge of attribute semantics.
+ They know only that there is a <code>String</code>-valued attribute named JRE,
+ not that this String is a memento that specifies the installed name and type
+ of the JRE. This gets to be a problem when the debug infrastructure needs to
+ perform comparisons with configs, for example, determine if two config objects
+ actually represent the same underlying configuration, or in the LCD, determine
+ if a config has been modified by the user. Without help from the developer,
+ the best the infrastructure can do is call <code>Object.equals(Object)</code>
+ on attribute values (or use <code>==</code> for primitive types). This may be
+ fine for some attributes, but you can imagine situations in which this would
+ be incorrect. For example, suppose your tab group collects a list of <code>String</code>s
+ as an attribute value, and suppose that order is not significant. Left to its
+ own devices, the Debug infrastructure would determine that two configs containing
+ the same list of Strings in their attribute values but in different orders,
+ were not equal. The solution to this problem lies in declaring a launch configuration
+ comparator. This is an entity that the Debug infrastructure will use to perform
+ all comparisons for attributes with a specified name. The Java Applet launcher
+ doesn't declare any comparators, but the standard Java Application launcher
+ does:</p>
+<p><u><b>Non-UI declaration</b></u> </p>
+<pre>&lt;extension point=&quot;org.eclipse.debug.core.launchConfigurationComparators&quot;&gt;
+ &lt;launchConfigurationComparator
+ id=&quot;org.eclipse.jdt.launching.classpathComparator&quot;
+ class=&quot;org.eclipse.jdt.internal.launching.RuntimeClasspathEntryListComparator&quot;
+ attribute=&quot;org.eclipse.jdt.launching.CLASSPATH&quot;/&gt;
+&lt;/extension&gt;</pre>
+<p>This declaration tells the Debug infrastructure to use the class <code>RuntimeClasspathEntryListComparator</code>
+ any time it performs a comparison involving an attribute named &quot;<code>org.eclipse.jdt.launching.CLASSPATH</code>&quot;.
+ Note that this comparator will be used for <i>all</i> attributes with this name,
+ regardless of config type. This allows you to reuse comparators that have already
+ been implemented by other developers, but requires caution in attribute naming.</p>
+<p><img src="images/tip.gif" width="62" height="13"> <i>When creating names for
+ config attributes, you should always prefix them with the fully qualified name
+ of your plug-in. This avoids potential collisions down the road if someone else
+ extends your launcher. It also avoids unintentionally using someone else's comparator.</i></p>
+<h2>Implementing a launch configuration comparator</h2>
+<table border="1" cellspacing="0" bordercolor="#0000FF" width="526">
+ <tr>
+ <td bgcolor="#FFFFCC" bordercolor="#FFFFFF">
+ <p> <b><font size="2">Source: <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/RuntimeClasspathEntryListComparator.java">org.eclipse.jdt.internal.launching.RuntimeClasspathEntryListComparator</a></font></b>
+ </p>
+ </td>
+ </tr>
+</table>
+<p>To implement a launch configuration comparator, you simply need to implement
+ the standard Java library interface <code>java.util.Comparator</code>. This
+ interface defines a single method, <code>public int compare(Object o1, Object
+ o2)</code> that returns a negative value if <code>o1</code> is less than <code>o2</code>,
+ zero if <code>o1</code> equals <code>o2</code> and a positive value if <code>o1</code>
+ is greater than <code>o2</code>: </p>
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;public int compare(Object o1, Object o2) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List list1 = (List)o1;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List list2 = (List)o2;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (list1.size() == list2.size()) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; list1.size(); i++) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String memento1 = (String)list1.get(i);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String memento2 = (String)list2.get(i);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IRuntimeClasspathEntry entry1 =
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaRuntime.newRuntimeClasspathEntry(memento1);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IRuntimeClasspathEntry entry2 =
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaRuntime.newRuntimeClasspathEntry(memento2);
+<img src="images/tag_1.gif" width="24" height="13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!entry1.equals(entry2)) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (CoreException e) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LaunchingPlugin.log(e);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+ &nbsp;&nbsp;&nbsp;&nbsp;return -1;
+&nbsp;&nbsp;&nbsp;&nbsp;}</pre>
+<p><img src="images/tag_1.gif" width="24" height="13"> This method simply reconstructs
+ <code>IRuntimeClasspathEntry</code> objects from the <code>String</code> mementos
+ stored in the <code>List</code> arguments, then calls <code>equals(Object)</code>
+ on these. The implementation of <code>equals()</code> on the <code>IRuntimeClasspathEntry</code>
+ objects will do an intelligent comparison.</p>
+<p>Another use for comparators is disambiguating default values for attributes.
+ Consider an integer-valued attribute named 'address' whose default value is
+ zero. If the debug infrastructure is asked to compare two configs, one of which
+ has an address value of zero, and the other which has no address attribute,
+ it would normally declare these to be not equal. However the absence of an address
+ value should in most cases mean the same thing as a default address value. The
+ solution is to implement a comparator that encapsulates this logic. </p>
+<p><img src="images/tip.gif" width="62" height="13"> <i>In the LCD, if you select
+ a config, then without making any changes to it select a different config and
+ are asked if you wish to save changes, the problem is probably due to a mismatch
+ between a default attribute value and no attribute value. Implement a comparator
+ to fix the problem.</i></p>
+<h2>Putting it all together</h2>
+<p>There are a couple of things to keep in mind while developing a launcher:</p>
+<ul>
+ <li>Putting your UI code in one plug-in and everything else in another plug-in
+ makes your launcher easier to maintain, facilitates programmatic launching,
+ and allows you or someone else to provide an alternate UI for your launcher.</li>
+ <li>If your delegate requires some attribute to function properly, there must
+ be UI somewhere in your tab group to collect it</li>
+ <li>The 3 main 'value copying' methods on tabs are called frequently and must
+ execute quickly. If you need to perform some sort of lengthy validation, consider
+ waiting until launch time to do it.</li>
+</ul>
+<h2>Work smarter, not harder</h2>
+<p>The first rule of implementing a launcher is to reuse as much as possible.
+ If you are implementing a Java-oriented launcher, there is a large amount of
+ code that is part of the Eclipse SDK, is public API and ready to be reused.
+ This article has pointed the opportunities for Java-oriented reuse. Non-Java
+ launchers can also take advantage of reuse. For example, consider extending
+ language-independent abstract API classes like: </p>
+<ul>
+ <li><code>org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup</code> </li>
+ <li><code>org.eclipse.debug.ui.AbstractLaunchConfigurationTab</code>. </li>
+</ul>
+<p>To get further reuse outside of Java, you need to identify plug-ins that contain
+ code you wish to reuse. Encourage other plug-in developers to make their launching
+ related classes public so that you can reuse them, and consider making your
+ own launching-related classes public for the same reason. </p>
+<h2>Source code</h2>
+<p>The Java Applet launcher discussed in this article is part of the Eclipse SDK,
+ as of release 2.1. All UI code for this launcher is found in the <code>org.eclipse.jdt.debug.ui</code>
+ plug-in, while the non-UI code lives in the <code>org.eclipse.jdt.launching</code>
+ plug-in. </p>
+<h2>Acknowledgments</h2>
+<p>Special thanks to Olivier Thomann, the author of the original applet launcher
+ plug-in. Also thanks to Vadim Berestetsky, Erich Gamma, Paul Gooderham, Dave
+ Wathen and Darin Wright for reading early drafts of this article and providing
+ feedback and suggestions. </p>
+</body>
+</html>
+
diff --git a/Article-Levels-Of-Integration/Levels Of Integration.html b/Article-Levels-Of-Integration/Levels Of Integration.html
new file mode 100644
index 0000000..5b89003
--- /dev/null
+++ b/Article-Levels-Of-Integration/Levels Of Integration.html
@@ -0,0 +1,251 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>Levels of Integration</title>
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+<body>
+<div align="right">
+ <font size="-1">Copyright &copy; 2001 Object Technology International, Inc</font></div>
+<table border=0 cellspacing=0 cellpadding=2 width="100%" >
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></b></td>
+ </tr>
+</table>
+<h1> <img src="images/idea.jpg" height=86 width=120 align=CENTER></h1>
+<center>
+ <h1> Levels Of Integration</h1>
+</center>
+<center>
+ <h3>Five ways you can integrate with the Eclipse Platform</h3>
+</center>
+<blockquote><b>Summary</b> <br>
+ The types of problems web application developers face today require the use
+ of a diverse set of tools that operate in many domains. In order to provide
+ flexible tool integration, a tool integration platform must allow tool developers
+ to target different levels or integration based on the desired level of investment,
+ time to market, and specific tool needs. Each integration level determines how
+ a tool must behave, and what end users can expect as a result. This article
+ defines the different levels of tool integration supported by Eclipse, and gives
+ an overview of how they work.<br>
+<p><b>By Jim Amsden, OTI</b>
+<br>
+ <font size="-1">March 25, 2001</font> </p>
+</blockquote>
+
+<p>
+ <hr width="100%">
+ <h3 align="left">Web Application development results in the need for&nbsp;integrated tools</h3>
+ <p><font color="#000000" >The Web&nbsp;represents a complex, highly dynamic, rapidly changing application problem space. A Web application incorporates many resource types representing diverse, yet highly interrelated components including: HTML, GIF, JPEG, DHTML, scripting, Java&trade; Applets, ActiveX controls, servlets, etc. In most cases, these resources are never collectively compiled in order to validate the intended relationships. This often results in applications that are fragile, and difficult to test, scale, and maintain.</font></p>
+ <p><font color="#000000"
+ >Because of this wide range of content types, building a Web application requires a set of diverse, highly specialized skills including: programmers, graphic designers, database designers, business experts, and document designers. The overall architecture of Web applications&nbsp;is established by the target runtime including client web browsers and HTTP, and web application servers. The resulting distributed applications require compromises between accessibility, availability, integrity, ease of use, performance, and footprint. Web applications are targeted to a broad audience&nbsp;which requires emphasis on ease of use, appealing look and feel, and masking resource and distribution technologies. This isn't easy stuff!</font></p>
+ <p><font color="#000000" >To make matters worse, techniques for developing Web applications are changing fast. Developers end up using new and immature technologies and tools in different stages of maturity: new tools, new revisions of old tools, and beta releases of emerging tools.&nbsp;There is a significant opportunity for point tools that support emerging web technologies to facilitate application development. However, these tools must be effectively integrated with other tools in order to speed Web application development, minimize gaps and overlaps between tools, and provide a positive developer experience.</font></p>
+ <h3>Tools vendors need to maximize acceptance while minimizing development cost</h3>
+ <p><font color="#000000" >In order to be successful, tool developers need to focus on the value added by their tools while minimizing their investment in &quot;plumbing&quot;, porting to other operating systems, browsers, and/or web servers, and minimizing the amount of ancillary functionality that must be provided in order for their tool to be accessible and useful. Minimizing this investment involves integrating tools with other complementary tools and IDEs in such a way that the integrated result provides more value to the end user than the individual tools by themselves. However, integrating tools can require a significant investment! Each tool or IDE that is a candidate for integration may provide its own set of extensibility and integration&nbsp; mechanisms. In order to achieve maximum market penetration, a tool vendor needs to integrate with as many other tools and IDEs as possible, and in such a way that the tools complement each other without creating undue redundancy and coupling.</font></p>
+ <h3>The Eclipse Platform provides a tool integration framework</h3>
+ <p><font color="#000000"
+ >The Eclipse Platform reduces the cost of tool integration by providing a large number of services, APIs, and frameworks that enable effective and scalable tool integration. Wherever possible, Eclipse uses open standards to limit tool vendor investment and reduce time to market. The Platform provides a focal point for integrating and configuring best-of-breed tools in a manner that best fits the end user's development process and Web application architecture. The Eclipse Workbench provides a central integration point for project control and an integration mechanism&nbsp;for resource-specific tools. This approach allows a user to build applications using a heterogeneous set of tools while at the same time providing a common view of the complete application across all components and the entire team.&nbsp;</font></p>
+ <p><font color="#000000" >The Eclipse Platform can also provide services common to different tools including user interface frameworks, managing relationships between components, component version management, and publishing services. Using Eclipse simplifies tool integration by allowing tools to integrate with the platform instead of each other. This significantly reduces the number of integration problems that must be solved, and provides a more consistent environment for the end user.</font></p>
+<h3><A name=ConformanceLevels></A>Integration Conformance Levels</h3>
+<p><font color="#000000" >Full integration with Eclipse provides an experience for the end user that is so seamless they can't tell where one tool ends and another begins. However full integration isn't always practical for all tools. In order to provide flexible tool integration, Eclipse supports a number of integration levels that tool developers can target based on the desired level of investment, time to market, and specific tool needs. Each level specifies what tool vendors must do to achieve that level of integration, and the required technologies that must be employed. The integration levels are summarized in the table below, and described in detail in the following sections.</font></p>
+ <DIV align=center>
+ <TABLE border=1 cellPadding=1 cellSpacing=1 width="75%">
+ <TR>
+ <TD>
+ <P align=left><STRONG>None</STRONG></P>
+ </TD>
+ <TD>No integration, tools are separate and independent.</TD>
+ </TR>
+ <TR>
+ <TD><STRONG>Invocation</STRONG></TD>
+ <TD>Integration is through invocation of registered applications on resource
+ types</TD>
+ </TR>
+ <TR>
+ <TD><STRONG>Data</STRONG></TD>
+ <TD>Integration is achieved through data sharing</TD>
+ </TR>
+ <TR>
+ <TD><STRONG>API</STRONG></TD>
+ <TD>Tools interact with other tools through Java APIs that abstract tool
+ behavior and make it publicly available</TD>
+ </TR>
+ <TR>
+ <TD><STRONG>UI</STRONG></TD>
+ <TD>Tools and their user interfaces are dynamically integrated at runtime including window panes, menus, toolbars, properties, preferences, etc.</TD>
+ </TR>
+ </TABLE>
+</DIV>
+ <h4><a name=None></a>None - No integration</h4>
+ <blockquote>
+ <p><font color="#000000"
+ >Tools don't always need to be integrated. If a tool has a good user
+ interface that is consistent with the host platform, doesn't share or require
+ require data other tools, or has limited relationships with other resources,
+ there may be no need to integrate it with other tools.</font></p>
+ <p><font color="#000000"
+ >At this level, there is no integration of the tool with other Eclipse-based
+ tools. Users use the tool and other Eclipse tools independently. Any integration
+ is done by the end user through their own development processes. This level
+ provides no integration services, and requires nothing of tool vendors. </font></p>
+</blockquote>
+ <h4><a name=Invocation></a>Invocation - Tool launched in external process</h4>
+ <blockquote>
+ <p><font color="#000000">Invocation, or launch, integration allows the Eclipse platform to be configured to invoke a tool on resources of a specific type. Using the Eclipse resource navigator view, the tool is launched in a separate window, and is completely responsible for managing all aspects of the resource contents. Since the Eclipse workspace is a view on the local file system, other tools can easily be launched on the user's project files. There is no need to export, modify, and reimport resources in order to use them with Eclipse. File based tools can also benefit from the Eclipse resource management facilities for version management, team support, access control, and synchronization with a shared team server.</font></p>
+ <p><font color="#000000">The Eclipse Platform provides an operating system independent
+ registry mechanism for registering tools to be invoked on resource types.
+ Tools that integrate at the invocation level only need to specify the resource
+ types they are interested in managing.</font></p>
+ <p><font color="#000000">Invocation integration is often the best place to start when integrating existing tools, especially file based tools that have user interfaces conforming to the host platform conventions. The tool doesn't run in the Eclipse workbench, doesn't share the same JVM, and can't integrate with other Eclipse views and editors. But it can be launched and use the Eclipse project model and resource management facilities. Developers can use the Eclipse Workbench as a central control point for navigating, editing, and managing all their project resources, including the ones manipulated the launched tools. That's a lot of functionality for practically no additional investment. </font></p>
+</blockquote>
+ <h4><a name=Data></a>Data - Data sharing</h4>
+ <blockquote>
+ <p><font color="#000000">Data integration allows data manipulated by the tool to be available to other tools. Data integration has three requirements on tool integration frameworks; an access method, an interchange protocol, and data transformation facilities. The access method says how applications access other applications' data. The interchange method specifies the form in which the data is accessed. Sometimes the form of the source data is not ideal for the requesting client. Transformation facilities are used to transform the data to make it more useful by the requesting application. These data integration requirements and facilities must be met independently of the actual data repositories, schemas, and physical stored data formats. This way multiple client applications can share data while minimizing the coupling between them.</font></p>
+ <p><font color="#000000"
+ >The Eclipse platform supports managed resources representing the
+ persistent state of some tool's data. These resources are edited and saved
+ in the user's private workspace on their local file system where they are
+ isolated from changes made by other members of the team. The resource manager
+ uses standard file access mechanisms to access resources. There is no proprietary
+ repository. File contents are not dictated by the platform. The platform can
+ be configured through workbench extension points to support any resource type.
+ To facilitate data integration with other tools, tool vendors may want to
+ store their resources as XML, or provide XML translators on proprietary data
+ formats. <a href="http://www.omg.org/technology/xml/index.htm">XMI</a> can
+ also be used as a standard data interchange format to provide even better
+ data integration. If a tool's data is available as XML or XMI, it is fairly
+ simple for other tools to use XSLT to transform the resource as needed by
+ the requesting tool.</font></p>
+ <p><font color="#000000">The Eclipse Platform can also be enabled to support WebDAV as a common, open, standard access protocol for accessing resources managed by WebDAV servers. This provides even more openness and flexibility for data access. Tools that want to focus on data integration with Eclipse, while leveraging open standards that enable integration with other environments can use WebDAV, XMI, and XSLT as their standard access, interchange, and transformation protocols. This provides a great deal of flexibility for handling multiple WebDAV enabled repositories and resource stored data formats. All based on open standards.</font></p>
+</blockquote>
+ <h4><a name=API></a>API - Integration through platform API's</h4>
+ <blockquote>
+ <p><font color="#000000"
+ >Data integration provides significantly more value than invocation
+ integration, but each tool that consumes the data must be responsible for
+ decoding its format, understanding it, and maintaining its integrity. Since
+ the data is public, other tools can access and potentially update the data.
+ This can compromise data integrity due to loss of encapsulation exposing implementation
+ details. It may also introduce undesirable data coupling limiting tool vendors'
+ ability to update their respective data models and associated tools. Using
+ XML/XMI as the interchange format can minimize the data integrity and coupling
+ issues, but not eliminate them. Data integration provides state reuse, but
+ not behavioral reuse. Each tool that consumes another tool's data must re-create
+ any behavior of that tool that is required as part of the integration. This
+ can result in less code reuse, and potential errors.</font></p>
+ <p><font color="#000000"
+ >API integration allows client applications to access data through
+ tool-specific client APIs. These APIs provide a high-level means of capturing
+ reusable semantics and simplify client application development by providing
+ data encapsulation and behavioral reuse. Tools that want to provide integration
+ at the API level simply provide Java client interfaces for accessing their
+ tool's model. Tools written in other languages must provided implementations
+ of the Java interfaces through JNI. By standardizing on Java, Eclipse inherits
+ a rich, object-oriented component model that is easy to use, distributed,
+ portable, and easy to develop. Separation of the specification of the interfaces
+ from their implementation and stored data formats allows tool vendors to update
+ their tool's implementation while minimizing the effect on current clients.</font></p>
+ <p><font color="#000000">To make the tool's Java API available to other Eclipse
+ tools, the tool vendor simply needs to describe the API in a plug-in manifest
+ file. Minimally this would require specifying the plug-in name, vendor, version,
+ runtime component (usually a .jar or .zip file containing Java classes), and
+ any required plug-ins. The Eclipse Platform plug-in class loader takes care
+ of loading the classes from the plug-in's runtime when they are needed. The
+ integrated tools are now running in the same JVM and can easily and securely
+ access each other's data. To facilitate tool model access through API integration,
+ tool developers may want to separate their tool's model and UI into separate
+ plug-ins so the model can be reused in other contexts, and by other tools.</font></p>
+</blockquote>
+ <h4><a name=UI></a>UI - User interface integration</h4>
+
+<blockquote>
+ <p><font color="#000000"
+ >UI integration allows a tool to participate with other tools as
+ if they were designed as a single application. Tool integration is done by
+ specifying at run-time the tools with which an application wants to integrate.
+ It is not necessary to compile, package, and release all the tool components
+ as a single monolithic unit. Eclipse allows &quot;just-in-time&quot; tool
+ components to be plugged into the platform when they are available and needed
+ instead of waiting six months to a year for the next release of some monster
+ IDE. An Eclipse editor's menu items, toolbar items and preferences are integrated
+ with the Workbench and share its content area as if they were built together.
+ Users move seamlessly from one tool to another.</font></p>
+ <p><font color="#000000">UI integration is accomplished by building the user
+ interface for the tool using the Eclipse UI frameworks, and integrating with
+ the Workbench through its extension points. Most application development tools
+ (in fact, most tools in general) operate on hierarchically structured data.
+ The Eclipse platform exploits this commonality by providing a number of reusable
+ viewers that can be easily customized through content providers to provide
+ a user interface for a tool's object model. There are many other facilities
+ in the Eclipse platform that support tool UI development including SWT, the
+ Source Editing Framework, contribution frameworks, wizard frameworks, etc.
+ The Workbench provides extension points for adding new views, editors, wizards,
+ preference pages, builders, project natures, perspectives, splash screens,
+ etc. Tools can also extend other tool's menus as well as add extensions to
+ their extension points. </font></p>
+ <p><font color="#000000"
+ >The tools can also be integrated by registering interest in events
+ generated by other tools. For example, each tool can participate in selection
+ management by providing a selection provider, and listening for selection
+ events from other editors and views. When the active workbench part (the one
+ with the focus) sets its selection, all other selection listeners are notified
+ by the Workbench, and can negotiate with the selected object to see if it
+ implements an interesting interface. If so, the receiving tool can adjust
+ its UI accordingly. The Eclipse Platform also provides a number of views that
+ can easily be reused by other tools including the properties view, outline
+ view, and task view. Each of these views expects its contributor to implement
+ certain interfaces. By implementing these interfaces, or delegating to an
+ adapter, your tool can easily contribute to these views eliminating the need
+ for you to create them yourself, providing better integration with Eclipse,
+ minimizing the number of opened windows, and providing your users with a more
+ consistent look-and-feel.</font></p>
+ <p><font color="#000000"
+ >Microsoft&reg; OLE document editors can be immediately integrated with
+ the Eclipse workbench, but only the UI is integrated. The tool will not be
+ able to contribute to the properties or outline views without additional work.
+ This shows that it is also possible to do UI integration without doing any
+ other integration. Other tools, including tools based on Microsoft's COM can
+ be integrated at the UI level by providing Java wrappers around the tool.</font></p>
+</blockquote>
+<h3>Conclusion</h3>
+<p>Application development, and in particular Web application development, isn't
+ getting any easier. Clients are demanding high-quality applications in Web time
+ to support critical business processes. They're betting their business on our
+ software. But these aren't the only demands we face. Modern Web applications
+ consist of many loosely coupled technologies requiring diverse, often distributed
+ teams, to create highly linked resources that are seldom collectively managed.
+ Addressing this &quot;software paradox&quot; and managing application development
+ complexity requires truly best-of-breed tools that can be selected and integrated
+ to provide a roles appropriate, end-to-end development environment tailored
+ to individual development processes. No longer can we wait for six to twelve
+ months for the next release of our development tools to get that bug fixed or
+ add the features we need to get our work done. We want what we need when we
+ need it!</p>
+<p>But integrated tools require a platform of services, frameworks, and standards
+ that allow vendors to focus on their value-add while reusing common infrastructure.
+ The platform must include a workbench that provides a common view of the whole
+ application across all resource types and the entire team. And the platform
+ must be accessible to tool vendors under an acceptable license. Eclipse not
+ only provides such a platform, but it's architecture also provides flexibility
+ in how tool venders integrate their tools and at what level. This allows vendors
+ to match their integration investment with their product needs and market window.</p>
+<p>Some tools don't need to be integrated at all. That's great when it works,
+ not so great when it doesn't. For simple integration, use <a href="#Invocation">invocation
+ integration</a> to provide users navigation, access, editing, and management
+ of file-based resources. Use <a href="#Data">data integration</a> to share data
+ between tools that are otherwise unconnected. When data integration isn't enough,
+ use <a href="#API">API integration</a> to provide secure access to encapsulated
+ data. Finally, for the whole Enchilada, use <a href="#UI">UI integration</a>
+ to make tool components fit seamlessly together as if they were built by a single
+ hand. Pick the integration you need today, but use Eclipse to do it in such
+ a way that you're prepared for integration your customers want tomorrow.</p>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/Article-Levels-Of-Integration/images/idea.jpg b/Article-Levels-Of-Integration/images/idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Levels-Of-Integration/images/idea.jpg
Binary files differ
diff --git a/Article-Mark My Words/Mark My Words.html b/Article-Mark My Words/Mark My Words.html
new file mode 100644
index 0000000..593d85f
--- /dev/null
+++ b/Article-Mark My Words/Mark My Words.html
@@ -0,0 +1,375 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+
+<html>
+
+<head>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+
+ <title>Mark My Words</title>
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+
+<body>
+
+ <div align="right">
+ &nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright &copy; 2001 International Business Machines Corp.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse Corner Article</font></font></b></td>
+ </tr>
+ </table>
+ </div>
+ <div align="left">
+ <h1><img src="images/idea.jpg" height=86 width=120 align=CENTER></h1>
+ <center>
+ <h1>Mark My Words</h1>
+ </center>
+ </div>
+
+<center>
+<h3>Using markers to tell users about problems and tasks</h3>
+</center>
+
+<blockquote>
+<b>Summary</b>
+
+<br>Eclipse workbench has a central mechanism for managing resource annotations. They are
+called <b>markers</b>. In this article, you will learn how to use markers to mark-up
+resources as well as how to define your own marker types and enhance the Tasks view to
+handle them in a special way.
+<p><b>By Dejan Glozic, IBM and Jeff McAffer, OTI</b>
+<br>
+<font size="-1">April 1, 2001</font> </p>
+</blockquote>
+
+
+
+<hr WIDTH="100%">
+
+<p>Eclipse-based applications may be quite complex, consisting of
+many plug-ins. Each plug-in may have a need to tag resources to communicate
+
+problems and other information to the user. In order to assist plug-in writers
+and ensure consistent user experience, the Eclipse platform has a central mechanism,
+called <b>markers</b> which manages this information.
+
+<p>A marker is like a yellow sticky note stuck to a
+resource.&nbsp; On the marker you can record information about a problem (e.g.,
+location, severity, ...), a task to be done or simply remember the location of
+the marker as a bookmark.&nbsp; Users can quickly jump to the marked
+location.
+
+There are several pre-defined marker <b>types</b> supplied by the platform:
+<br>&nbsp;
+<center><table BORDER=0 CELLSPACING=5 CELLPADDING=0 >
+<tr>
+<td><img SRC="images/error_tsk.gif" height=16 width=16></td>
+<td><p><b>Problems</b> - for representing invalid states (errors,
+warnings, information)</p></td>
+</tr>
+<tr>
+<td><img SRC="images/task_tsk.gif" BORDER=0 height=16 width=16></td>
+<td><p><b>Tasks</b> - for capturing user created reminders (todo's)</p></td>
+</tr>
+<tr>
+<td><img SRC="images/bkmrk_tsk.gif" height=16 width=16></td>
+<td><p><b>Bookmarks</b> - for marking a location that can be quickly jumped
+to later</p></td>
+</tr>
+</table></center><br>
+
+<h3>Marker attributes, declaration and inheritance</h3>
+
+<p>The set of marker types and attributes managed by the platform is extensible.
+As a matter of fact, the <tt>IMarker</tt> interface has very few methods which are
+type- or attribute-specific. Given a marker, you can ask for its associated resource,
+the marker's id (unique relative to that resource) and
+its type. You can also access additional information encoded as generic <b>attributes</b>.&nbsp;</p>
+
+<p>
+Attributes are maintained as name/value pairs where the names are strings and a
+value can be any one of the supported value types (Boolean, Integer, String). The limitation
+on value types allows the platform to persistent the markers quickly and simply (its hard to persist generic Objects).</p>
+
+<p>You might ask - &quot;if everything is an attribute, how do I do simple things like
+manipulating marker message or priority?&quot; The answer lies in naming
+conventions. The IMarker interface defines a set of constants containing
+standard attribute names and values which
+are used when getting and setting attributes.&nbsp; For
+example:</p>
+
+<blockquote>
+ <pre><font color="#0000FF">public void</font> manipulateMarker(IMarker marker) {
+ <font color="#FF0000">// test to see if the marker really exists. Perhaps its stale?</font>
+ <font color="#0000FF">if</font> (!marker.exists())
+ <font color="#0000FF">return</font>;
+ <font color="#0000FF">try</font> {
+ marker.setAttribute(IMarker.MESSAGE, <font color="#008000">&quot;A sample marker message&quot;</font>);
+ marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
+ } <font color="#0000FF">catch</font> (CoreException e) {
+ <font color="#FF0000">// You need to handle the cases where attribute value is rejected</font>
+ }
+}</pre>
+
+</blockquote>
+<p>Since there is no way the platform could anticipate all possible uses of
+markers, the set of attributes is not fixed - users can declare new marker types
+and new attributes.&nbsp; Plug-in developers create their own types by configuring extensions in their
+plug-in manifest. While problems, tasks and bookmarks are well-known marker types
+which appear embedded in the platform, they are in fact declared by the platform
+using exactly the same mechanism available to plug-in developers!</p>
+
+<p>New marker types are derived from existing ones using multiple
+inheritance. New marker types inherit all of the attributes
+from their supertypes and add any new attributes defined as part of the
+declaration. They also transitively inherit the supertypes of their supertypes.&nbsp;
+Consider the following markup extracted from the <tt>com.example.markers.r.us</tt>
+plug-in:</p>
+
+<blockquote>
+ <pre>&lt;<font color="#0000FF">extension</font> <font color="#0000FF">id</font>=&quot;coolmarker&quot; <font color="#0000FF">point</font>=&quot;org.eclipse.core.resources.markers&quot;/&gt;
+&lt;<font color="#0000FF">extension</font> <font color="#0000FF">id</font>=&quot;coolproblem&quot; <font color="#0000FF">point</font>=&quot;org.eclipse.core.resources.markers&quot;&gt;
+ &lt;<font color="#0000FF">super</font> <font color="#0000FF">type</font>=&quot;org.eclipse.core.resources.problemmarker&quot;/&gt;
+ &lt;<font color="#0000FF">super</font> <font color="#0000FF">type</font>=&quot;com.example.markers.r.us.coolmarker&quot;/&gt;
+ &lt;<font color="#0000FF">attribute</font> <font color="#0000FF">name</font>=&quot;coolFactor&quot;/&gt;
+ &lt;<font color="#0000FF">persistent</font> <font color="#0000FF">value</font>=&quot;true&quot;/&gt;
+&lt;/<font color="#0000FF">extension</font>&gt;</pre>
+</blockquote>
+<p>Note that the marker type <tt>org.eclipse.core.resources.problemmarker</tt>
+ is actually one of the pre-defined types (aka <tt>IMarker.PROBLEM</tt>).&nbsp;
+ The only part of a marker supertype that is not inherited is its persistence
+ flag.&nbsp; While the standard marker types (task, problem and bookmark) are
+ declared as persistent, by default, new marker types are <b>not</b> persistent.&nbsp;
+ The platform will not save their state between sessions.&nbsp; If developers
+ declare their marker types as persistent (as shown above), the state of markers
+ of that type will be saved and restored by the platform.&nbsp;</p>
+
+<p>After placing the above declaration into your plug-in manifest file,
+you can create instances of <tt>coolproblem</tt> marker type and freely set or
+get <tt>coolFactor</tt> attribute (see example below). The new attributes allow you to associate data with markers that you plan to use elsewhere
+(in your views, editors etc.).&nbsp; Markers of a particular type do not have to
+have values for all of the declared attributes.&nbsp; The attribute declarations
+are more for solving naming convention problems (so everyone uses
+&quot;message&quot; to talk about a marker's description) than they are for
+constraining content.&nbsp;&nbsp;&nbsp;</p>
+
+<blockquote>
+ <pre><font color="#0000FF">public </font>IMarker<font color="#0000FF"> </font>createCoolMarker(IResource resource) {
+ <font color="#0000FF">try</font> {
+ IMarker marker = resource.createMarker(<font color="#008000">&quot;com.example.markers.r.us.coolproblem&quot;</font>);
+ marker.setAttribute(&quot;coolFactor&quot;, <font color="#008000">&quot;ULTRA&quot;</font>);
+ <font color="#0000FF">return</font> marker;
+ } <font color="#0000FF">catch</font> (CoreException e) {
+ <font color="#FF0000">// You need to handle the cases where attribute value is rejected</font>
+ }
+}</pre>
+
+</blockquote>
+<p>The real power of defining your own marker types comes from the query
+facilities built-into the platform.&nbsp; The query in the code below finds all <tt>coolmarkers</tt>
+associated with the given target resource and all its descendents.&nbsp; Note
+that this will also find all <tt>coolproblems</tt>.</p>
+
+<blockquote>
+ <pre><font color="#0000FF">public</font> IMarker[] findCoolMarkers(IResource target) {
+ String type = <font color="#008000">&quot;com.example.markers.r.us.coolmarker&quot;</font>;
+ IMarker[] markers = target.findMarkers(type, <font color="#0000FF">true</font>, IResource.DEPTH_INFINITE);
+}</pre>
+
+</blockquote>
+
+<h3>
+
+<font size=+0>Marker representation in the platform</font></h3>
+
+<p>You don't have to look hard to spot markers in the platform.
+Just open the Tasks view, create a sample Java&trade; project, open a Java file
+for editing and type something obviously wrong. You will soon see error
+markers in the Tasks view, one per syntax error. And since you have Java
+editor opened, you can also select a line of code and place a bookmark
+there. If you open Bookmarks view, you will see the newly created bookmark.
+Similarly, you can set breakpoint markers for the purpose of debugging your
+code.&nbsp; All of these markers appear together in the vertical left
+sidebar (Figure 1).&nbsp;&nbsp;</p>
+
+<p>The standard platform can display and manage any of the pre-defined marker
+types.&nbsp; A standard set of images are used to denote a marker's type,
+priority, severity etc. as appropriate.&nbsp; The
+presentation is maintained for extended types as well - supertypes will be used
+in that case. For example, if your marker extends the task marker type, it will look like a
+task in the workbench but will still be able to carry additional attributes.&nbsp;
+If you create a new breed of marker that does not
+inherit from the pre-defined types (e.g., tasks, problems or bookmarks), or want
+to change the way markers are presented, you can define new views which give the
+desired look and feel.
+
+</p>
+
+
+<div align="center">
+ <center>
+
+
+<table BORDER=0 CELLSPACING=0 CELLPADDING=5 >
+
+<tr>
+<td><img SRC="images/markers.jpg" width="662" height="507"></td>
+</tr>
+
+<tr>
+<td>
+ <p align="center"><b><font size=-1>Figure 1: Places where markers show up in
+ the platform.&nbsp;</font></b></p>
+</td>
+</tr>
+
+</table>
+
+
+ </center>
+</div>
+<br>
+
+<h3>Basic marker operations</h3>
+
+Markers are owned and managed by the platform. It is your job to
+create them, remove them or change their attributes. The platform takes care of
+resource associations, change notification and persistence (you need to define your marker type as persistent for this to happen). It is also important to note that
+they are similar to resources in that they are only handles and it is possible to
+have a 'stale' handle (i.e., a handle to a marker that does not exist). <tt>IMarker.exists()</tt> should be called to test for this situation.
+<p>
+
+Marker changes will be reported in resource deltas. Resource change
+listeners are able to detect this by checking the change flags to see if the
+delta represents changes in the resource, in its markers, or both.
+
+<p>It is interesting to note that markers cannot be directly
+
+created (using the constructor). They are created using a factory method (<tt>IResource.createMarker()</tt>)
+on the resource they will be associated with. If you need to create a marker that has
+a global scope (not associated with any specific resource), you need do it on the
+<b>
+workspace root</b> (see <tt>IWorkspace.getRoot()</tt>).
+
+<blockquote>
+ <pre><font color="#0000FF">public</font> <font color="#0000FF">void</font> createMarkerForResource(IResource resource) <font color="#0000FF">throws</font> CoreException {
+ IMarker marker = resource.createMarker(<font color="#008000">&quot;com.example.markers.r.us.coolproblem&quot;</font>);
+
+ <font color="#FF0000">//Once we have a marker object, we can set its attributes</font>
+ marker.setAttribute(<font color="#008000">&quot;coolFactor&quot;</font>, <font color="#008000">&quot;ULTRA&quot;</font>);
+ marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+ marker.setAttribute(IMarker.MESSAGE, <font color="#008000">&quot;Variable 'i' has not been defined.&quot;</font>);
+}</pre>
+</blockquote>
+
+At a later point in time, you may want to remove the marker you
+have created. If you still have a handle to it, you will do something like
+this:
+
+<blockquote>
+ <pre><font color="#0000FF">try</font> {
+&nbsp;&nbsp; marker.delete();
+} <font color="#0000FF">catch</font> (CoreException e) {
+ <font color="#FF0000">// Something went wrong</font>
+}</pre>
+</blockquote>
+
+Any time during the session, you can query the resources for
+markers. If resource is a folder or a workspace root, you can also ask for
+markers associated with resource children.&nbsp; For example, querying the workspace root
+with infinite depth considers all of the markers in the workspace.
+
+<blockquote>
+ <pre>IMarker[] problems = <font color="#0000FF">null</font>;
+<font color="#0000FF">int</font> depth = IResource.DEPTH_INFINITE;
+<font color="#0000FF">try</font> {
+ problems = resource.findMarkers(IMarker.PROBLEM, <font color="#0000FF">true</font>, depth);
+} <font color="#0000FF">catch</font> (CoreException e) {
+ <font color="#FF0000">// something went wrong</font>
+}</pre>
+</blockquote>
+
+The result of the code snippet above depends on how you tweak the arguments in
+the <tt>findMarkers</tt>
+
+call. For example, if you pass <tt>null</tt> for the marker type, you will get all the
+markers associated with the resource. The depth argument controls the depth of
+the search. The depth can be limited to zero (just the given resource), one (the
+resource and all its direct children) or infinite (the resource and all direct
+and indirect children). Finally, you can specify if you want to include only markers of the
+specified type or markers of all subtypes as well.
+
+<p>Batches of markers can be deleted using the same
+specification technique and <tt>deleteMarkers()</tt> (identical signature). This method is useful when removing markers
+in numbers or when individual marker references or IDs are not available.</p>
+
+<h3>Marker use</h3>
+
+<p>
+The most general statement of marker usage is to say that markers allow plug-ins
+and/or users to highlight points of interest. They are very much like bookmarks
+in typical web browsers except that they may be automatically generated by
+plug-ins.</p>
+<p>
+The most obvious way to use markers in a plug-in is to communicate
+
+build problems. Java Development Tooling plug-in, for example, uses markers to inform users
+
+about Java compilation errors and warnings. These markers show up in the
+
+Tasks view and users can use them to jump directly to the Java editor at
+
+the error location.</p>
+
+<p>Task markers are ideal as user reminders when generated by
+plug-ins that create entire projects using elaborate wizards and templates.
+While the wizard instantiates the template it adds task markers to highlight areas where users needs to
+
+fill in content or make choices.&nbsp; Users can then jump in and quickly fill in the blanks.
+
+<p>Whatever the usage, it is important to remember that the
+platform manages markers, but it is the plug-ins that control their
+creation, removal and attribute values.&nbsp; The platform will throw away
+markers attached to resources which are deleted but you are responsible for removing
+stale markers when they no longer apply to a resource which lives on.&nbsp; Stale markers can be very confusing to users and will make
+them search
+
+for problems when there aren't any.
+
+<h3>Space for creativity</h3>
+
+<p>Markers are intended to be small, lightweight objects.&nbsp; There
+is the potential of hundreds, even thousands of markers in a single Eclipse project. Keep this in mind when defining new marker types with lots
+of new
+attributes. When used in moderation, additional attributes can be used
+by other platform artifacts for a powerful effect. For example, Eclipse UI plug-in uses a Boolean attribute to mark the task completed.</p>
+
+<p>It is possible to combine new attributes and the ability to
+
+extend Tasks view pop-up menu and local tool bar and provide additional behavior for your markers.
+
+For example, spec compliance warning marker can carry violated spec index
+
+as an attribute. An added pop-up menu action can use this information to
+
+show a dialog with the entire text of the violated spec with suggestions
+
+for fixing the problem. Note how we increased the footprint of the marker only
+slightly (one Integer object) by keeping the actual spec text in an indexed
+table elsewhere.</p>
+
+<h3>Conclusion</h3>
+
+<p>This article has shown that the Eclipse platform has a central mechanism for managing annotations on resources. Techniques
+for performing basic operations on markers, extending the
+basic marker types and creatively tapping into marker attributes for interesting
+effect were also shown.</p>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+
+</body>
+
+</html>
diff --git a/Article-Mark My Words/images/bkmrk_tsk.gif b/Article-Mark My Words/images/bkmrk_tsk.gif
new file mode 100644
index 0000000..081dbe8
--- /dev/null
+++ b/Article-Mark My Words/images/bkmrk_tsk.gif
Binary files differ
diff --git a/Article-Mark My Words/images/error_tsk.gif b/Article-Mark My Words/images/error_tsk.gif
new file mode 100644
index 0000000..7cf763c
--- /dev/null
+++ b/Article-Mark My Words/images/error_tsk.gif
Binary files differ
diff --git a/Article-Mark My Words/images/idea.jpg b/Article-Mark My Words/images/idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Mark My Words/images/idea.jpg
Binary files differ
diff --git a/Article-Mark My Words/images/info_tsk.gif b/Article-Mark My Words/images/info_tsk.gif
new file mode 100644
index 0000000..919dac7
--- /dev/null
+++ b/Article-Mark My Words/images/info_tsk.gif
Binary files differ
diff --git a/Article-Mark My Words/images/markers.jpg b/Article-Mark My Words/images/markers.jpg
new file mode 100644
index 0000000..134b4f0
--- /dev/null
+++ b/Article-Mark My Words/images/markers.jpg
Binary files differ
diff --git a/Article-Mark My Words/images/task_tsk.gif b/Article-Mark My Words/images/task_tsk.gif
new file mode 100644
index 0000000..29a4d1f
--- /dev/null
+++ b/Article-Mark My Words/images/task_tsk.gif
Binary files differ
diff --git a/Article-Mark My Words/images/warn_tsk.gif b/Article-Mark My Words/images/warn_tsk.gif
new file mode 100644
index 0000000..a0c0600
--- /dev/null
+++ b/Article-Mark My Words/images/warn_tsk.gif
Binary files differ
diff --git a/Article-Monitor/images/Idea.jpg b/Article-Monitor/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Monitor/images/Idea.jpg
Binary files differ
diff --git a/Article-Monitor/images/classDiagramDetail.gif b/Article-Monitor/images/classDiagramDetail.gif
new file mode 100644
index 0000000..84cf083
--- /dev/null
+++ b/Article-Monitor/images/classDiagramDetail.gif
Binary files differ
diff --git a/Article-Monitor/images/classDiagramMain.gif b/Article-Monitor/images/classDiagramMain.gif
new file mode 100644
index 0000000..0dc4cbc
--- /dev/null
+++ b/Article-Monitor/images/classDiagramMain.gif
Binary files differ
diff --git a/Article-Monitor/images/logView.jpg b/Article-Monitor/images/logView.jpg
new file mode 100644
index 0000000..98ddf73
--- /dev/null
+++ b/Article-Monitor/images/logView.jpg
Binary files differ
diff --git a/Article-Monitor/images/monitoring.gif b/Article-Monitor/images/monitoring.gif
new file mode 100644
index 0000000..dd95691
--- /dev/null
+++ b/Article-Monitor/images/monitoring.gif
Binary files differ
diff --git a/Article-Monitor/images/newServerWizard.gif b/Article-Monitor/images/newServerWizard.gif
new file mode 100644
index 0000000..fe5694c
--- /dev/null
+++ b/Article-Monitor/images/newServerWizard.gif
Binary files differ
diff --git a/Article-Monitor/images/preferences.gif b/Article-Monitor/images/preferences.gif
new file mode 100644
index 0000000..5b4df46
--- /dev/null
+++ b/Article-Monitor/images/preferences.gif
Binary files differ
diff --git a/Article-Monitor/images/sample1.gif b/Article-Monitor/images/sample1.gif
new file mode 100644
index 0000000..4379a06
--- /dev/null
+++ b/Article-Monitor/images/sample1.gif
Binary files differ
diff --git a/Article-Monitor/images/sample1.jpg b/Article-Monitor/images/sample1.jpg
new file mode 100644
index 0000000..8bd855d
--- /dev/null
+++ b/Article-Monitor/images/sample1.jpg
Binary files differ
diff --git a/Article-Monitor/images/serverOperations.jpg b/Article-Monitor/images/serverOperations.jpg
new file mode 100644
index 0000000..8b6a34e
--- /dev/null
+++ b/Article-Monitor/images/serverOperations.jpg
Binary files differ
diff --git a/Article-Monitor/images/servers.gif b/Article-Monitor/images/servers.gif
new file mode 100644
index 0000000..4ccf43a
--- /dev/null
+++ b/Article-Monitor/images/servers.gif
Binary files differ
diff --git a/Article-Monitor/images/tag_1.gif b/Article-Monitor/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Monitor/images/tag_1.gif
Binary files differ
diff --git a/Article-Monitor/images/tag_2.gif b/Article-Monitor/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Monitor/images/tag_2.gif
Binary files differ
diff --git a/Article-Monitor/images/tag_3.gif b/Article-Monitor/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Monitor/images/tag_3.gif
Binary files differ
diff --git a/Article-Monitor/images/tag_4.gif b/Article-Monitor/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Monitor/images/tag_4.gif
Binary files differ
diff --git a/Article-Monitor/images/tag_5.gif b/Article-Monitor/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Monitor/images/tag_5.gif
Binary files differ
diff --git a/Article-Monitor/images/tag_6.gif b/Article-Monitor/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Monitor/images/tag_6.gif
Binary files differ
diff --git a/Article-Monitor/images/tag_7.gif b/Article-Monitor/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Monitor/images/tag_7.gif
Binary files differ
diff --git a/Article-Monitor/images/tip.gif b/Article-Monitor/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Monitor/images/tip.gif
Binary files differ
diff --git a/Article-Monitor/images/tryit.gif b/Article-Monitor/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Monitor/images/tryit.gif
Binary files differ
diff --git a/Article-Monitor/monitorArticle.html b/Article-Monitor/monitorArticle.html
new file mode 100644
index 0000000..eb28e67
--- /dev/null
+++ b/Article-Monitor/monitorArticle.html
@@ -0,0 +1,430 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!-- saved from url=(0067)http://www.eclipse.org/articles/treeviewer-cg/TreeViewerArticle.htm -->
+<HTML><HEAD><TITLE>Building administrative applications in Eclipse</TITLE>
+<link rel="stylesheet" href="../default_style.css">
+<META http-equiv=Content-Type content="text/html; charset=windows-1252">
+<META content="MSHTML 5.50.4915.500" name=GENERATOR></HEAD>
+<BODY vLink=#800080 link=#0000ff>
+<DIV align=right>&nbsp; <FONT face="Times New Roman, Times, serif"
+size=2>Copyright © 2004 IBM Corporation.</FONT>
+<TABLE cellSpacing=0 cellPadding=2 width="100%" border=0>
+ <TBODY>
+ <TR>
+ <TD vAlign=top align=left bgColor=#0080c0 colSpan=2><B><FONT
+ face=Arial,Helvetica><FONT color=#ffffff>&nbsp;Eclipse Corner
+ Article</FONT></FONT></B></TD></TR></TBODY></TABLE></DIV>
+<DIV align=left>
+<H1><IMG height=86 src="images/Idea.jpg" width=120></H1></DIV>
+<P>&nbsp;</P>
+<H1 align=center>Building administrative applications in Eclipse</H1>
+<BLOCKQUOTE><B>Summary</B> <BR>Eclipse is most commonly used as a platform for tools that allow the user to construct or assemble an end product out of development resources. It is less usual to use Eclipse as an administrative tool for monitoring existing runtime systems or applications. This article will describe some of the issues that arise in this case and illustrate possible solutions.
+It will show you can build an Eclipse perspective dedicated to the monitoring task. Running processes are shown in a dedicated view which always reflects their current state. You can start/stop the process, manage connections, invoke operations that the server exposes, examine server output and view events generated by the running applications.
+ <P><B>By Doina Klinger and Chris Markes, IBM UK</B> (dklinger@uk.ibm.com, cmarkes@uk.ibm.com)<BR>
+ November 12, 2004</P>
+</BLOCKQUOTE>
+<HR width="100%">
+
+<H2>Introduction</H2>
+<P>Eclipse is mainly a development environment: you create applications and run them. Take the Java<SUP>TM</SUP> Development Toolkit component:
+applications are stored in Java packages and classes which correspond to directories and files with .java extension respectively. The applications are
+built using the Java compiler and then executed. Projects are holders for the various files that are stored in the
+workspace. Depending of the nature of the file, a different type of
+builder is applied to them.<p>
+Administration applications are fundamentally different. In this case,
+the user interacts with existing applications that typically run outside of the Eclipse
+JVM, possibly on a remote machine. We will refer to these
+external applications as <B>servers</B>, since they typically perform some function on
+behalf of some client. The servers already exist, though they can be made to run from Eclipse or even developed from the same workspace.
+Often servers are administered by a browser-based application. In this article, we will show you how it can be done using Eclipse.</P>
+<H2>Server administration sample</H2>
+
+<P>We will show how you can use Eclipse to manage external servers. Our server is a simple
+ phone directory that holds data about people and their phone numbers. The
+<A href="#serverSection">server</A> exposes operations to add new entries, query the list of entries and find out how many you have.<P>To see the sample in action you'll need to <A
+ href="monitorPlugin.jar">download</A> it and install it as a plug-in on Eclipse 3.0 and then start the workbench and open the Monitor perspective.
+In figure 1 you can see the sample when a few servers have been defined and data entries have been added.</P>
+<P align="center"><img border="0"
+ src="images/sample1.jpg"><BR>
+ Figure 1. Monitor sample in action </P>
+
+<P>
+In the servers view, the icons indicate the state of the servers: a red square shows the server being unavailable, a green triangle shows an active server. The state is kept up to date by polling every ten seconds. To create a new server entry, start the New Connection wizard from the pulldown menu of the local toolbar of the Servers view (highlighted in figure 1):</P>
+<DIV align="center"><IMG border="0"
+ src="images/newServerWizard.gif"><BR>Figure 2. Define a new server
+</DIV>
+<P>
+Specify a name, a host, a port number and whether you can start and stop the server from the workbench. Start the server by selecting the Start option from the context menu (Figure 3). Add a few new entries. You can see the server output in the console view. When you select a server, the number of entries is shown in the status line and the content in the detail view in the right hand side.</P>
+<P align="center"><IMG border="0"
+ src="images/serverOperations.jpg"><BR>Figure 3. Invoking operations on the server
+</P>
+
+<P>
+The sample shows how you can monitor the state of a running system and report back in the Monitor Log view events related to the state of the server. Add entries until the maximum number of entries is reached and you can see the event reported in the log . You can modify the server preferences for the refresh interval and maximum number of entries.</P>
+<P align="center"> <IMG border="0" src="images/preferences.gif"><BR>Figure 4. Server preferences
+</P>
+
+
+<H2>Modelling the server world</H2>
+<P>
+From the point of view of an administrative application, the world is composed of the target systems being administered together with the environment of the application itself. The figure below shows the target servers running either on a different host or on the same machine with the Eclipse workbench, though in a different JVM.</P>
+<P align="center"><IMG border="0" src="images/servers.gif">
+<BR>
+Figure 5. Workbench and target servers</P>
+
+<P>
+The application requires an internal representation or model of the target systems, which is used to hold information about their state and attributes. In our example, we model individual target systems using instances of ServerElement. The ServerElement class encapsulates instance variables (exposed by accessor methods) relating to the target server's location and a snapshot of its most recently observed condition: </P>
+<BLOCKQUOTE><PRE><CODE>public class ServerElement implements IAdaptable, IWorkbenchAdapter
+{
+<IMG height="13" src="images/tag_1.gif" width="24" border="0"> // Target server location
+ String name;
+ String hostname;
+ int port;
+ boolean local;
+
+<IMG height="13" src="images/tag_2.gif" width="24" border="0"> // Target server state
+ boolean alive;
+ boolean full;
+
+
+<IMG height="13" src="images/tag_3.gif" width="24" border="0">PhoneBookClient connection
+<IMG height="13" src="images/tag_4.gif" width="24" border="0">ServerLauncher launcher;
+
+ ...
+}</CODE></PRE></BLOCKQUOTE>
+<P>
+The location information (<CODE><IMG height="13"
+ src="images/tag_1.gif" width="24" border="0"></CODE>) is used when we establish a connection to interact with the target system. These attributes are also exposed as properties of the object using the PhoneBookServerPropertySource class, which allows us to plug into the standard Properties view in the workbench. <P>
+The alive and full attributes (<CODE><IMG height="13"
+ src="images/tag_2.gif" width="24" border="0"></CODE>) are updated as a result of the listening on the target server, and affect the way we display the server entry in the ServersView using started or stopped icons.
+<P>
+
+The ServerElement class encapsulates a PhoneBookClient instance (<CODE><IMG
+ height="13" src="images/tag_3.gif" width="24" border="0"></CODE>), which is the actual object used to communicate with the server and handle the network operations involved in talking to the server (in our case, a simple HTTP server).
+<P>
+An optional ServerLauncher field(<CODE><IMG height="13"
+ src="images/tag_4.gif" width="24" border="0"></CODE>) is used for invoking the server application on the local system. We'll cover the ServerLauncher in more detail in the launching servers
+<A href="#launchServerSection">section</A>
+later in the article.<P>
+Since our sample application allows the administrator to interact with more than one target server, we use the ServersModel class to bring together multiple instances of ServerElement as a list. The interaction of these classes is described in the following diagram:
+</P>
+<P align="center">
+<IMG border="0" src="images/classDiagramMain.gif"><BR>Figure 6. Server model
+</P>
+<P> We next look into how to serialize such a model.
+</P>
+<H2> Representing remote resources in the workspace</H2>
+<H3>Beyond the workspace</H3>
+<P>When we're using the Eclipse workbench to develop applications, the
+resources we work with are generally local. The source files we create
+reside in the workspace -- even if we use a repository to share them
+with other developers -- and the built output of a project likewise
+remains local. <P>
+By contrast, when our task is to monitor and administer
+remote systems, the content we need to display in the views we use
+must be retrieved across the network. (We'll deal with issues of
+'liveness' <A
+ href="#monitoringSection">later</A> on in the
+article.)<P>
+In our example, the ServerElement is the class that represents the remote system and is persisted locally. In our example, we provide a view, PhoneBookServersListView, which is really a Navigator for servers. </P>
+
+<P>At this point, we have to decide where to
+store the connection information representing remote systems. We can store them:
+ <UL>
+ <LI>
+as
+normal workspace resources in a file of certain type. <BR>
+They show up in the Navigator view and can be modified by an editor associated with this file type. </LI>
+
+ <LI>
+ as data specific and private to our plug-in <BR>
+The plug-in metadata
+area is available for this purpose. This area can't be seen
+in the Navigator view, so we need to provide a specialized view to display a representation of this content.
+</LI>
+</UL>
+We've chosen the second option above, though both are valid approaches.
+Incidentally, if you've been using the CVS Repository Exploring
+perspective, you've already been working with an example of the second
+approach. The implications of the two approaches are contrasted below.
+<P>
+<TABLE border="1">
+ <TBODY>
+ <TR>
+ <TD width="477"><B>Using workspace resources</B></TD>
+ <TD width="477"><B>Using private resource information (plug-in
+ metadata)</B></TD>
+ </TR>
+ <TR>
+ <TD width="477">Resources (representations of remote systems) are
+ visible in the Navigator, and are available to other Eclipse tools</TD>
+ <TD width="477">Resources are visible only via dedicated plug-in code
+ (specialized views etc.)</TD>
+ </TR>
+ <TR>
+ <TD width="477">Representations of remote systems created with New
+ wizard (contribution to org.eclipse.ui.NewWizards)</TD>
+ <TD width="477">Representations of remote systems created by a user
+ action provided by plug-in code</TD>
+ </TR>
+ <TR>
+ <TD width="477">'Content' of remote systems is accessed using an
+ Editor</TD>
+ <TD width="477">Content is accessed using specialized views</TD>
+ </TR>
+ <TR>
+ <TD width="477">Multiple editor instances can be used to work with
+ multiple remote systems simultaneously</TD>
+ <TD width="477">View must specifically accommodate working with
+ multiple remote systems if this is desired</TD>
+ </TR>
+ <TR>
+ <TD width="477">Content can appear without customizing any
+ perspective</TD>
+ <TD width="477">Existing perspective must be customized by user (e.g.
+ Window -&gt; Show View) or a specialized perspective provided</TD>
+ </TR>
+ </TBODY>
+</TABLE>
+<H2> Persisting server references</H2>
+<P>The .metadata directory of a workspace is considered to be a "black
+box" where important information about the workspace structure, such as
+a project's references or a resource's properties, are typically stored.
+ The non-workspace
+resources are stored on a per plug-in basis, typically all in one file.
+<P>
+In our example, the "resources" that we want to persist are ServerElement objects, or, more precisely, those attributes needed to establish a session with the remote process and interact with it -- name, host, port and the isLocal attribute. The other attributes of the ServerElement which describe the state of the server at one moment are transient and are not saved.<P>
+In
+/workspace/.metadata/.plugins/MonitorProject/connection.xml we save
+information about connections in an XML format:</P>
+<BLOCKQUOTE><PRE><CODE>&lt;Monitor&gt;
+ &lt;Server Host="134.456.888.99" <SPAN
+ class="m"> IsLocal= "true" </SPAN>
+ <SPAN class="t"></SPAN>Name="MyConnection" Port="600" /&gt;
+ &lt;Server Host="334.553.636.44" <SPAN class="t">IsLocal</SPAN><SPAN
+ class="m">="</SPAN>true<SPAN class="m">"</SPAN><SPAN class="t"> </SPAN>
+ Name="OtherConnection" Port="600" /&gt;
+ &lt;Server Host="223.223.662.55" <SPAN class="t">IsLocal</SPAN><SPAN
+ class="m">="</SPAN>false<SPAN class="m">"</SPAN><SPAN class="t"> </SPAN>
+ Name="DomainConnection" Port="400" /&gt;
+&lt;/Monitor&gt;</CODE></PRE></BLOCKQUOTE>
+<P>The serialization of our server model is achieved in the following steps:</P>
+<UL>
+ <LI>construct the java.io.File object representing the file where the server elements are to be saved <BR>We use the getStateLocation method on our plug-in to return the location
+in the local file system of the plug-in state area for this plug-in (<IMG
+ height="13" src="images/tag_1.gif" width="24" border="0">).<BLOCKQUOTE><PRE><IMG height="13" src="images/tag_1.gif"
+ width="24" border="0"><CODE> File connectionFile = MonitorProjectPlugin.getDefault().getStateLocation().append(<FONT
+ color="#0000ff">&quot;connection.xml&quot;</FONT>).toFile();
+<CODE> if (!connectionFile.exists()) connectionFile.createNewFile();</CODE></CODE></PRE></BLOCKQUOTE>
+
+
+ </LI>
+ <LI>on start-up read the content of the file to build the connection model<BR>
+
+ We use XMLMemento for easy manipulation of the XML file.
+ We create a file reader for the connection file and an XMLMemento object from the
+ reader (<CODE><IMG height="13" src="images/tag_2.gif" width="24"
+ border="0"></CODE>) corresponding to the <CODE>&lt;Monitor&gt;</CODE> tag. From the parent IMemento object, we extract the children entries for each Server. (
+ <CODE><IMG height="13" src="images/tag_3.gif" width="24"
+ border="0"></CODE> ). We can now extract the attributes of the connection and initialize the in-memory model.<BLOCKQUOTE><PRE><CODE> FileReader reader = new FileReader(connectionFile);
+<IMG
+ height="13" src="images/tag_2.gif" width="24" border="0"> memento = XMLMemento.createReadRoot(reader);
+<IMG height="13" src="images/tag_3.gif" width="24" border="0"> IMemento[] children =memento.getChildren(<FONT
+ color="#8000ff">&quot;Server&quot;</FONT>);
+ for (int i = 0; i &lt; children.length; i++) {
+ String name = children[i].getString(<FONT color="#0000ff">&quot;Name&quot;</FONT>);
+ //extract all attributes and build the servers model
+ }</CODE></PRE></BLOCKQUOTE>
+ </LI>
+ <LI>when closing the connection view, serialize the connections from the model to the file.</LI>
+<P> We create an XMLMemento corresponding to our <CODE>&lt;Monitor&gt;</CODE> root (<CODE><IMG
+ height="13" src="images/tag_4.gif" width="24" border="0"></CODE>). We iterate through the model and create a child memento for each server (<CODE><IMG
+ height="13" src="images/tag_5.gif" width="24" border="0"></CODE>) and set its attributes. In the end, we save the XMLMemento data structure to the file
+using a file writer(<CODE><IMG height="13"
+ src="images/tag_6.gif" width="24" border="0"></CODE>).</P>
+<BLOCKQUOTE><PRE><CODE>
+ Iterator iterator = model.getContent().iterator()
+<IMG height="13" src="images/tag_4.gif" width="24" border="0"> XMLMemento memento = XMLMemento.createWriteRoot(<FONT color="#0000ff">&quot;Monitor&quot;</FONT>);
+ while (iterator.hasNext()) {
+ DirectoryConnection conn =((DirectoryViewElement)iterator.next()).getConnection();
+<IMG height="13" src="images/tag_5.gif" width="24" border="0"> IMemento child = memento.createChild(<FONT color="#0000ff">&quot;Server&quot;</FONT>);
+ child.putString(<FONT color="#0000ff">&quot;Name&quot;</FONT>, conn.getName());
+ // the same for all attributes
+
+ }
+<IMG height="13" src="images/tag_6.gif" width="24" border="0"> Writer writer = new FileWriter(connectionFile);
+ memento.save(writer); </CODE></PRE></BLOCKQUOTE>
+
+</UL>
+<H2> <A name="monitoringSection"></A>Monitoring and event notifications </H2>
+<H3>Is the server still there?</H3>
+<P>A key ingredient in monitoring running systems or processes is
+knowing whether or not they're in a normal, healthy state. In the most
+basic situations, it can be enough just to know whether a server is
+running or stopped, but typically there are a number of other potential
+conditions -- which depend upon the type of system being monitored --
+that an administrator is interested in. Rather than having to go and
+pro-actively query the state of the server, it's useful to have a
+continuous indication of its health, much like the dashboard in your
+car. You can tell at a glance if all's well, and only peek under the
+hood if something lights up that tells you there's a problem. (Well,
+that's the theory!)
+ </P>
+ <P>The server view is our dashboard display showing at a quick glance the state of the running applications. How this is put together is captured in the class diagram from Figure 7. The view uses the model for its label and content provider. The server model uses a background thread to continually poll the target servers for which it contains references. When a change occurs in the state represented by the model, it generates a ServerEvent to notify listeners of the change. The ServerListView registers itself as a ServerListener in order to receive these notifications.</P>
+<P>The server view needs to be up-to-date; a dashboard that shows your petrol tank full when you are down to the last drops is of not much use. Hence the view needs to be a server listener to react to the changes. The ServerListener interface defines the following methods:</P>
+<BLOCKQUOTE><PRE>
+void serverStarted(ServerEvent event)
+void serverStopped(ServerEvent event)
+void serverUpdate(ServerEvent event)
+void serverError(ServerEvent event)</PRE></BLOCKQUOTE>
+<P align="center"><IMG border="0" src="images/classDiagramDetail.gif"><BR>
+Figure 7. Class diagram </P>
+<P>The way the connection object works depends upon the nature of
+the server. Our example uses an HTTP server which expects connections to
+be short-lived (i.e. it is connectionless), and that means we need to
+perform a 'normal' interaction with the server in order to determine if
+it's still there. We won't illustrate the HTTP protocol handling here -- that's implemented in the PhoneBookClient class.<P>
+The ServerListModel keeps up-to-date with the state of the target servers it knows about by having a monitor thread class running in the background and examining each server element in turn. The interaction for one ServerElement is shown in the code snippet from below. For the server element, we obtain its PhoneBookClient in order to invoke its method that tells us how many entries the server contains(<CODE><IMG
+ height="13" src="images/tag_1.gif" width="24" border="0"></CODE>). There are two reasons for invoking this method. If we get any answer at all the server is running. We use the return value (<CODE><IMG
+ height="13" src="images/tag_2.gif" width="24" border="0"></CODE>) to determine if the server is full. If we get an IOException (<CODE><IMG
+ height="13" src="images/tag_3.gif" width="24" border="0"></CODE>) , the server is stopped.<P>
+The response from the server is used to generate events for registered listeners (i.e. the servers view), using the notifyStarted and notifyUpdate methods.</P>
+<BLOCKQUOTE><PRE>
+ ServerElement element = ..;
+ try {
+ PhoneBookClient client = element.getPhoneBookClient();
+<IMG height="13" src="images/tag_1.gif" width="24" border="0"> int count = client.getEntryCount ();
+ if (element.isAlive () == false) {
+ element.setAlive (true);
+ notifyStarted (new ServerEvent (&quot;Server started&quot;, IStatus.INFO, element.getName()));
+ }
+<IMG height="13" src="images/tag_2.gif" width="24" border="0"> if (element.isFull () == false &amp;&amp; count &gt;= maxEntries) {
+ element.setFull (true);
+ notifyUpdate (new ServerEvent (&quot;Max number of entries reached&quot;, IStatus.WARNING, element.getName ()));
+ } else element.setFull(false);
+ } catch (IOException e) {
+<IMG height="13" src="images/tag_3.gif" width="24" border="0"> if (element.isAlive () == true) {
+ element.setAlive (false);
+ notifyStarted (new ServerEvent (&quot;Server stopped (&quot; + e.toString () + ')', IStatus.INFO, element.getName ()));
+ }</PRE></BLOCKQUOTE>
+<P>For servers that are connection-oriented (expect
+clients to remain connected indefinitely), it may be sufficient simply
+to assume that as long as the connection hasn't been broken, the server
+is still available. For cases where we want to use more detailed
+criteria to determine the health of a server, our connection object will
+need to interact with the remote system and perform the necessary
+operations to determine that state.
+<H3>How is the server doing?</H3>
+ <P>In addition to checking whether a server is still running or not, the administrator might want to get more details about the well being of a running application. One way of doing this is by examining the Monitor Log view.<BR>This view records notifications from the server
+ sent in the shape of a ServerEvent. The view is consistent with the ErrorLog of the PDE plug-in and it wraps a TableViewer. The entries
+ are of our own type ServerLogEntry, which wraps various details about the event, such as the severity,
+ detailed message, code, server name. <BR>In our example, the type of events that are recorded are server started and stopped, and an alarm event. For illustration purposes, we have defined a (configurable) limit of ten entries
+as maximum to be held by a server and we can see the event being reported when this number is reached. </P>
+<P align="center"><img border="0" src="images/logView.jpg"><BR>
+ Figure 8. Monitor log view </P>
+<P>
+The events are generated by the background thread of the server model that monitors the remote servers. If one of the servers is killed externally you can see the server's state being updated to stop and a stopped event being generated.</P><P> Thinking back to the dashboard, if a warning red light shows an unusual condition, there's usually further investigation required. The experienced mechanic wants to open the hood to see the internal workings of
+the running system. In our example, when the server and the log views provide an indication of a problem, the administrator might want to
+dig deeper to check the state of the server. <P>
+In our example we have the ServerContentView in the right hand of the
+perspective. This shows the details of our PhoneBookServer, namely the
+names and phone numbers corresponding to the server
+selected in the Servers view. If the server is stopped, there is no
+detailed content.</P>
+<H2><A name="launchServerSection"></A>Launching server instances </H2>
+<P>
+When developing applications destined to run in a server environment, it’s useful to have an instance of the target server under the
+control of the development environment. This allows the development environment – i.e. the workbench – to be the single point of
+control for running the application under development. (If the server itself is the application being developed, the picture changes a
+little.) A sample use is a test environment, though this function is not limited to it.<P>
+If the server is a separate, existing application, we need a way of launching it from the workbench while making its output visible to the developer. In order to do this we use the framework described in <A
+ href="http://www.eclipse.org/articles/Article-Java-launch/launching-java.html">Launching
+Java Application programmatically</A>.
+<H3>
+The ServerLauncher class
+</H3>
+<P>
+An instance of a server launcher is associated with each server instance that’s defined as local. (The local property exists in order for us
+to determine whether or not we can launch the defined server as a local process.).
+ The launcher is set on the <SAMP>start</SAMP> method oof the ServerElement and nulled up on the <SAMP>stop</SAMP>
+and is used to determine the started/stopped status. The steps necessary to launch our phone server are detailed below:</P>
+<UL>
+ <LI>gets the launch manager <CODE><IMG height="13"
+ src="images/tag_1.gif" width="24" border="0"></CODE></LI>
+ <LI>constructs a launch configuration type and copy <CODE><IMG
+ height="13" src="images/tag_2.gif" width="24" border="0"></CODE></LI>
+ <LI>set the attributes and classpath <CODE><IMG height="13"
+ src="images/tag_3.gif" width="24" border="0"></CODE></LI>
+ <LI>launch the configuration <CODE><IMG height="13"
+ src="images/tag_4.gif" width="24" border="0"></CODE></LI>
+</UL>
+<BLOCKQUOTE><PRE>
+public ILaunch launch (String mainClassname, String args) throws IOException, CoreException {
+<IMG height="13" src="images/tag_1.gif" width="24" border="0"> ILaunchManager manager = DebugPlugin.getDefault ().getLaunchManager ();
+ ILaunchConfigurationType type = manager.getLaunchConfigurationType
+ (IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
+<IMG height="13" src="images/tag_2.gif" width="24" border="0"> ILaunchConfigurationWorkingCopy config = type.newInstance (null, mainClassname);
+
+ config.setAttribute (IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainClassname);
+ config.setAttribute (IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, args);
+<IMG height="13" src="images/tag_3.gif" width="24" border="0"> setClasspath (config);
+<IMG height="13" src="images/tag_4.gif" width="24" border="0"> return config.launch (ILaunchManager.RUN_MODE, new NullProgressMonitor ());
+}</PRE>
+<P>The <CODE>setClasspath</CODE> method creates the list of classpath entries by adding the JVM and all the required plug-ins and libraries. For more details, see the code.</P>
+</BLOCKQUOTE>
+
+ <H2>Tying it all together</H2>
+
+ <H3>The monitor perspective</H3>
+ <P>Admittedly it is a bad idea to create your own perspective in
+ Eclipse, you should aim to reuse the existing ones. We made an
+ exception for this article, because no existing perspective seem to
+ quite fit with the task of administering objects and for illustration
+ purpose. <P>
+ We use the <CODE>org.eclipse.ui.perspectives</CODE> extension point,
+ giving it the class attribute which must implement the <CODE>org.eclipse.ui.IPerspectiveFactory</CODE>
+ interface. The <CODE>createLayout</CODE> method arranges the views that
+ are relevant to our monitoring application. The layout is defined
+ around the editor area(top-right part). We don't actually have anything
+ to edit so make the editor area not visible. To the left of it, there
+ is the servers view. Replacing the editor area is a view that shows
+ the content of the selected server. At the bottom of the page, we show
+ the monitor view and below the property view
+ and the console view.</P>
+ <H3>Server preferences</H3>
+ <P>We use <CODE>org.eclipse.ui.preferencePages</CODE> extension point
+ with <CODE>ServerPreferencePage</CODE> as its class attribute
+ to define two of the configuration attributes of the server. One of
+ them is specific to our server, the maximum number of entries that the
+ phone directory accepts. After this number is reached, alarms are sent
+ to the log view if more entries are added. <P>
+ The second parameter is more generic and could be used for other
+ servers. It describes the refresh interval that the sample uses are to
+ maintain the status of the connections up to date. The line from below is used to extract the preferred value of a parameter from the preference store associated with our plug-in.<P>
+<CODE>ServersPlugin.getDefault().getPreferenceStore().getInt("MAXIMUM_ENTRIES")</CODE></P>
+
+
+ <H2><A name="serverSection">Server</A></H2>
+ <P align="left">The server we've supplied in our example is a simple HTTP server representing a phone book. The server holds a set of phone number entries in a Properties object, and supports a handful of HTTP requests to query and update the content. The requests supported are
+<UL>
+ <LI><CODE>/lookup?name=name</CODE>: returns the phone number entry for the given name</LI>
+ <LI><CODE>/remove?name=name</CODE>: removes the phone number entry for the given name</LI>
+ <LI><CODE>/update?name=name&amp;value=value</CODE>: creates or updates the phone number entry for the given name</LI>
+ <LI><CODE>/count</CODE>: returns the number of phone number entries stored in the server</LI>
+ <LI><CODE>/info</CODE>: returns a version string</LI>
+ <LI><CODE>/</CODE>: returns the server's set of entries</UL>
+<P> Much of the server's code is there simply to implement just enough of the
+ HTTP 1.1 protocol to support the necessary operations. We use a PhoneBookClient
+ object to construct the necessary queries and handle the responses. A java.net.URLConnection
+ provides the client-side implementation of the HTTP protocol, and the PhoneBookClient
+ simply creates URLConnection instances with the appropriate request URI for
+ each operation.</P>
+<H2><A name="resourceSection"></A>Resources</H2>
+
+<P> <A href="monitorPlugin.jar">Monitor sample</A></P>
+<P><SMALL>Java and all Java-based trademarks and logos are trademarks or
+registered trademarks of Sun Microsystems, Inc. in the United States,
+other countries, or both. <BR>
+Other company, product or service names may be trademarks or service marks of others
+</SMALL>
+</P>
+</BODY></HTML>
diff --git a/Article-Monitor/monitorPlugin.jar b/Article-Monitor/monitorPlugin.jar
new file mode 100644
index 0000000..6583399
--- /dev/null
+++ b/Article-Monitor/monitorPlugin.jar
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/FieldEditorPreferenceHierarchy.GIF b/Article-Mutatis-mutandis/images/FieldEditorPreferenceHierarchy.GIF
new file mode 100644
index 0000000..5742fa1
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/FieldEditorPreferenceHierarchy.GIF
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/Idea.jpg b/Article-Mutatis-mutandis/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/Idea.jpg
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/PreferencePage.GIF b/Article-Mutatis-mutandis/images/PreferencePage.GIF
new file mode 100644
index 0000000..599c389
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/PreferencePage.GIF
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/PropertyHierarchy.GIF b/Article-Mutatis-mutandis/images/PropertyHierarchy.GIF
new file mode 100644
index 0000000..5132ef5
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/PropertyHierarchy.GIF
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/PropertyPage.GIF b/Article-Mutatis-mutandis/images/PropertyPage.GIF
new file mode 100644
index 0000000..a9b1a42
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/PropertyPage.GIF
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/linux_only.gif b/Article-Mutatis-mutandis/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/linux_only.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/spellPreferences.GIF b/Article-Mutatis-mutandis/images/spellPreferences.GIF
new file mode 100644
index 0000000..fe3dd32
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/spellPreferences.GIF
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/spellProperties.GIF b/Article-Mutatis-mutandis/images/spellProperties.GIF
new file mode 100644
index 0000000..82f4a0d
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/spellProperties.GIF
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/tag_1.gif b/Article-Mutatis-mutandis/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/tag_1.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/tag_2.gif b/Article-Mutatis-mutandis/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/tag_2.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/tag_3.gif b/Article-Mutatis-mutandis/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/tag_3.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/tag_4.gif b/Article-Mutatis-mutandis/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/tag_4.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/tag_5.gif b/Article-Mutatis-mutandis/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/tag_5.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/tag_6.gif b/Article-Mutatis-mutandis/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/tag_6.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/tag_7.gif b/Article-Mutatis-mutandis/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/tag_7.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/tip.gif b/Article-Mutatis-mutandis/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/tip.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/tryit.gif b/Article-Mutatis-mutandis/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/tryit.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/images/win_only.gif b/Article-Mutatis-mutandis/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Mutatis-mutandis/images/win_only.gif
Binary files differ
diff --git a/Article-Mutatis-mutandis/overlay-pages.html b/Article-Mutatis-mutandis/overlay-pages.html
new file mode 100644
index 0000000..a1b65d7
--- /dev/null
+++ b/Article-Mutatis-mutandis/overlay-pages.html
@@ -0,0 +1,812 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta http-equiv="Content-Language" content="en-us">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Mutatis mutandis - Using Preference Pages as Property Pages</title>
+<link rel="stylesheet" href="../default_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2003 Berthold Daum.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">Mutatis mutandis - Using Preference Pages as Property Pages</h1>
+
+<blockquote>
+<b>Summary</b>
+
+<br>
+A common problem in the implementation of applications is the implementation of
+project-specific properties that override workbench-wide preferences on project or file level. The
+naive approach is to implement these pages from scratch. However, writing the
+same code twice is a boring task and leads to increased maintenance efforts. In
+this article we show how existing preferences pages (with or without field
+editors) can be easily converted into pages that can act as both preference and
+property pages. We demonstrate this by implementing the abstract class <code> FieldEditorOverlayPage</code>
+providing the necessary functionality.
+ <p><b>Berthold Daum, bdaum industrial communications</b> <br>
+ October 24, 2003 </p>
+</blockquote>
+
+<hr width="100%">
+<h2>The problem</h2>
+<p>Implementing <i>Preference Pages</i> for Eclipse plug-ins is not a difficult
+ task, especially if you use field editors. Such preference pages are usually
+ implemented as subclasses of <code>org.eclipse.jface.preference.PreferencePage</code>
+ and <code>org.eclipse.jface.preference.FieldEditorPreferencePage</code>. There
+ are already two excellent articles on <i> Eclipse Corner</i> dealing with this
+ subject: <a href="../Article-Preferences/preferences.htm">Preferences in the
+ Eclipse Workbench UI</a> by Tod Creasey and <a href="../Article-Field-Editors/field_editors.html">Simplifying
+ Preference Pages with Field Editors</a> by Ryan Cooper. In this article I will
+ not go into details with the implementation of preference pages but assume that
+ you are already fairly familiar with standard implementation techniques of such
+ pages.</p>
+<p>The problem that I want to discuss here begins after you already have implemented
+preference pages for your plug-in. At some stage you notice that some or all of your plug-in
+preferences should rather be project specific or even file specific. The usual
+way to implement such project or file specific settings are <i>Property Pages</i>,
+which usually are subclasses of <code>org.eclipse.ui.dialogs.PropertyPage</code>.
+The Eclipse workbench already contains some examples of how property pages are used to override workbench settings on project level. One example are the <i> Java
+Compiler</i> settings. These settings can be controlled in the workbench
+preferences but can be overridden for each
+Java project separately by project specific property pages.&nbsp;</p>
+<table border="0">
+ <tr>
+ <td width="50%"><img border="0" src="images/PreferencePage.GIF" width="441" height="380">
+ <p><i>The Java compiler settings in the workbench preferences</i>
+ <p><i>&nbsp;</i></td>
+ </tr>
+ <tr>
+ <td width="50%"><img border="0" src="images/PropertyPage.GIF" width="440" height="355">
+ <p><i>The Java compiler settings as a property page of a Java project</i></td>
+ </tr>
+</table>
+<p>As we see, both preference page and property page look, in fact, very similar. There are some differences, however,
+at the top of the page. Instead of the page description, the property page
+contains two radio buttons for toggling between workbench settings and project settings. It also features a button for direct access to the
+corresponding workbench preference page. But its main body (in this case the
+tabbed notebook) is identical with the main body of the corresponding preference
+page.</p>
+<h2>Possible solutions</h2>
+<p>An obvious solution to this problem is to implement both pages from scratch.
+However, since the main body of the both pages is identical, this would result
+in a large portion of duplicated code, code that is subject to later maintenance
+and thus increases maintenance costs. After all, object-oriented programming is
+about reuse, isn't it?</p>
+<p>Well, why don't we factor out the main body of both pages into a separate
+class? This is actually the way in which both pages shown above are implemented.
+(The tabbed notebook is implemented in JDT class <code>CompilerConfigurationBlock</code>.)
+But this technique is not trivial. What I did not tell you is that preference
+pages and property pages are based on different data models. Workbench preferences
+are usually stored in plug-in specific but workbench-wide preference stores. Properties,
+in contrast, are stored as resource related properties. The interface <code>org.eclipse.core.resources.IResource</code>
+provides the necessary access method. When a resource is deleted, also its
+properties cease to exist. This different way of data management would require
+us to implement two variants of access routines, if we want to use preference
+pages in the role of property pages. For property pages we would need to direct all field accesses
+to the respective resource (project or file), for preference pages we would need
+to direct all field accesses to the plug-in specific preference store. Unfortunately, this
+strategy is not possible for preference pages utilizing field editors. Field
+editors internally always access a preference store - we cannot tell them to
+access resource properties instead. So we would need to re-implement the whole
+property page - replacing the field editors with standard SWT widgets! Not very nice.</p>
+<p>Fortunately, there is another solution and it works for field editors, too.
+To get to this solution we have to look at the inheritance trees of both field
+editor preference pages and property pages. (We will deal with the problem of
+field editor preferences pages first and will discuss &quot;normal&quot;
+preference pages later.)</p>
+<table border="0">
+ <tr>
+ <td width="50%" valign="top"><img border="0" src="images/FieldEditorPreferenceHierarchy.GIF" width="225" height="169"></td>
+ <td width="50%" valign="top"><img border="0" src="images/PropertyHierarchy.GIF" width="220" height="181"></td>
+ </tr>
+</table>
+<p>Both types are extensions of the abstract class <code>PreferencePage</code>.
+The class <code>FieldEditorPreferencePage</code> implements, in addition, the
+interface <code>IPropertyChangeListener</code>, while the class <code>PropertyPage</code>
+additionally implements the interface <code>IWorkbenchPropertyPage</code>. Since
+the extension from <code>PreferencePage</code> to <code>PropertyPage</code> is
+minimal (the implementation of <code>IWorkbenchPropertyPage</code> is
+trivial), it makes sense to base our solution on class <code>FieldEditorPreferencePage</code>
+and simply add the implementation of <code>IWorkbenchPropertyPage</code>.</p>
+<p>But how do we deal with the problem of different data models for property
+pages and preference pages? Since field editors can only access preference
+stores, we simply create a temporary preference store (which we call <i>overlay store</i>
+within this article)
+when a property page is initialized. We implement this store by extending class <code>PreferenceStore</code>
+but provide different semantics to its access methods. In particular, when
+fetching a value from the store, we look into the resource properties first if
+we can find an identically named value there. Only if such a value is not found,
+we refer to the underlying workbench preference store. The <code>save()</code>
+methods of this store have different semantics, too: they must store the values
+contained in the overlay store into the resource properties instead of saving them as preferences. So,
+our field editors have only to deal with a preference store and are perfectly
+happy.</p>
+<h2>Implementing class PropertyStore</h2>
+<p>The class <code> PropertyStore</code> implements the overlay store and extends the class
+<code>PreferenceStore</code>. Each instance of <code>
+PropertyStore</code> represents the properties of a specific resource in context
+of a specific
+property page but as an incarnation of a property store. Because the store is
+resource and page specific, we pass the <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+resource and a <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+page identification in the constructor:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">class</font></b> PropertyStore <b><font COLOR="#7f0055">extends</font></b> PreferenceStore {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">private</font></b> IResource resource;
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">private</font></b> IPreferenceStore workbenchStore;
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">private</font></b> String pageId;</pre>
+<pre> <b><font COLOR="#7f0055">public</font></b> PropertyStore(IResource resource,
+ IPreferenceStore workbenchStore,
+ String pageId) {
+ <font COLOR="#7f0055"><b>this</b></font>.resource = resource;
+ <b><font COLOR="#7f0055">this</font></b>.workbenchStore = workbenchStore;
+ <b><font COLOR="#7f0055">this</font></b>.pageId = pageId;
+ }</pre>
+<p>We also pass the underlying <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+workbench preference store. When a preference value is not available as a
+resource property value, we will route accesses through to this
+store.</p>
+<h5>Getters and Setters</h5>
+<p>Now, let's first discuss the <code>get...()</code> accessors. The class <code>PreferenceStore</code>
+has an awful lot of them, one for each primitive Java type and one for <code>java.lang.String</code>. Here, we show only
+the accessor for type <code>String</code> but leave the others to your
+imagination. Let's start with the accessor for the default values:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> String getDefaultString(String name) {
+ <b><font COLOR="#7f0055">return</font></b> workbenchStore.getDefaultString(name);
+ }</pre>
+<p>Well, that was easy enough. Because we don't store any default values in <code>PropertyStore</code>
+we just fetch the default values from the workbench preference store. Next are
+the accessors for non-default values:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> String getString(String name) {
+ insertValue(name);
+ <font COLOR="#7f0055"><b>return</b></font> <b><font COLOR="#7f0055">super</font></b>.getString(name);
+ }</pre>
+<p>That seems easy enough, too, but what's in <code>insertValue()</code> ?</p>
+<pre> <b><font COLOR="#7f0055">private</font></b> <b><font COLOR="#7f0055">boolean</font></b> inserting = <b><font COLOR="#7f0055">false</font></b>;</pre>
+<pre><b><font COLOR="#7f0055"> private</font></b> <b><font COLOR="#7f0055">synchronized</font></b> <b><font COLOR="#7f0055">void</font></b> insertValue(String name) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">if</font></b> (inserting)
+ <b><font COLOR="#7f0055">return</font></b>;
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">if</font></b> (<b><font COLOR="#7f0055">super</font></b>.contains(name))
+ <b><font COLOR="#7f0055">return</font></b>;
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> inserting = <b><font COLOR="#7f0055">true</font></b>;
+ String prop = <b><font COLOR="#7f0055">null</font></b>;
+ <b><font COLOR="#7f0055">try</font></b> {
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> prop = getProperty(name);
+ } <b><font COLOR="#7f0055">catch</font></b> (CoreException e) {
+ }
+ <font COLOR="#7f0055"><b>if</b></font> (prop == <b><font COLOR="#7f0055">null</font></b>)
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> prop = workbenchStore.getString(name);
+ <font COLOR="#7f0055"><b>if</b></font> (prop != <b><font COLOR="#7f0055">null</font></b>)
+<img src="images/tag_5.gif" height=13 width=24 align=CENTER> setValue(name, prop);
+ inserting = <b><font COLOR="#7f0055">false</font></b>;
+ }</pre>
+<pre><b><font COLOR="#7f0055"> private</font></b> String getProperty(String name) <b><font COLOR="#7f0055">
+ throws</font></b> CoreException {
+<img src="images/tag_6.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">return</font></b> resource.getPersistentProperty(<b><font COLOR="#7f0055">
+ new</font></b> QualifiedName(pageId, name));
+ }</pre>
+<p>Not easy at all! It starts with a synchronized method and a <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+semaphore (<code>inserting</code>). This is necessary to avoid recursions.
+Method calls inside the <code>insertValue()</code> body internally call <code>getString()</code>
+which would lead to unlimited recursion and a stack overflow. The semaphore
+inhibits just this. To make this logic thread safe we have declared this method
+as synchronized.</p>
+<p>After we have made sure that this is not a recursive call we first look if the value is already stored in the <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+ local store instance. If yes, we do
+nothing. If not, we try to <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+read a property with the same name. We always <img src="images/tag_6.gif" height=13 width=24 align=CENTER>
+ qualify the names of properties with the page identification to avoid name clashes between
+properties from different property pages. If such a property value does not
+exist, we get the value from the <img src="images/tag_4.gif" height=13 width=24 align=CENTER>
+workbench preference store. Then we <img src="images/tag_5.gif" height=13 width=24 align=CENTER>
+cache this value in the local store.&nbsp;Sooner or later, the value of all
+fields in a given page will end up in this local core: all field editors will
+call a <code>get...()</code> method in order to display a value on the
+page.&nbsp;</p>
+<p>What about the corresponding <code>set...() </code>methods? Fortunately, we
+don't have to override these methods because all changes are applied directly to
+the local store. However, a few other <code>PreferenceStore</code> methods need
+consideration.</p>
+<h5>More methods</h5>
+<p>In particular, we have to modify the methods <code>contains()</code>, <code>isDefault()</code>
+and <code>setToDefault()</code>. Let's start with method <code>contains()</code>:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">boolean</font></b> contains(String name) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">return</font></b> workbenchStore.contains(name);
+ }</pre>
+<p>Here, we just <img src="images/tag_1.gif" height=13 width=24 align=CENTER> delegate to the workbench preference store assuming that
+the property page is an exact replica of the preference page.</p>
+<p>Default values need a bit more attention. Above, we had simply delegated <code>getDefault...()</code>
+calls to the workbench preference store. But what if we want to reset a
+property to its default value? Standard preference stores internally contain two
+sets of properties: one for the default values and one for the non-default
+values. The second set only contains a value if it is unequal to the default value.
+So, when a value is reset to its default value, it is sufficient to remove it
+from the set of non-default values. In our case, however, we need a different
+implementation. We must explicitly <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+store property values that equal the default value. So we are able to set
+resource level properties to their default while on workbench level they still
+have a non-default value:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">void</font></b> setToDefault(String name) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> setValue(name, getDefaultString(name));
+ }</pre>
+<p>This has implications for the method <code>isDefault()</code>. The standard
+implementation just tests if the specified property name is contained in the set
+of non-default values. In our case, however, this is not sufficient because this
+value set may contain default values, too. We must therefore explicitly compare <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+ non-default values with <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+default values:</p>
+<font>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">boolean</font></b> isDefault(String name) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> String defaultValue = getDefaultString(name);
+ <font COLOR="#7f0055"><b>if</b></font> (defaultValue == <b><font COLOR="#7f0055">null</font></b>) <b><font COLOR="#7f0055">return</font></b> <b><font COLOR="#7f0055">false</font></b>;
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> <font COLOR="#7f0055"><b>return</b></font> defaultValue.equals(getString(name));
+ }</pre>
+<h5>Updating Resource Properties</h5>
+<p>What remains to do is overriding both <code>save()</code>
+ methods of class <code>PreferenceStore</code>. In contrast to the standard save operation we write all
+cached values to
+the resource properties:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">void</font></b> save() <b><font COLOR="#7f0055">throws</font></b> IOException {
+ writeProperties();
+ }</pre>
+<pre><font COLOR="#7f0055"> <b>public</b></font> <b><font COLOR="#7f0055">void</font></b> save(OutputStream out, String header) <b><font COLOR="#7f0055">
+ throws</font></b> IOException {
+ writeProperties();
+ }</pre>
+<pre><font COLOR="#7f0055"> <b>private</b></font> <b><font COLOR="#7f0055">void</font></b> writeProperties() <b><font COLOR="#7f0055">throws</font></b> IOException {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> String[] preferences = <b><font COLOR="#7f0055">super</font></b>.preferenceNames();
+ <b><font COLOR="#7f0055">for</font></b> (<b><font COLOR="#7f0055">int</font></b> i = 0; i &lt; preferences.length; i++) {
+ String name = preferences[i];
+ <font COLOR="#7f0055"><b>try</b></font> {
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> setProperty(name, getString(name));
+ } <b><font COLOR="#7f0055">catch</font></b> (CoreException e) {
+ <b><font COLOR="#7f0055">throw</font></b> <b><font COLOR="#7f0055">new</font></b> IOException(<font COLOR="#2a00ff">
+ &quot;Cannot write resource property &quot;</font> + name);
+ }
+ }
+ }</pre>
+<pre><b><font COLOR="#7f0055"> private</font></b> <b><font COLOR="#7f0055">void</font></b> setProperty(String name, String value) <b><font COLOR="#7f0055">
+ throws</font></b> CoreException {
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> resource.setPersistentProperty(<b><font COLOR="#7f0055">
+ new</font></b> QualifiedName(pageId, name), value);
+ }</pre>
+<p>Here, we first get the <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+ names of all values in the local preference store. Then we <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+ write each of them into the resource properties as shown above. Again, we need to <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+ qualify the property name with the page identification.</p>
+<p>We are now done with the implementation of class <code>PropertyStore</code>
+and turn our attention to GUI issues.</p>
+<h2>Implementing class FieldEditorOverlayPage</h2>
+<p>The class <code>FieldEditorOverlayPage</code> can act as a common superclass for all field editor preference pages that
+also
+want to behave as property pages.</p>
+<h5>A place in the type hierarchy</h5>
+<p> As we have already discussed above this
+class <img src="images/tag_1.gif" height=13 width=24 align=CENTER> extends class <code>FieldEditorPreferencePage</code> and additionally
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> implements <code>IWorkbenchPropertyPage</code>.
+We
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> replicate all constructors of class <code>FieldEditorPreferencePage</code> but
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> save the image passed in
+the third constructor for later use:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">abstract</font></b> <b><font COLOR="#7f0055">class</font></b> FieldEditorOverlayPage
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <font COLOR="#7f0055"><b>extends</b></font> FieldEditorPreferencePage
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">implements</font></b> IWorkbenchPropertyPage</pre>
+<pre><img src="images/tag_3.gif" height=13 width=24 align=CENTER><b><font COLOR="#7f0055"> public</font></b> FieldEditorOverlayPage(<b><font COLOR="#7f0055">int</font></b> style) {
+ <b><font COLOR="#7f0055">super</font></b>(style);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> public</font></b> FieldEditorOverlayPage(String title, <b><font COLOR="#7f0055">int</font></b> style) {
+ <b><font COLOR="#7f0055">super</font></b>(title, style);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> private</font></b> ImageDescriptor image;</pre>
+<pre><b><font COLOR="#7f0055"> public</font></b> FieldEditorOverlayPage(String title,
+ ImageDescriptor image, <b><font COLOR="#7f0055">
+ int</font></b> style) {
+ <b><font COLOR="#7f0055">super</font></b>(title, image, style);
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">this</font></b>.image = image;
+ }</pre>
+<p>The implementation of interface <code>IWorkbenchPropertyPage</code> is
+trivial, indeed:</p>
+<pre><img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">private</font></b> IAdaptable element;</pre>
+<pre><img src="images/tag_2.gif" height=13 width=24 align=CENTER> <font COLOR="#7f0055"><b>public</b></font> <b><font COLOR="#7f0055">void</font></b> setElement(IAdaptable element) {
+ <b><font COLOR="#7f0055">this</font></b>.element = element;
+ }</pre>
+<pre> <b><font COLOR="#7f0055">public</font></b> IAdaptable getElement() {
+ <font COLOR="#7f0055"><b>return</b></font> element;
+ }</pre>
+<p>The method <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+<code>setElement()</code> is called when a property page is opened. In our
+case, when the property page is called on a project, folder, or file, the <code>
+IAdaptable</code> that is passed as an argument is actually of type <code>IResource</code>.
+We simply store this element in an <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+ instance variable. Obviously, when this variable is not <code>null</code>, the
+current instance of <code>FieldEditorOverlayPage</code>
+represents a property page, otherwise a preference page. We express this fact in
+the following method:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">boolean</font></b> isPropertyPage() {
+ <b><font COLOR="#7f0055">return</font></b> element != <b><font COLOR="#7f0055">null</font></b>;
+ }</pre>
+<p>We can use this method, for example, in subclasses that want to vary the page
+content depending on if it is a property page or a preference page.</p>
+<h5>Additional GUI elements</h5>
+<p>Also the GUI elements of class <code>FieldEditorOverlayPage</code> are
+variable. If the page instance represents a property page, we want the button
+group for project/workbench selection at the top. If it is a preference page, we
+don't. Depending on the state of these buttons we must enable or
+disable the field editors, too.</p>
+<p>Let's start with this button group. To add these buttons to a property page we
+extend the method <code>createContents()</code>:</p>
+<pre><b><font COLOR="#7f0055"> public static</font></b> <b><font COLOR="#7f0055">final</font></b> String USEPROJECTSETTINGS = <font COLOR="#2a00ff">
+ &quot;useProjectSettings&quot;</font>;</pre>
+<pre><b><font COLOR="#7f0055"> private</font></b> Button useWorkspaceSettingsButton,
+ useProjectSettingsButton,
+ configureButton;</pre>
+<pre><b><font COLOR="#7f0055"> protected</font></b> Control createContents(Composite parent) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <font COLOR="#7f0055"><b>if</b></font> (isPropertyPage())
+ createSelectionGroup(parent);
+ <font COLOR="#7f0055"><b>return</b></font> <b><font COLOR="#7f0055">super</font></b>.createContents(parent);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> private</font></b> void createSelectionGroup(Composite parent) {
+ Composite comp = <b><font COLOR="#7f0055">new</font></b> Composite(parent, SWT.NONE);
+ GridLayout layout = <b><font COLOR="#7f0055">new</font></b> GridLayout(2, <b><font COLOR="#7f0055">false</font></b>);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ comp.setLayoutData(<b><font COLOR="#7f0055">new</font></b> GridData(GridData.FILL_HORIZONTAL));
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> Composite radioGroup = <b><font COLOR="#7f0055">new</font></b> Composite(comp, SWT.NONE);
+ radioGroup.setLayout(<b><font COLOR="#7f0055">new</font></b> GridLayout());
+ radioGroup.setLayoutData(<b><font COLOR="#7f0055">new</font></b> GridData(GridData.FILL_HORIZONTAL));
+ useWorkspaceSettingsButton =
+ createRadioButton(radioGroup, <font COLOR="#2a00ff">&quot;Use workspace settings&quot;</font>);
+ useProjectSettingsButton =
+ createRadioButton(radioGroup, <font COLOR="#2a00ff">&quot;Use project settings&quot;</font>);
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> configureButton = <b><font COLOR="#7f0055">new</font></b> Button(comp, SWT.PUSH);
+ configureButton.setText(<font COLOR="#2a00ff">&quot;Configure Workspace Settings ...&quot;</font>);
+ configureButton.addSelectionListener(<b><font COLOR="#7f0055">new</font></b> SelectionAdapter() {
+ <b><font COLOR="#7f0055">public</font></b> <b><font COLOR="#7f0055">void</font></b> widgetSelected(SelectionEvent e) {
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> configureWorkspaceSettings();
+ }
+ });
+<b><font COLOR="#7f0055"> try</font></b> {
+<img src="images/tag_5.gif" height=13 width=24 align=CENTER> String use = ((IResource) element).getPersistentProperty(
+ <font COLOR="#7f0055"><b>new</b></font> QualifiedName(pageId, USEPROJECTSETTINGS));
+<img src="images/tag_6.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">if</font></b> (&quot;true&quot;.equals(use)) {
+ useProjectSettingsButton.setSelection(<b><font COLOR="#7f0055">true</font></b>);
+ configureButton.setEnabled(<b><font COLOR="#7f0055">false</font></b>);
+ } <b><font COLOR="#7f0055">else
+</font></b> useWorkspaceSettingsButton.setSelection(<b><font COLOR="#7f0055">true</font></b>);
+ } <b><font COLOR="#7f0055">catch</font></b> (CoreException e) {
+ useWorkspaceSettingsButton.setSelection(<b><font COLOR="#7f0055">true</font></b>);
+ }
+ }</pre>
+<p>This code is straightforward. If the current instance is a <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+property page, we create a group of <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+two radio buttons and a <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+push button. When this button is pressed,
+the <img src="images/tag_4.gif" height=13 width=24 align=CENTER> method <code>configureWorkspaceSettings()</code>
+ is called for configuring the corresponding workspace settings. (We will discuss this method later.)&nbsp;</p>
+<p>After the controls have been created they are <img src="images/tag_6.gif" height=13 width=24 align=CENTER>
+initialized. To do so we <img src="images/tag_5.gif" height=13 width=24 align=CENTER>
+fetch the resource property <code>USEPROJECTSETTINGS</code>.
+Because this setting may be different for each single property page, we qualify
+the name of this property with the page identification.</p>
+<p>Both radio buttons are created via the convenience method <code>createRadioButton()</code>:</p>
+<pre><b><font COLOR="#7f0055"> private</font></b> Button createRadioButton(Composite parent, String label) {
+ <font COLOR="#7f0055"><b>final</b></font> Button button = <b><font COLOR="#7f0055">new</font></b> Button(parent, SWT.RADIO);
+ button.setText(label);
+ button.addSelectionListener(<b><font COLOR="#7f0055">new</font></b> SelectionAdapter() {
+ <b><font COLOR="#7f0055">public</font></b> <b><font COLOR="#7f0055">void</font></b> widgetSelected(SelectionEvent e) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> configureButton.setEnabled(button == useWorkspaceSettingsButton);
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> updateFieldEditors();
+ }
+ });
+ <b><font COLOR="#7f0055">return</font></b> button;
+ }</pre>
+<p>When a radio button is pressed, we <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+enable or disable
+the button for the workbench configuration (enabled when we use the workbench
+settings), and we <img src="images/tag_2.gif" height=13 width=24 align=CENTER> enable or disable the field editors (disabled when the
+workbench settings are activated).&nbsp;</p>
+<p> However, this confronts us with a problem. We have to know
+the page's field editors. Our parent class <code>FieldEditorPreferencePage</code>
+has this knowledge, but unfortunately it keeps this knowledge close to itself.
+We must therefore keep track of the field editor ourselves. To do so, we
+override the method <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+<code>addField()</code> and add each field editor added to the page to a <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+list:</p>
+<pre><img src="images/tag_1.gif" height=13 width=24 align=CENTER><b><font COLOR="#7f0055"> </font><font COLOR="#7f0055">private</font></b> List editors = <b><font COLOR="#7f0055">new</font></b> ArrayList();</pre>
+<pre><img src="images/tag_2.gif" height=13 width=24 align=CENTER><b><font COLOR="#7f0055"> protected</font></b> <b><font COLOR="#7f0055">void</font></b> addField(FieldEditor editor) {
+ editors.add(editor);
+ <font COLOR="#7f0055"><b>super</b></font>.addField(editor);
+ }</pre>
+<p>Now, we can implement the method <code>updateFieldEditors()</code>:</p>
+<pre><b><font COLOR="#7f0055"> private</font></b> <b><font COLOR="#7f0055">void</font></b> updateFieldEditors() {
+ <font COLOR="#7f0055"><b>boolean</b></font> enabled = useProjectSettingsButton.getSelection();
+ updateFieldEditors(enabled);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> protected</font></b> <b><font COLOR="#7f0055">void</font></b> updateFieldEditors(<b><font COLOR="#7f0055">boolean</font></b> enabled) {
+ Composite parent = getFieldEditorParent();
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> Iterator it = editors.iterator();
+ <font COLOR="#7f0055"><b>while</b></font> (it.hasNext()) {
+ FieldEditor editor = (FieldEditor) it.next();
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> editor.setEnabled(enabled, parent);
+ }
+ }</pre>
+<p>We simply <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+iterate through the list of field editors and
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+ tell each field editor if it is enabled or not. Subclasses may override this
+method if special treatment is required. This may be the case when the
+enablement of field editors depends on the state of other field editors or on
+the current state of the application.</p>
+<h5>Modifying the access layer</h5>
+<p>We have nearly completed the GUI part of class <code>FieldEditorOverlayPage</code>.
+We only must enable or disable the field editors appropriately after they have
+been created. The best place to do this is the method <code>createControl()</code>
+where we <img src="images/tag_4.gif" height=13 width=24 align=CENTER> call <code>updateFieldEditors()</code>
+after the <img src="images/tag_3.gif" height=13 width=24 align=CENTER> complete
+page content has been created:</p>
+<pre><b><font COLOR="#7f0055"> private</font></b> IPreferenceStore overlayStore;</pre>
+<pre><b><font COLOR="#7f0055"> private</font></b> String pageId;</pre>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">void</font></b> createControl(Composite parent) {
+ <b><font COLOR="#7f0055">if</font></b> (isPropertyPage()) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> pageId = getPageId();
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> overlayStore = <b><font COLOR="#7f0055">new</font></b> PropertyStore((IResource) getElement(), <b><font COLOR="#7f0055">
+ super</font></b>.getPreferenceStore(),
+ pageId);
+ }
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> <font COLOR="#7f0055"><b>super</b></font>.createControl(parent);
+ <b><font COLOR="#7f0055">if</font></b> (isPropertyPage())
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> updateFieldEditors();
+ }</pre>
+<pre><img src="images/tag_5.gif" height=13 width=24 align=CENTER><b><font COLOR="#7f0055"> protected</font></b> <b><font COLOR="#7f0055">abstract</font></b> String getPageId();</pre>
+<p>The method <code>createControl()</code> is also the best place to <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+create an instance of class <code>PropertyStore</code> (see above). This
+instance will act as our local overlay store. This <code>PropertyStore</code>
+instance is supplied with a <code>pageId</code> used for qualifying property
+names. We <img src="images/tag_1.gif" height=13 width=24 align=CENTER> obtain
+this value via the <img src="images/tag_5.gif" height=13 width=24 align=CENTER>
+method <code>getPageId()</code>. As this method is abstract, subclasses of <code>FieldEditorOverlayPage</code>
+are required to implement it.</p>
+<p>What remains to do is to inform clients about our overlay store. We do this
+by overriding the method <code>getPreferenceStore()</code>:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> IPreferenceStore getPreferenceStore() {
+ <b><font COLOR="#7f0055">if</font></b> (isPropertyPage())
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">return</font></b> overlayStore;
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">return</font></b> <b><font COLOR="#7f0055">super</font></b>.getPreferenceStore();
+ }</pre>
+<p>If the page is a property page we return the <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+overlay store, otherwise we just return the <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+standard preference store. All clients that can work with preference stores
+(such as field editors) will be happy.</p>
+<h5>Handling button events</h5>
+<p>The button group from above, needs some special treatment when the <i>OK</i>
+button or the <i>Restore Defaults</i> button is pressed. When the <i>OK</i>
+button is pressed, we need to save the selection state of the radio buttons, and
+when the <i>Restore Defaults</i> button is pressed, we need to set the selection
+state of these buttons:</p>
+<p>To implement this <i> OK</i> button behavior, we override the method <code>performOk()</code>.
+Pay close attention here because things are getting a bit tricky:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">boolean</font></b> performOk() {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">boolean</font></b> result = <b><font COLOR="#7f0055">super</font></b>.performOk();
+ <b><font COLOR="#7f0055">if</font></b> (result &amp;&amp; isPropertyPage()) {
+<font color="#3f7f5f"> </font>IResource resource = (IResource) element;
+ <b><font COLOR="#7f0055">try</font></b> {
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> String value = (useProjectSettingsButton.getSelection()) ?
+ TRUE : FALSE;
+ resource.setPersistentProperty(<font COLOR="#7f0055"><b>
+ new</b></font> QualifiedName(pageId, USEPROJECTSETTINGS), value);
+ } <b><font COLOR="#7f0055">catch</font></b> (CoreException e) {
+ }
+ }
+ <font COLOR="#7f0055"><b>return</b></font> result;
+ }</pre>
+<p>In method <code>performOk()</code> we first <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+execute the <code>performOk()</code> method of the super class, then save <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+ the state of the radio buttons into a resource property.</p>
+<pre><b><font COLOR="#7f0055"> protected</font></b> <b><font COLOR="#7f0055">void</font></b> performDefaults() {
+ <b><font COLOR="#7f0055">if</font></b> (isPropertyPage()) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> useWorkspaceSettingsButton.setSelection(<b><font COLOR="#7f0055">true</font></b>);
+ useProjectSettingsButton.setSelection(<b><font COLOR="#7f0055">false</font></b>);
+ configureButton.setEnabled(<b><font COLOR="#7f0055">true</font></b>);
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> updateFieldEditors();
+ }
+ <font COLOR="#7f0055"><b>super</b></font>.performDefaults();
+ }</pre>
+<p>Here, we
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> reset all buttons
+to <i>Use workspace settings</i> and <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+invoke method <code>updateFieldEditors()</code> to disable the field editors,
+too.</p>
+<p>To conclude the definition of this class, we implement
+the invocation of the corresponding workbench preference page when the <i>Configure
+Workbench Settings...</i> button is pressed. This is done in method <code>configureWorkspaceSettings()</code>:</p>
+<pre><b><font COLOR="#7f0055"> protected</font></b> <b><font COLOR="#7f0055">void</font></b> configureWorkspaceSettings() {
+ <font COLOR="#7f0055"><b>try</b></font> {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> IPreferencePage page =
+ (IPreferencePage) <b><font COLOR="#7f0055">this</font></b>.getClass().newInstance();
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> page.setTitle(getTitle());
+ page.setImageDescriptor(image);
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> showPreferencePage(pageId, page);
+ } <b><font COLOR="#7f0055">catch</font></b> (InstantiationException e) {
+ e.printStackTrace();
+ } <b><font COLOR="#7f0055">catch</font></b> (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }</pre>
+<p>This method first <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+ creates a sibling of the current instance, <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+ then completes its definition with title and image (remember, we had saved the
+required <code>ImageDescriptor</code> instance in one of the constructors), and <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+calls method <code>showPreferencePage()</code> on
+this new page:</p>
+<pre><b><font COLOR="#7f0055"> protected</font></b> <b><font COLOR="#7f0055">void</font></b> showPreferencePage(String id, IPreferencePage page) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">final</font></b> IPreferenceNode targetNode = <b><font COLOR="#7f0055">new</font></b> PreferenceNode(id, page);
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> PreferenceManager manager = <b><font COLOR="#7f0055">new</font></b> PreferenceManager();
+ manager.addToRoot(targetNode);
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> <font COLOR="#7f0055"><b>final</b></font> PreferenceDialog dialog = <b><font COLOR="#7f0055">
+ new</font></b> PreferenceDialog(getControl().getShell(), manager);
+ BusyIndicator.showWhile(getControl().getDisplay(), <b><font COLOR="#7f0055">new</font></b> Runnable() {
+ <b><font COLOR="#7f0055">public</font></b> <b><font COLOR="#7f0055">void</font></b> run() {
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> dialog.create();
+ dialog.setMessage(targetNode.getLabelText());
+<img src="images/tag_5.gif" height=13 width=24 align=CENTER> dialog.open();
+ }
+ });
+ }</pre>
+<p>The code for method <code>showPreferencePage()</code> is actually pinched from an existing
+workbench component (to be precise: from the property page implementation for the
+Java compiler settings). It <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+ creates a solitary preference node, <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+ adds it as the root object to a new preference manager, then constructs a <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+new
+preference dialog with this manager. This dialog is then <img src="images/tag_4.gif" height=13 width=24 align=CENTER>
+ created and <img src="images/tag_5.gif" height=13 width=24 align=CENTER> opened.</p>
+<p>This concludes the definition of class <code>FieldEditorOverlayPage</code>.</p>
+<h2>Using class FieldEditorOverlayPage</h2>
+<p>Using (i.e. subclassing) this class is very simple. Let us assume that we
+already have implemented a subclass of class <code>FieldEditorPreferencePage</code>.
+All what we have to do is to:</p>
+<ol>
+ <li>modify the <code>extends</code> declaration of this subclass (exchange <code>FieldEditorPreferencePage</code>
+ against <code>FieldEditorOverlayPage</code>).</li>
+ <li>provide an implementation of method <code>getPageId()</code>.</li>
+ <li>optionally we may implement layout variations depending on the page type
+ (preference page or property page).</li>
+</ol>
+<p>Afterwards we can use this subclass in both roles: as a property page and as
+a preference page.</p>
+<p>Let us look at an example. Here is the original field editor preference page:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">class</font></b> DefaultSpellCheckerPreferencePage <b><font COLOR="#7f0055">
+ extends</font></b> FieldEditorPreferencePage <b><font COLOR="#7f0055">
+ implements</font></b> IWorkbenchPreferencePage {</pre>
+<pre> <font COLOR="#7f0055"><b>public</b></font> DefaultSpellCheckerPreferencePage() {
+ <b><font COLOR="#7f0055">super</font></b>(GRID);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> public</font></b> IPreferenceStore doGetPreferenceStore() {
+ <b><font COLOR="#7f0055">return</font></b> SpellCheckerPlugin.getDefault().getPreferenceStore();
+ }</pre>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">void</font></b> init(IWorkbench workbench) {
+ setDescription(<font COLOR="#2a00ff">&quot;All changes will take effect ...&quot;</font>);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">void</font></b> createFieldEditors() {
+ Composite composite = getFieldEditorParent();
+ addField(<b><font COLOR="#7f0055">new</font></b> IntegerFieldEditor(
+ Configuration.SPELL_THRESHOLD,
+ <font COLOR="#2a00ff">&quot;Spell &amp;Threshold&quot;</font>,
+ composite));
+ addField(<b><font COLOR="#7f0055">new</font></b> BooleanFieldEditor(
+ Configuration.SPELL_IGNOREDIGITWORDS,
+ <font COLOR="#2a00ff">&quot;&amp;Ignore Numbers&quot;</font>,
+ composite));
+ ...
+ addField(<b><font COLOR="#7f0055">new</font></b> BooleanFieldEditor(
+ SpellCheckerPreferences.CHECKWHILETYPING,
+ <font COLOR="#2a00ff">&quot;Check &amp;while Typing&quot;</font>,
+ composite));
+ ...
+ }
+ }</pre>
+<p>And this is how we have to modify this class to be able using it as
+both a preference page and a property page. We have printed these changes in bold
+type:</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">class</font></b> DefaultSpellCheckerPreferencePage <b><font COLOR="#7f0055">
+ extends</font></b> <b>FieldEditorOverlayPage</b> <b><font COLOR="#7f0055">
+ implements</font></b> IWorkbenchPreferencePage {</pre>
+<pre> <font COLOR="#7f0055"><b>public</b></font> DefaultSpellCheckerPreferencePage() {
+ <b><font COLOR="#7f0055">super</font></b>(GRID);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> public</font></b> IPreferenceStore doGetPreferenceStore() {
+ <b><font COLOR="#7f0055">return</font></b> SpellCheckerPlugin.getDefault().getPreferenceStore();
+ }</pre>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">void</font></b> init(IWorkbench workbench) {
+ setDescription(<font COLOR="#2a00ff">&quot;All changes will take effect ...&quot;</font>);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> protected</font> String getPageId() {
+</b><img src="images/tag_1.gif" height=13 width=24 align=CENTER><b> <font COLOR="#7f0055">return</font> &quot;com.bdaum.SpellChecker.preferences.defaultPreferences&quot;;
+ }</b></pre>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">void</font></b> createFieldEditors() {
+ Composite composite = getFieldEditorParent();
+ addField(<b><font COLOR="#7f0055">new</font></b> IntegerFieldEditor(
+ Configuration.SPELL_THRESHOLD,
+ <font COLOR="#2a00ff">&quot;Spell &amp;Threshold&quot;</font>,
+ composite));
+ addField(<b><font COLOR="#7f0055">new</font></b> BooleanFieldEditor(
+ Configuration.SPELL_IGNOREDIGITWORDS,
+ <font COLOR="#2a00ff">&quot;&amp;Ignore Numbers&quot;</font>,
+ composite));
+ ...
+ <b><font COLOR="#7f0055">if</font> (!isPropertyPage()) {</b>
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> addField(<b><font COLOR="#7f0055">new</font></b> BooleanFieldEditor(
+ SpellCheckerPreferences.CHECKWHILETYPING,
+ <font COLOR="#2a00ff">&quot;Check &amp;while Typing&quot;</font>,
+ composite));
+ ...
+ <b>}</b></pre>
+<p>Note, that we display the <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+last field editor only in preference pages, not in property pages.</p>
+<p>In the plug-in manifest file <code>plugin.xml</code> the
+necessary declarations could look like this:</p>
+<pre><img src="images/tag_3.gif" height=13 width=24 align=CENTER><font COLOR="#000080"> &lt;extension id=</font><font COLOR="#008000">&quot;com.bdaum.aoModeling.preferences&quot;</font><font COLOR="#000080">
+</font> <font COLOR="#000080">name=</font><font COLOR="#008000">&quot;SpellChecker Preferences&quot;
+</font> <font COLOR="#000080">point=</font><font COLOR="#008000">&quot;org.eclipse.ui.preferencePages&quot;</font><font COLOR="#000080">&gt;
+</font> <font COLOR="#000080">&lt;page name=</font><font COLOR="#008000">&quot;Spelling&quot; </font><font COLOR="#000080">class=</font><font COLOR="#008000">
+</font><img src="images/tag_4.gif" height=13 width=24 align=CENTER><font COLOR="#008000"> &quot;com.bdaum.SpellChecker.preferences.DefaultSpellCheckerPreferencePage&quot;
+</font><img src="images/tag_5.gif" height=13 width=24 align=CENTER> <font COLOR="#000080">id= </font><font COLOR="#008000">&quot;com.bdaum.SpellChecker.preferences.defaultPreferences&quot;</font><font COLOR="#000080">&gt;
+</font> <font COLOR="#000080">&lt;/page&gt;
+</font> <font COLOR="#000080">&lt;/extension&gt;</font></pre>
+<pre><font COLOR="#000080"> &lt;extension id=</font><font COLOR="#008000">&quot;com.bdaum.aoModeling.properties&quot;
+</font> <font COLOR="#000080">name=</font><font COLOR="#008000">&quot;SpellChecker Properties&quot;
+</font> <font COLOR="#000080">point=</font><font COLOR="#008000">&quot;org.eclipse.ui.propertyPages&quot;</font><font COLOR="#000080">&gt;
+</font><img src="images/tag_6.gif" height=13 width=24 align=CENTER> <font COLOR="#000080">&lt;page objectClass=</font><font COLOR="#008000">&quot;org.eclipse.core.resources.IProject&quot;
+</font> <font COLOR="#000080">adaptable=</font><font COLOR="#008000">&quot;true&quot;
+</font> <font COLOR="#000080">name=</font><font COLOR="#008000">&quot;Spell Default&quot; </font><font COLOR="#000080">class=</font><font COLOR="#008000">
+</font><img src="images/tag_4.gif" height=13 width=24 align=CENTER><font COLOR="#008000"> &quot;com.bdaum.SpellChecker.preferences.DefaultSpellCheckerPreferencePage&quot;
+</font><img src="images/tag_7.gif" height=13 width=24 align=CENTER> <font COLOR="#000080">id=</font><font COLOR="#008000">&quot;com.bdaum.SpellChecker.propertyPage.project&quot;</font><font COLOR="#000080">&gt;
+</font> <font COLOR="#000080">&lt;/page&gt;
+</font> <font COLOR="#000080">&lt;/extension&gt;</font></pre>
+<p>Note, that the page identification returned by <img src="images/tag_1.gif" height=13 width=24 align=CENTER>
+ method <code>getPageId()</code> matches the <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+page identification specified in the preference page extension point. Note also, that we used the same
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> page implementation in both
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> the preference page extension point and
+<img src="images/tag_6.gif" height=13 width=24 align=CENTER> the property page extension point.
+(The <img src="images/tag_7.gif" height=13 width=24 align=CENTER>
+ identification of the property page actually may differ from the <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+preference page id.)</p>
+<table border="0">
+ <tr>
+ <td width="50%" valign="top"><img border="0" src="images/spellPreferences.GIF" width="452" height="383">
+ <p><i>Preferences page for a spell checker plug-in</i>
+ <p><i>&nbsp;</i></td>
+ </tr>
+ <tr>
+ <td width="50%" valign="top"><img border="0" src="images/spellProperties.GIF" width="452" height="365">
+ <p><i>Corresponding properties page for the same plug-in. The last group
+ of widgets&nbsp;<br>
+ is deliberately suppressed for property pages by this page implementation.</i></td>
+ </tr>
+</table>
+<h2>Retrieving overlayed preference values</h2>
+<p>Reading such overlayed preference values is a multi-stage process. First we
+must <img src="images/tag_1.gif" height=13 width=24 align=CENTER> interrogate
+the resource, if this property page uses the project settings or the workbench
+settings. If it uses the project settings, we must <img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+read the value from the resource properties, if not we fall back to the <img src="images/tag_3.gif" height=13 width=24 align=CENTER>
+values defined in the workbench preference store. Here again, we have to <img src="images/tag_4.gif" height=13 width=24 align=CENTER>
+qualify the field name with the page identification when we access the resource
+properties.</p>
+<pre><b><font COLOR="#7f0055"> public</font></b> <b><font COLOR="#7f0055">static</font></b> String getOverlayedPreferenceValue(
+ IPreferenceStore store,
+ IResource resource,
+ String pageId,
+ String name) {
+ IProject project = resource.getProject();
+ String value = <b><font COLOR="#7f0055">null</font></b>;
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">if</font></b> (useProjectSettings(project, pageId)) {
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> value = getProperty(resource, pageId, key);
+ }
+ <font COLOR="#7f0055"><b>if</b></font> (value != <b><font COLOR="#7f0055">null</font></b>)
+ <b><font COLOR="#7f0055">return</font></b> value;
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> <b><font COLOR="#7f0055">return</font></b> store.getString(key);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> private</font></b> <b><font COLOR="#7f0055">static</font></b> <b><font COLOR="#7f0055">boolean</font></b> useProjectSettings(IResource resource,
+ String pageId) {
+ String use = getProperty(
+ resource,
+ pageId,
+ FieldEditorOverlayPage.USEPROJECTSETTINGS);
+ <font COLOR="#7f0055"><b>return</b></font> <font COLOR="#2a00ff">&quot;true&quot;</font>.equals(use);
+ }</pre>
+<pre><b><font COLOR="#7f0055"> private</font></b> <b><font COLOR="#7f0055">static</font></b> String getProperty(IResource resource,
+ String pageId,
+ String key) {
+ <font COLOR="#7f0055"><b>try</b></font> {
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> <font COLOR="#7f0055"><b>return</b></font> resource.getPersistentProperty(<b><font COLOR="#7f0055">
+ new</font></b> QualifiedName(pageId, key));
+ } <b><font COLOR="#7f0055">catch</font></b> (CoreException e) {
+ }
+ <b><font COLOR="#7f0055">return</font></b> <b><font COLOR="#7f0055">null</font></b>;
+ }</pre>
+<h2>Technology transfer</h2>
+<p>What works well for field editor preferences should also work for
+&quot;normal&quot; preference pages. However, some things are different when
+creating the class <code>OverlayPage</code>, since we now extend a <code>PreferencePage</code>
+and not a <code>FieldEditorPreferencePage</code>:</p>
+<ol>
+ <li>We can directly extend the class <code>PropertyPage</code> because
+ this class is a subclass of <code>PreferencePage</code>. This saves us from
+ implementing the interface <code>IWorkbenchPropertyPage</code> with its <code>getElement()</code>
+ and <code>setElement()</code> methods.<br>
+ </li>
+ <li>We need to modify the constructors (no <code>style</code>
+ parameter required).<br>
+ </li>
+ <li>We need a different implementation for method <code>createContents()</code>.
+ Since <code>PreferencePage</code> only defines this method as an abstract
+ method, we need to implement it from scratch. We do so by creating two
+ containers in the parent composite: One for our own button group and one for
+ the contents created by subclasses. We return this second container as the
+ method's result.<br>
+ </li>
+ <li>There is no <code>addField()</code> method that we can override to
+ keep track of field editors. In fact, there are no field editors at all.
+ Consequently, we cannot rely on the knowledge encapsulated in the field
+ editors. Therefore, we drop the methods <code>addField()</code> and <code>updateFieldEditors()</code>.
+ Instead, we implement a method <code>setControlsEnabled()</code>. This
+ method walks through the whole tree of child controls created by subclasses
+ enabling or disabling them. (We spare tabbed notebooks and the like to allow
+ for user navigation.) Again, subclasses may want to override this method
+ when the enablement of controls depends on the state of other controls or on
+ the state of the application.<br>
+ </li>
+ <li>Subclasses must play it safe: If they
+ override method <code>performOk()</code> they must invoke <code>super.performOk()</code>;
+ and the implementation of <code>createContents()</code> must invoke <code>super.createContents()</code>
+ and use the composite returned by this method as container for all controls
+ created in the subclass.</li>
+</ol>
+<p>At this point we leave it with these hints. For implementation details please
+ see class <code>OverlayPage</code> in the <a href="overlayPages.zip"> source
+ code zip</a>.</p>
+<h2>Summary</h2>
+<p>We have implemented two abstract classes <code>FieldEditorOverlayPage</code>
+and <code>OverlayPage</code>. Subclasses extending these classes can act as both
+preference pages and property pages leading to an improved application
+consistency and lower maintenance cost. With only minimal modifications, already
+existing preference pages can be made by extending&nbsp; <code>FieldEditorOverlayPage</code>
+or <code>OverlayPage</code> and can then be reused in the role of property
+pages. We achieved this by implementing an abstract access layer in form of
+class <code>PropertyStore</code> that encapsulates the properties of a resource
+but behaves as a preference store. In addition, both classes <code>FieldEditorOverlayPage</code>
+and <code>OverlayPage</code> provide the additional GUI elements required by
+property pages.</p>
+<h2>Source Code</h2>
+<p>To use these classes within your own plug-in, download the <a href="overlayPages.zip">source
+ code zip</a> and import its contents of into the source folder of your Eclipse
+ project.</p>
+
+<h2>About the author </h2>
+
+<p>Berthold Daum is an independent consultant and writer based in Germany. His
+ best-selling book &quot;Java Entwicklung mit Eclipse 2&quot; (dpunkt verlag)
+ will appear in an English version as &quot;Eclipse 2 for Java Developers&quot;
+ in November 2003 (John Wiley &amp; Sons). </p>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the United States, other countries, or both.</small></p>
+
+</body>
+</html>
diff --git a/Article-Mutatis-mutandis/overlayPages.zip b/Article-Mutatis-mutandis/overlayPages.zip
new file mode 100644
index 0000000..96a8686
--- /dev/null
+++ b/Article-Mutatis-mutandis/overlayPages.zip
Binary files differ
diff --git a/Article-Online Help for 1_0/Idea.jpg b/Article-Online Help for 1_0/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Online Help for 1_0/Idea.jpg
Binary files differ
diff --git a/Article-Online Help for 1_0/final.jpg b/Article-Online Help for 1_0/final.jpg
new file mode 100644
index 0000000..1311ef4
--- /dev/null
+++ b/Article-Online Help for 1_0/final.jpg
Binary files differ
diff --git a/Article-Online Help for 1_0/final.zip b/Article-Online Help for 1_0/final.zip
new file mode 100644
index 0000000..8cb60b5
--- /dev/null
+++ b/Article-Online Help for 1_0/final.zip
Binary files differ
diff --git a/Article-Online Help for 1_0/help1.htm b/Article-Online Help for 1_0/help1.htm
new file mode 100644
index 0000000..fbe49c4
--- /dev/null
+++ b/Article-Online Help for 1_0/help1.htm
@@ -0,0 +1,475 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.73 [en] (Win98; U) [Netscape]">
+ <meta name="Author" content="Greg Adams">
+ <title>Help Part 1</title>
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+<body>
+
+<div align=right><font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2001 Object Technology International, Inc.</font></font></div>
+<div ALIGN=right><table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table></div>
+
+<h1> <img SRC="Idea.jpg" height=86 width=120></h1>
+
+<center>
+<h1>
+Help – Part 1<br>
+Contributing a little help</h1></center>
+<b>Summary</b>
+<br>The Eclipse platform’s help system defines two extension points (<tt>"contributions"
+</tt>and<tt>"contexts"</tt>)
+that allow individual plug-ins to contribute online help and context-sensitive
+help for their components. In this article we will investigate the “contributions”
+extension point and how you can use it to contribute documentation for
+your plug-in.
+<p><b>By Greg Adams, OTI and Dorian Birsan, IBM</b> <br>
+ <font size=-1>Updated May 28, 2001</font>
+<p><font size="-1">Editor's note: This article describes the help system for Eclipse
+ release 1.0. There is an <a href="../Article-Online%20Help%20for%202_0/help1.htm">updated
+ version of this article</a> for Eclipse release 2.0.</font>
+<center>
+ </center>
+<center>
+<hr size=2 width="100%" align=center></center>
+
+<h2>
+Introduction</h2>
+The Eclipse platform’s help system allows you to contribute your plug-in’s online
+help using the org.eclipse.help.contributions extension point. You can either
+contribute the online help as part of your code plug-in or provide it separately
+in its own documentation plug-in. This separation is beneficial in those situations
+where the code and documentation teams are different groups or where you want
+to reduce the coupling/dependency between the documentation and code. The platform’s
+help facilities provide you with the raw building blocks to structure and contribute
+your help. It does not dictate structure or granularity of documentation. The
+platform does however provide and control the integrated help viewers thus ensuring
+seamless integration of your documentation.
+<p>The org.eclipse.help.contributions extension point provides four elements
+through which you can contribute your help, they are:
+<ul>
+<li>
+topics</li>
+
+<li>
+infoset (also known as a book)</li>
+
+<li>
+infoview</li>
+
+<li>
+actions (also known as wiring)</li>
+</ul>
+The topics, infoset and actions contributions all specify an associated
+xml file that contains the details of the contribution. In the remainder
+of this article we will create a documentation plug-in that uses all four
+of these elements. By the time we’re done, you’ll have your first online
+help plug-in.
+<h2>
+Making the plug-in and content</h2>
+A content author supplies one or more HTML files containing the actual
+documentation. There are no restrictions imposed by the platform on the
+granularity of the HTML files. That is, the documentation authors can opt
+to use one massive HTML file, or numerous smaller granularity HTML files.
+We will start by assuming that you already have some html files that you
+want to integrate into the Eclipse platform. Let’s assume your content
+is arranged into the following directory tree.
+<blockquote><tt>doc/</tt>
+<br><tt>&nbsp;&nbsp; concepts/</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; concept1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; concept1_1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; concept1_2.html</tt>
+<br><tt>&nbsp;&nbsp; tasks/</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task2.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task3_1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task3_2.html</tt>
+<br><tt>&nbsp;&nbsp; ref/</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref2.html</tt></blockquote>
+Create a plug-in directory called org.eclipse.helparticle and place the above
+<i>doc\ </i>sub-tree into it<i>. </i>Now create an initial plugin.xml file with
+the following content:
+<blockquote><tt>&lt;?xml version="1.0"?></tt>
+<br><tt>&lt;plugin</tt>
+<br><tt>&nbsp;&nbsp; name = "Online Help Sample"</tt>
+<br><tt>&nbsp;&nbsp; id = "org.eclipse.helparticle"</tt>
+<br><tt>&nbsp;&nbsp; version = "0.9"</tt>
+<br><tt>&nbsp;&nbsp; provider-name = "Object Technology International,
+Inc."></tt>
+<br><tt>&lt;/plugin></tt></blockquote>
+To help you get started here is a zip file containing the above <a href="initialstructure.zip">initial
+plug-in structure</a>. This plug-in manifest file doesn't actually integrate anything
+yet but soon we will add our contributions to it. <br>
+&nbsp;
+<br>&nbsp;
+<h2>
+Topics &amp; HTML Content</h2>
+Now that we have our sample content files we are ready to create our <b>topics
+</b>file.
+A topics file defines the key entry points into the HTML content files
+by mapping a topic id and label to a reference in one of the HTML files.
+A topics file acts like a table of contents for a set of html content.
+Teams migrating onto the Eclipse platform can quickly reuse existing documentation
+by defining entry points into their existing documentation via the topics
+file. A plug-in can have one or more topics files. Topics files are sometimes
+referred to as navigation files since they describe how to navigate the
+html content. We have three main content areas, concepts, tasks and reference.
+Our obvious choices are one big topics file, or a topics file for each
+main content area. Keep in mind this decision is ours to make, and is not
+a decision the platform dictates to us. If we were “really” writing our
+documentation we would have a larger number of files so, with that in mind
+we will try and keep things manageable by creating a topics file for each
+of the three content areas as follows:
+
+<p class="MsoNormal"><b>topics_Tasks.xml</b>
+<blockquote><tt>&lt;topics id="tasksAll"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="plainTasks" label="Plain Stuff"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task1"
+href="doc/tasks/task1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task2"
+href="doc/tasks/task2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt>&nbsp;<tt>&nbsp;&nbsp;&nbsp;
+&lt;topic id="funTasks" label="Fun Stuff" ></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_1"
+href="doc/tasks/task3_1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_2"
+href="doc/tasks/task3_2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt>
+<br><tt>&lt;/topics></tt></blockquote>
+<b>topics_Concepts.xml</b>
+<blockquote><tt>&lt;topics id="conceptsAll"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Concept1" href="doc/concepts/concept1.html"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Concept1_1"
+href="doc/concepts/concept1_1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Concept1_2"
+href="doc/concepts/concept1_2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt> <tt>&lt;/topics></tt></blockquote>
+<b>topics_Ref.xml</b>
+<blockquote><tt>&lt;topics id="refAll"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Ref1" href="doc/ref/ref1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Ref2" href="doc/ref/ref2.html"/></tt>
+<br><tt>&lt;/topics></tt></blockquote>
+Topics are contributed as part of the <i>topics</i> container element. A <i>topic</i>
+can be a simple link to content (e.g. Task1) or a hierarchical grouping of sub-topics
+(e.g. Fun Stuff), or both (e.g. Concept1). When we start wiring these topics into
+the overall documentation web we will refer to them by their id. When used as
+a link, the argument to href is assumed to be relative to the current plug-in.
+Only topics with an id can be manipulated. We can also refer to the id associated
+with the topics element if we want to refer to all of its enclosed topic entries.
+Later we will modify the plugin.xml to add the actual contributions pointing to
+these files.
+<h2>
+Creating a book</h2>
+Now that we have our raw content and topic files it’s time to create our
+infoset. An information set (infoset) is a documentation web or book. The
+Eclipse platform can display any number of infosets. An infoset contains
+one or more infoviews. An infoview provides a high-level semantic grouping
+within the infoset. Infoviews could be used to create multiple views onto
+the document web. For example we could use them to create an integrated
+view of documentation supplied by many components, or a component based
+view. We could also use them to create separate views for getting started,
+tasks and concepts, or as we will shortly do, create one infoview to show
+them all. The term infoview is used to avoid collision/confusion with the
+term view in the platform’s user interface. Each infoview contains a collection
+of topics. Sometimes a higher-level component or product team is responsible
+for weaving together the documentation and topics supplied by a number
+of its component teams. For our purposes we’ll assume that our plug-in
+should supply both the topics and the book that integrates the topics.
+Towards the end of the article we will look at how to make your documentation
+plug-in live happily in both a component world and a product world.
+<br>&nbsp;
+<p>The following infoset has id “infoset_SampleGuide” and declares one
+infoview whose id is “view_Contents”. The id of the infoview will become
+important as we start wiring in the high level structure for the infoview,
+and ultimately wiring in the topics we defined earlier.
+<p><b>infoset_SampleGuide.xml</b>
+<blockquote><tt>&lt;infoset id="infoset_SampleGuide" label="Online Help
+Sample" href="<b>doc/splash.html</b>"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;<b>infoview</b> label="Content" id="view_Contents"
+/></tt>
+<br><tt>&lt;/infoset></tt></blockquote>
+Selecting the book called "Online Help Sample" shows one possible infoview
+called "Content". The following figure shows the eventual look of our help.
+If multiple infoviews had been declared by our xml file they would show
+up as additional "infoview tabs" alongside the "Content" tab. Notice that
+our splash page (contained in splash.html&nbsp; and declared above) is
+also displayed.&nbsp;
+<blockquote><img SRC="final.jpg" height=437 width=668></blockquote>
+
+<br>&nbsp;
+<h2>
+Wiring in the top level structure</h2>
+Next on our agenda is to define the top-level structure that a user will
+see within our “Contents” infoview. We start by creating the following
+topics file for the top-level topics:
+<p><b>topics_view_Contents.xml</b>
+<blockquote><tt>&lt;topics id="topics_view_Contents"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="conceptsRoot" label="Concepts"
+/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="tasksRoot" label="Tasks" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="funRoot" label="Fun Things" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="refRoot" label="Reference" /></tt>
+<br><tt>&lt;/topics></tt></blockquote>
+Now comes the fun part, time to “wire in” these topics into our “Contents”
+infoview. Once we’ve done that we can then proceed to wire in all of our
+other topics underneath the above top-level topics. We start by wiring
+in the top-level topics using the following <b>actions
+</b>file.
+<p><b>actions_view_Contents.xml</b>
+<blockquote><tt>&lt;actions infoview="org.eclipse.helparticle.view_Contents"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.topics_view_Contents"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.view_Contents"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt>
+<br><tt>&lt;/actions></tt></blockquote>
+The following snapshot shows what our infoset (Outline Help Sample) will
+look like as a result of wiring in these top-level topics. The title (label)
+of the infoset is only displayed in the combo box if there is more than
+one infoset.
+<blockquote>
+ <div align="left"><img SRC="toplevel.jpg" height=99 width=197></div>
+</blockquote>
+
+<h2>
+Taking a closer look at actions</h2>
+<div align="left">Before we continue let’s take a closer look at the action file
+ and the action elements it contains. The actions file contains scripting actions
+ to be performed on topics and infoviews. Currently there is only one kind of
+ action, the insert action, which is used to wire topics and views together into
+ one integrated information web. The actions are structural actions (insert)
+ and, thus, apply to a certain infoview. So, all the insert actions in an actions
+ file wire their topics into one infoview. If you want to wire into different
+ infoviews, you will need an actions file for each. The insertion points can
+ be topics or infoviews.&nbsp; A topic indicates its willingness to be an insertion
+ point by providing an id. Infoviews are required to have id's.&nbsp; Only fully
+ qualified ids are used as references. For example, the fully qualified topic
+ id of the topic &lt;topic id="conceptsRoot " label="Concepts">&nbsp; in our
+ org.eclipse.helparticle plug-in is org.eclipse.helparticle.conceptsRoot. In
+ the above actions file we took the topics element with fully qualified id "org.eclipse.helparticle.topics_viewContents"&nbsp;
+ and wired it into the infoview with id "org.eclipse.helparticle.view_Contents".
+</div>
+<p>Since the insertion points are sometimes located in other plug-ins,
+and these plug-ins may not be installed, one can specify an alternate insertion
+point. By default, if none of the choices succeed, the topic stays under
+its component hierarchy. The "to" attribute specifies the target insertion
+point. The topic specified by the "from" attribute is the topic being inserted.&nbsp;
+Followings are some possible ways to insert a topic and they are specified
+using the "<b>as</b>" attribute:
+<ul type=disc>
+<li>
+As a child of the insertion point, which is the most common. Attribute:&nbsp;
+as = "child".</li>
+
+<li>
+As the first child of the insertion point. Attribute as = "first-child".</li>
+
+<li>
+As the last child of the insertion point. Attribute as = "last-child".</li>
+
+<li>
+As the previous sibling of the insertion point (i.e., just before the insertion
+point at the same level in the navigation tree). Attribute as = "prev-sib".</li>
+
+<li>
+As the next sibling of the insertion point (i.e., just after the insertion
+point at the same level in the navigation tree). Attribute as = "next-sib".</li>
+</ul>
+Alternative insertion options can be provided. The nested insert sub-elements
+of the insert element provide these alternatives. This can be thought of as a
+"fall-back" mechanism where if an insert action fails, the nested insert action
+will be executed. Once the first choice insertion point has been satisfied, the
+other alternative insertion points are ignored. <br>
+&nbsp;
+<h2>
+Integrating our topics</h2>
+The time has come to finally integrate our topics into the top-level topics of
+the “Contents” infoview. To do this we need another actions file that we will
+call actions_All.xml (since it integrates all of our topics).
+<p><b>actions_All.xml</b>
+<blockquote><tt>&lt;actions infoview="org.eclipse.helparticle.view_Contents"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.conceptsAll"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.conceptsRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.refAll"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.refRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.plainTasks"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.tasksRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.funTasks"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.funRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt> <tt>&lt;/actions></tt></blockquote>
+Recall that we had a number of task related html files, and the structure/navigation
+of these files was defined by topics_tasks.xml as follows:
+<p><b>topics_Tasks.xml</b>
+<blockquote><tt>&lt;topics id="tasksAll"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="plainTasks" label="Plain Stuff"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task1"
+href="doc/tasks/task1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task2"
+href="doc/tasks/task2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="funTasks" label="Fun Stuff" ></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_1"
+href="doc/tasks/task3_1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_2"
+href="doc/tasks/task3_2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt>
+<br><tt>&lt;/topics></tt></blockquote>
+In the above actions file we use the insert as child action to take the topic
+with id org.eclipse.helparticle.plainTasks and insert it and its sub-topics under
+the topic with id org.eclipse.helparticle.tasksRoot
+<blockquote><tt>&lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.plainTasks"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.tasksRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; as="child"/></tt></blockquote>
+The actions file also takes some of our more entertaining tasks and inserts
+them into the “Fun Things” area of the web using the following action.
+<blockquote><tt>&lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.funTasks"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.funRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; as="child"/></tt></blockquote>
+
+<h2>
+Finishing our plugin</h2>
+Before we continue a brief recap is in order:
+<ul>
+<li>
+We started by creating our plug-in and document files.</li>
+
+<li>
+Next we created topic files to describe the structure/navigation of our
+content.</li>
+
+<li>
+We then moved up one level above content, to the wiring and integration
+of our book. To do this we created our infoset with its single Contents
+infoview.</li>
+
+<li>
+Next we created another topics file (topics_view_Contents.xml) to define
+the top-level topics.</li>
+
+<li>
+Finally we wired it all together using the action files actions_view_Contents.xml
+(to wire in the top level topics) and actions_All.xml (to wire in the bulk
+of our topics).</li>
+</ul>
+
+<p><br>The one remaining piece of work is to update our plugin.xml to actually
+contribute the action, topics, and infoset files that we created. Start
+with updating the plugin.xml to contribute our infoset:
+<blockquote><tt>&lt;extension point="org.eclipse.help.contributions"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;infoset name="infoset_SampleGuide.xml"/>&lt;/extension></tt></blockquote>
+Next we contribute the top-level topics, and the actions file that wires
+them into our infoset:
+<blockquote><tt>&lt;extension point="org.eclipse.help.contributions"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topics name="topics_view_Contents.xml"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;actions name="actions_view_Contents.xml"
+/></tt>
+<br><tt>&lt;/extension></tt></blockquote>
+Lastly we contribute the bulk of our topics and wire them in:
+<blockquote><tt>&lt;extension point="org.eclipse.help.contributions"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topics name="topics_Concepts.xml" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topics name="topics_Tasks.xml" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topics name="topics_Ref.xml" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;actions name="actions_All.xml" /></tt>
+<br><tt>&lt;/extension></tt></blockquote>
+That’s it, you’re done. Now take your plugin (click here for a <a href="final.zip">zip
+file</a> of the final plugin) and drop it into the platform’s <i>plugins</i> directory,
+start eclipse and choose Help -> Help Contents. Once you expand the topics in
+the “Contents” infoview you will see the following. <br>
+&nbsp;
+<p><img SRC="final.jpg" height=437 width=668> <br>
+ &nbsp;
+<br>&nbsp;
+<h2>
+Non-integrated components</h2>
+What if we expect our plug-in will sometimes be installed by itself, and in other
+cases it will be installed as part of a larger component or product. When deploying
+a free floating plug-in we want to ensure that our infoset is visible. When topics
+from a plug-in are integrated into a larger web it probably doesn’t make sense
+for their standalone book to show up anymore. To support this nonintegrated or
+loosely integrated documentation, a plug-in can define an infoset and associated
+actions and set their <b>standalone</b> attribute to true. This has the effect
+of executing the inserts only when those topics have never been contributed anywhere
+else and only display the infoset if it is not empty. In other words, this behaves
+as: "if this is an independent plug-in, and there are no topics contributed to
+some well-known infoset, then insert the documentation into a standalone info
+set". Empty standalone infosets are not shown. This really says that if the topics
+contributed by the plug-in are inserted into well-known infosets, then the standalone
+actions did not insert anything in the standalone infoset, so just ignore this
+empty infoset. Setting standalone attributes on actions and infosets is useful
+when providing a "Catch all" scenario, when documentation cannot be contributed
+to a well-known infoset but the plug-in documentation should still appear somewhere.
+To support standalone mode we need to make the following additions to our infoset
+and action xml files. The addition is marked in bold.
+<p>infoset_Guide.xml
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;infoset id="infoset_Guide"label="Online
+Help Sample" href="doc/splash.html"
+<b>standalone="true"</b>></tt>
+<p>actions_All.xml
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;actions infoview="org.eclipse.platform.doc.user.view_Contents"
+<b>standalone="true"</b>></tt>
+<p>actions_view_Contents.xml
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;actions infoview="org.eclipse.platform.doc.user.view_Contents"
+<b>standalone="true"</b>></tt>
+<p>Now if someone includes our topics our actions will not be used, and
+consequently our infoset will be empty and not show up.
+<br>&nbsp;
+<h2> Externalizing Strings in your XML files</h2>
+Plugin.xml files externalize their strings by replacing the string with
+a key (e.g. %pluginName) and creating an entry in the plugin.properties
+file of the form:
+<br><tt>&nbsp;&nbsp;&nbsp; pluginName = “Online Help Sample Plugin”</tt>
+<br>The contribution XML files are externalized using a similar approach.
+To externalize &lt;topic id="plainTasks" label="Plain Stuff"> we replace
+its label with a key %plainStuff . Our topic now looks like:
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="plainTasks" label="%plainStuff"></tt>
+<br>Create an entry in the document.properties file containing the entry:
+<br><tt>&nbsp;&nbsp;&nbsp; plainStuff = Plain Stuff</tt>
+<br>The help system will use document.properties when looking up strings
+externalized by our online help contributions.
+<br>&nbsp;
+<h2>
+Server and zip files</h2>
+The platform utilizes its own documentation server to provide the actual web pages
+from within the document web.&nbsp; A custom server allows the platform to handle
+the wide variety of web browsers in a browser independent way while also providing
+plugin aware support. The platform's help server allows the documentation to also
+be deliver in a zip file thus avoiding problems that may result when a large number
+of files are present. In our example plugin we created a sub-directory called
+"doc". Alternatively we could have placed our html files into a zip file called
+"doc.zip". <br>
+&nbsp;
+<h2>
+Conclusions</h2>
+We have seen how we can use the infoset, infoview to declare books the
+user can see. We then used the actions contribution and the topics contribution
+to declare and integrate our topics. The platform’s mechanisms can be used
+to integrate new documentation, or to quickly wire in existing html based
+documentation without rewriting it. The mechanisms allow you to create
+multiple different views onto your documentation web. In our plug-in we
+only created a single infoview but additional infoviews could easily be
+created. Component documentation can either be written to be a standalone
+book, or optionally marked such that if it is integrated into a larger
+document web, the individual component book will automatically be hidden.
+Lastly, we observed that the platform provides the building blocks for
+doc integration but does not set out any style or structuring guidelines.
+<br>&nbsp;
+<br>&nbsp;
+</body>
+</html>
diff --git a/Article-Online Help for 1_0/initialstructure.zip b/Article-Online Help for 1_0/initialstructure.zip
new file mode 100644
index 0000000..8cb60b5
--- /dev/null
+++ b/Article-Online Help for 1_0/initialstructure.zip
Binary files differ
diff --git a/Article-Online Help for 1_0/toplevel.jpg b/Article-Online Help for 1_0/toplevel.jpg
new file mode 100644
index 0000000..aea95df
--- /dev/null
+++ b/Article-Online Help for 1_0/toplevel.jpg
Binary files differ
diff --git a/Article-Online Help for 2_0/Idea.jpg b/Article-Online Help for 2_0/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Online Help for 2_0/Idea.jpg
Binary files differ
diff --git a/Article-Online Help for 2_0/book.jpg b/Article-Online Help for 2_0/book.jpg
new file mode 100644
index 0000000..9f85119
--- /dev/null
+++ b/Article-Online Help for 2_0/book.jpg
Binary files differ
diff --git a/Article-Online Help for 2_0/books.jpg b/Article-Online Help for 2_0/books.jpg
new file mode 100644
index 0000000..8c1c001
--- /dev/null
+++ b/Article-Online Help for 2_0/books.jpg
Binary files differ
diff --git a/Article-Online Help for 2_0/expanded_book.jpg b/Article-Online Help for 2_0/expanded_book.jpg
new file mode 100644
index 0000000..dee5364
--- /dev/null
+++ b/Article-Online Help for 2_0/expanded_book.jpg
Binary files differ
diff --git a/Article-Online Help for 2_0/final.zip b/Article-Online Help for 2_0/final.zip
new file mode 100644
index 0000000..1d87cf3
--- /dev/null
+++ b/Article-Online Help for 2_0/final.zip
Binary files differ
diff --git a/Article-Online Help for 2_0/final_ja_JP.zip b/Article-Online Help for 2_0/final_ja_JP.zip
new file mode 100644
index 0000000..8c8d03b
--- /dev/null
+++ b/Article-Online Help for 2_0/final_ja_JP.zip
Binary files differ
diff --git a/Article-Online Help for 2_0/help1.htm b/Article-Online Help for 2_0/help1.htm
new file mode 100644
index 0000000..e5131a1
--- /dev/null
+++ b/Article-Online Help for 2_0/help1.htm
@@ -0,0 +1,358 @@
+<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+
+
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=iso-8859-1">
+
+ <meta name="Author" content="Greg Adams">
+ <meta name="Author" content="Dorian Birsan">
+
+ <title>Help Part 1</title>
+
+ <link rel="stylesheet" href="../../default_style.css">
+</head>
+ <body>
+
+<div align="right"><font face="Times New Roman, Times, serif"><font
+ size="-1"> Copyright &copy; 2001, 2003 Object Technology International, Inc.</font></font></div>
+
+<div align="right">
+<table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tbody>
+ <tr>
+ <td align="left" valign="top" colspan="2" bgcolor="#0080c0"><b><font
+ face="Arial,Helvetica"><font color="#ffffff"> &nbsp;Eclipse Corner Article</font></font></b></td>
+ </tr>
+
+ </tbody>
+</table>
+ </div>
+
+<h1><img src="Idea.jpg" height="86" width="120">
+ </h1>
+
+<center>
+<h1> Help &#8211; Part 1<br>
+ Contributing a little help</h1>
+ </center>
+ <b>Summary</b><br>
+ The Eclipse Platform&#8217;s help system defines two extension points (<code>
+ "toc" </code>and<code> "contexts"</code>) that allow individual plug-ins to
+contribute online help and context-sensitive help for their components.
+In this article we will investigate the <code>"toc"</code> extension point and how
+you can use it to contribute documentation for your plug-in.
+<p><b>By Greg Adams, OTI and Dorian Birsan, IBM</b><br>
+ <font size="-1">Updated August 9, 2002</font></p>
+<p>Editor's note: This article describes the help system for Eclipse release 2.1,
+ which differs in minor ways from the previous Eclipse release. If you are working
+ with Eclipse release 1.0, you should consult <a href="../Article-Online%20Help%20for%201_0/help1.htm">the
+ original version of this article</a>.</p>
+<center>
+ <hr size="2" width="100%" align="center"></center>
+
+<h2> Introduction</h2>
+ The Eclipse Platform&#8217;s help system allows you to contribute your plug-in&#8217;s
+ online help using the org.eclipse.help.toc extension point. You can either
+ contribute the online help as part of your code plug-in or provide it
+separately in its own documentation plug-in. This separation is beneficial
+in those situations where the code and documentation teams are different
+groups or where you want to reduce the coupling/dependency between the
+documentation and code. The Platform&#8217;s help facilities provide you with
+the raw building blocks to structure and contribute your help without
+dictating the structure or granularity of documentation. The Platform
+does however provide and control the integrated help viewers thus ensuring
+ seamless integration of your documentation. <br>
+<br>
+The org.eclipse.help.toc contribution specifies one or more associated
+ XML files that contain the structure of your help and its integration with
+help contributed by other plug-ins. In the remainder of this article we
+will create a documentation plug-in, so by the time your're done you can
+browse your own documentation using the Eclipse Help System.
+<h2> Making the plug-in and content</h2>
+ A content author supplies one or more HTML files containing the actual
+ documentation. There are no restrictions imposed by the Platform on the
+granularity of the HTML files or on their content. We will start by assuming
+that you already have some HTML files that you want to integrate into the
+Eclipse Platform. Let&#8217;s assume your content is arranged into the following
+directory tree.
+<blockquote><tt>html/</tt><tt>&nbsp;&nbsp; <br>
+ &nbsp; &nbsp;overview.html</tt><br>
+ <tt>&nbsp;&nbsp; concepts/</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; concept1.html</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; concept1_1.html</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; concept1_2.html</tt><br>
+ <tt>&nbsp;&nbsp; tasks/</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task1.html</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task2.html</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task3_1.html</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task3_2.html</tt><br>
+ <tt>&nbsp;&nbsp; ref/</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref1.html</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref2.html</tt></blockquote>
+ Create a plug-in directory called org.eclipse.helparticle and place
+ the above <code>html/</code> sub-tree into it. Now create an initial
+plugin.xml file with the following content:
+<blockquote><tt>&lt;?xml version="1.0"?&gt;</tt><br>
+ <tt>&lt;plugin</tt><br>
+ <tt>&nbsp;&nbsp; name = "Online Help Sample"</tt><br>
+ <tt>&nbsp;&nbsp; id = "org.eclipse.helparticle"</tt><br>
+ <tt>&nbsp;&nbsp; version = "1.0"</tt><br>
+ <tt>&nbsp;&nbsp; provider-name = "Eclipse.org&gt;</tt><br>
+ <tt>&lt;/plugin&gt;</tt></blockquote>
+ To help you get started here is a zip file containing the above <a
+ href="initialstructure.zip"> initial plug-in structure</a> . This
+plug-in manifest file doesn't actually integrate anything yet but soon
+we will add our contributions to it. <br>
+ &nbsp; <br>
+ &nbsp;
+<h2> Topics &amp; HTML Content</h2>
+ Now that we have our sample content files we are ready to create our
+ <b> toc </b>file. A toc file defines the key entry points into the
+HTML content files by defining labeled topics mapped to the&nbsp; individual
+HTML files. A toc file acts like a table of contents for a set of HTML content.
+Teams migrating onto the Eclipse Platform can quickly reuse existing HTML
+documentation by defining entry points into their existing documentation
+via the toc file. A plug-in can have one or more toc files. Toc files are
+sometimes referred to as navigation files since they describe how to navigate
+the HTML content. We have three main content areas, concepts, tasks and reference.
+Our obvious choices are one big toc file, or a toc file for each main content
+area. Keep in mind this decision is ours to make, and is not a decision
+the Platform dictates to us. If we were &#8220;really&#8221; writing our documentation
+we would have a larger number of files so, with that in mind we will try
+and keep things manageable by creating a toc file for each of the three
+content areas as follows:
+<p class="MsoNormal"><b>toc_Tasks.xml</b></p>
+
+<blockquote><tt>&lt;toc label="Tasks"&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Plain Stuff"&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task1"
+ href="html/tasks/task1.html"/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task2"
+ href="html/tasks/task2.html"/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;/topic&gt;</tt>&nbsp;<tt>&nbsp;&nbsp;&nbsp;
+ <br>
+ &nbsp; &nbsp; &lt;topic label="Fun Stuff" &gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_1"
+ href="html/tasks/task3_1.html"/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_2"
+ href="html/tasks/task3_2.html"/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;/topic&gt;</tt><br>
+ <tt>&lt;/toc&gt;</tt></blockquote>
+ <b>toc_Concepts.xml</b>
+<blockquote><tt>&lt;toc label="Concepts"&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Concept1" href="html/concepts/concept1.html"&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Concept1_1"
+ href="html/concepts/concept1_1.html"/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Concept1_2"
+ href="html/concepts/concept1_2.html"/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;/topic&gt;</tt><tt><br>
+ &lt;/toc&gt;</tt></blockquote>
+ <b>toc_Ref.xml</b>
+<blockquote><tt>&lt;toc label="Refs"&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Ref1" href="html/ref/ref1.html"/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Ref2" href="html/ref/ref2.html"/&gt;</tt><br>
+ <tt>&lt;/toc&gt;</tt></blockquote>
+ Topics are contributed as part of the <code>&lt;toc&gt;</code> container element.
+ A <code>&lt;topic&gt;</code> can be a simple link to content (e.g. Task1)
+ or a hierarchical grouping of sub-topics (e.g. Fun Stuff), or both (e.g.
+ Concept1). When used as a link, the argument to href is assumed to be
+relative to the current plug-in. Later we will modify the plugin.xml to
+add the actual contributions consisting of these files. Notice that the
+hierarchical structure of topics is not the same as the file system structure:
+all the "Concepts" topics files in one directory, but the table of contents
+nests them differently.
+
+<h2> Creating a book</h2>
+ Now that we have our raw content and toc files it&#8217;s time to create
+our book. A book is just table of contents. In fact, we could make a book
+out of each of the three toc files above, but we will treat them as sections
+of a larger book instead. So, we will create another toc file that defines
+the main sections of the book and will link the three toc files above to
+create a larger table of contents (our book).<br>
+ <br>
+ <b>book.xml</b>
+<blockquote><tt>&lt;toc label="Online Help Sample" &nbsp;topic="html/book.html"&gt;</tt><br>
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <tt>&lt;topic label="Overview"
+ href="html/overview.html"/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Concepts"&gt;</tt><br>
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
+ <tt>&lt;<b>link toc="toc_Concepts.xml"/&gt;</b></tt><br>
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <tt>&lt;/topic&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Tasks"&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;<b>link toc="toc_Tasks.xml</b>"/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;/topic&gt;</tt><br>
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <tt>&lt;topic label="Reference"&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </tt><tt>&lt;<b>link
+ toc="toc_Ref.xml"</b>/&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;/topic&gt;</tt><br>
+ <tt>&lt;/toc&gt;</tt></blockquote>
+ The Eclipse Platform can display any number of books/tables of contents.
+ Each table of contents contains a collection of topics. Sometimes a higher-level
+ component or product team is responsible for weaving together the documentation
+ and topics supplied by a number of its component teams. For our purposes
+ we&#8217;ll assume that our plug-in should supply both the topics and the book
+ that integrates the topics. Towards the end of the article we will look
+at how to make your documentation plug-in live happily in both a component
+world and a product world. <br>
+ The following figure shows the book called "Online Help Sample" in
+the list of &nbsp;all available books.<br>
+ <br>
+
+<blockquote><img src="books.jpg" alt="books" width="677" height="505"
+ border="0">
+ <br>
+ </blockquote>
+ <br>
+
+<h2> Finishing our plug-in</h2>
+
+<p><br>
+ The one remaining piece of work is to update our plugin.xml to actually
+ contribute the toc files that we created. Start with updating the plugin.xml
+ to contribute our book. The important thing here is to define this table
+ of contents as a primary <code>&lt;toc&gt;</code>.</p>
+
+<blockquote><tt>&lt;extension point="org.eclipse.help.toc"&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;toc file="book.xml" <b>primary="true"</b>
+ /&gt;<br>
+ &lt;/extension&gt;<br>
+ </tt></blockquote>
+ Next we contribute the section toc files, and the important thing
+here is that primary is not set, so its default value (false) gets picked
+up:
+
+<blockquote><tt>&lt;extension point="org.eclipse.help.toc"&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;toc file="toc_Concepts.xml"
+ /&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;toc file="toc_Tasks.xml" /&gt;</tt><br>
+ <tt>&nbsp;&nbsp;&nbsp; &lt;toc file="toc_Ref.xml" /&gt;</tt><br>
+ <tt>&lt;/extension&gt;</tt></blockquote>
+ That&#8217;s it, you&#8217;re done. Now take your plug-in (click here for a <a
+ href="final.zip"> zip file</a> of the final plug-in) and drop it
+into the Platform&#8217;s <i>plugins</i> directory, start Eclipse and choose
+Help -&gt; Help Contents. Once you select the Online Help Sample and expand
+the topics&nbsp; you will see the following. <br>
+ &nbsp;
+ <br>
+
+<blockquote><img src="expanded_book.jpg" alt="expanded book" width="631"
+ height="520">
+ &nbsp; &nbsp;</blockquote>
+
+<p><br>
+ Before we continue a brief recap is in order: </p>
+
+<ul>
+ <li> We started by creating our plug-in and document
+ files.</li>
+ <li> Next we created toc files to describe the structure/navigation
+ of our content.</li>
+ <li>We then created the toc file for the book and linked
+ the other toc files as sections of the book.</li>
+ <li>Finally we &nbsp;contributed all the files in the
+ plugin.xml in the org.eclipse.help.toc extension point.<br>
+ </li>
+
+</ul>
+
+<p>&nbsp; &nbsp;</p>
+
+<h2>Integration of Tables of Contents</h2>
+
+<div align="left">In our example we defined four tables of contents, of which
+one was viewed as the book, the other three as sections of the book. Since
+the book is aware of what sections to link we call this a top-down integration.
+It is possible to do it the other way around, i.e. bottom-up integration,
+where the sections specify which book (or section) to link to. A table of
+contents indicates its willingness to allow others to link to by providing
+anchors (&lt;anchor id=..."/&gt;) at the desired linking points.<br>
+ Most often a plug-in defines a primary table of contents to which other plug-ins
+integrate their own table of contents. Tables of contents that are not primary
+or are not (directly or indirectly) integrated into other primary tables of
+contents are discarded from the final help navigation.<br>
+ Linking is specified by using the fully qualified reference to a table of
+contents, such as<br>
+
+<ul>
+ <li>top-down:&nbsp; &lt;link toc="../the_other_plugin_id/path/to/toc.xml"
+/&gt; or</li>
+ <li>bottom-up: &nbsp;&lt;toc link_to="../the_other_plugin_id/path/to/toc.xml#anchor_id"/&gt;<br>
+ </li>
+
+</ul>
+ </div>
+
+<p>Since the participating tables of contents are sometimes located in other
+plug-ins, and these plug-ins may not be installed, it is possible that some
+tables of contents remain unintegrated.<br>
+ What if we expect our plug-in will sometimes be installed by itself, and
+ in other cases it will be installed as part of a larger component or product.
+ When deploying a free floating plug-in we want to ensure that our book is
+visible. When topics from a plug-in are integrated into a larger web it
+probably doesn&#8217;t make sense for their standalone book to show up anymore.
+ To support this nonintegrated or loosely integrated documentation, a plug-in
+ can define a table of contents as a book by setting its <b>primary</b>
+ attribute to true (inside plugin.xml) and having a <b>link_to </b>attribute
+pointing to the desired anchor in the larger web. This has the effect of the
+table of contents appearing as a book when the plug-in defining the anchor
+is not installed, and appearing as a section of the target book when the plug-in
+defining the anchor is installed.<br>
+<br>
+ </p>
+
+<h2>Localization</h2>
+ Plugin manifest files externalize their strings by replacing the string
+with a key (e.g. %pluginName) and creating an entry in the plugin.properties
+file of the form: <br>
+ <tt>&nbsp;&nbsp;&nbsp; pluginName = &#8220;Online Help Sample
+ Plugin&#8221;</tt><br>
+ <br>
+Strings from the contribution XML files and the topic HTML files are not
+externalized. The toc XML files and the HTML documentation must be translated
+and packaged in the appropriate NL directory structure or in an NL fragment,
+ making sure files do not change their names. The NL directory structure
+inside a plug-in is <br>
+<br>
+<tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; myplugin/<br>
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nl/<br>
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <em>langCode</em>/<br>
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
+<em>countryCode</em>/<br>
+</tt>&nbsp; <br>
+Here is how the plug-in with Japanese documentation is <a href="final_ja_JP.zip">packaged</a> (note: the files are not translated,
+just packaged in the appropriate location).
+
+<h2> Server and zip files</h2>
+ The Platform utilizes its own help server to provide the
+actual web pages from within the document web.&nbsp; A help server
+allows the Platform to handle the wide variety of web browsers in a browser
+independent way while also providing plug-in aware support. The Platform's
+help server allows the documentation to also be packaged in zip files
+thus avoiding problems that may result when a large number of files are
+present. In our example, we put the HTML files in subdirectories of the plug-in directory.
+Alternatively, we could have placed them in a .zip file, called doc.zip, in the plug-in directory,
+maintaining the directory structure underneath. In general, the recommended way is to actually zip all the documentation.
+Here is how the plug-in is <a href="zipped_plugin.zip">packaged.</a><br>
+ &nbsp;
+
+<h2> Conclusions</h2>
+ We have seen how we can use the tables of contents to declare books
+the user can see. We then used the linking mechanism to integrate our topics.
+The Platform&#8217;s mechanisms can be used to integrate new documentation, or
+to quickly wire in existing HTML based documentation without rewriting
+it. The mechanisms allow you to create multiple different views/books onto
+your documentation web. In our plug-in we only created a single book but
+additional books could easily be created. Lastly, we observed that the Platform
+provides the building blocks for documentation integration, provides minimal packaging guidelines,
+and lets the documentation authors have full control over structuring their HTML files. <br>
+ &nbsp; <br>
+ &nbsp;
+ <br>
+ <br>
+</body>
+</html>
+
+<!-- ZoneLabs Popup Blocking Insertion -->
+<script language='javascript'>postamble();</script>
diff --git a/Article-Online Help for 2_0/initialstructure.zip b/Article-Online Help for 2_0/initialstructure.zip
new file mode 100644
index 0000000..e0e8b7d
--- /dev/null
+++ b/Article-Online Help for 2_0/initialstructure.zip
Binary files differ
diff --git a/Article-Online Help for 2_0/zipped_plugin.zip b/Article-Online Help for 2_0/zipped_plugin.zip
new file mode 100644
index 0000000..c3d8f86
--- /dev/null
+++ b/Article-Online Help for 2_0/zipped_plugin.zip
Binary files differ
diff --git a/Article-PDE-Automation/NoCVSConnStackTrace.txt b/Article-PDE-Automation/NoCVSConnStackTrace.txt
new file mode 100644
index 0000000..217ee7c
--- /dev/null
+++ b/Article-PDE-Automation/NoCVSConnStackTrace.txt
@@ -0,0 +1,243 @@
+D:\java\rdt-ssh2\org.rubypeople.rdt.build\bootstrap\customTargets.xml:88: Could
+not create \tmp\preFetch
+ at org.apache.tools.ant.ProjectHelper.addLocationToBuildException(Projec
+tHelper.java:539)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:388)
+ at org.apache.tools.ant.taskdefs.CallTarget.execute(CallTarget.java:106)
+
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRu
+nner.java:635)
+ at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRu
+nner.java:539)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
+ at java.lang.reflect.Method.invoke(Unknown Source)
+ at org.eclipse.ant.core.AntRunner.run(AntRunner.java:488)
+ at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformAct
+ivator.java:335)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja
+va:273)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja
+va:129)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
+ at java.lang.reflect.Method.invoke(Unknown Source)
+ at org.eclipse.core.launcher.Main.basicRun(Main.java:185)
+ at org.eclipse.core.launcher.Main.run(Main.java:704)
+ at org.eclipse.core.launcher.Main.main(Main.java:688)
+Caused by: D:\eclipse\eclipse-3.0.1\plugins\org.eclipse.pde.build_3.0.1\scripts\
+build.xml:46: The following error occurred while executing this line:
+D:\java\rdt-ssh2\org.rubypeople.rdt.build\bootstrap\customTargets.xml:88: Could
+not create \tmp\preFetch
+ at org.apache.tools.ant.ProjectHelper.addLocationToBuildException(Projec
+tHelper.java:539)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:388)
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:386)
+ ... 23 more
+Caused by: D:\java\rdt-ssh2\org.rubypeople.rdt.build\bootstrap\customTargets.xml
+:88: Could not create \tmp\preFetch
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:227)
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:178)
+ at org.apache.tools.ant.taskdefs.Touch.execute(Touch.java:160)
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:386)
+ ... 29 more
+Caused by: java.io.FileNotFoundException: \tmp\preFetch (The system cannot find
+the path specified)
+ at java.io.FileOutputStream.open(Native Method)
+ at java.io.FileOutputStream.<init>(Unknown Source)
+ at java.io.FileOutputStream.<init>(Unknown Source)
+ at org.apache.tools.ant.util.FileUtils.createNewFile(FileUtils.java:1160
+)
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:225)
+ ... 37 more
+--- Nested Exception ---
+D:\eclipse\eclipse-3.0.1\plugins\org.eclipse.pde.build_3.0.1\scripts\build.xml:4
+6: The following error occurred while executing this line:
+D:\java\rdt-ssh2\org.rubypeople.rdt.build\bootstrap\customTargets.xml:88: Could
+not create \tmp\preFetch
+ at org.apache.tools.ant.ProjectHelper.addLocationToBuildException(Projec
+tHelper.java:539)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:388)
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:386)
+ at org.apache.tools.ant.taskdefs.CallTarget.execute(CallTarget.java:106)
+
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRu
+nner.java:635)
+ at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRu
+nner.java:539)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
+ at java.lang.reflect.Method.invoke(Unknown Source)
+ at org.eclipse.ant.core.AntRunner.run(AntRunner.java:488)
+ at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformAct
+ivator.java:335)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja
+va:273)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja
+va:129)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
+ at java.lang.reflect.Method.invoke(Unknown Source)
+ at org.eclipse.core.launcher.Main.basicRun(Main.java:185)
+ at org.eclipse.core.launcher.Main.run(Main.java:704)
+ at org.eclipse.core.launcher.Main.main(Main.java:688)
+Caused by: D:\java\rdt-ssh2\org.rubypeople.rdt.build\bootstrap\customTargets.xml
+:88: Could not create \tmp\preFetch
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:227)
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:178)
+ at org.apache.tools.ant.taskdefs.Touch.execute(Touch.java:160)
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:386)
+ ... 29 more
+Caused by: java.io.FileNotFoundException: \tmp\preFetch (The system cannot find
+the path specified)
+ at java.io.FileOutputStream.open(Native Method)
+ at java.io.FileOutputStream.<init>(Unknown Source)
+ at java.io.FileOutputStream.<init>(Unknown Source)
+ at org.apache.tools.ant.util.FileUtils.createNewFile(FileUtils.java:1160
+)
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:225)
+ ... 37 more
+--- Nested Exception ---
+D:\java\rdt-ssh2\org.rubypeople.rdt.build\bootstrap\customTargets.xml:88: Could
+not create \tmp\preFetch
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:227)
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:178)
+ at org.apache.tools.ant.taskdefs.Touch.execute(Touch.java:160)
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:386)
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:386)
+ at org.apache.tools.ant.taskdefs.CallTarget.execute(CallTarget.java:106)
+
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRu
+nner.java:635)
+ at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRu
+nner.java:539)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
+ at java.lang.reflect.Method.invoke(Unknown Source)
+ at org.eclipse.ant.core.AntRunner.run(AntRunner.java:488)
+ at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformAct
+ivator.java:335)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja
+va:273)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja
+va:129)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
+ at java.lang.reflect.Method.invoke(Unknown Source)
+ at org.eclipse.core.launcher.Main.basicRun(Main.java:185)
+ at org.eclipse.core.launcher.Main.run(Main.java:704)
+ at org.eclipse.core.launcher.Main.main(Main.java:688)
+Caused by: java.io.FileNotFoundException: \tmp\preFetch (The system cannot find
+the path specified)
+ at java.io.FileOutputStream.open(Native Method)
+ at java.io.FileOutputStream.<init>(Unknown Source)
+ at java.io.FileOutputStream.<init>(Unknown Source)
+ at org.apache.tools.ant.util.FileUtils.createNewFile(FileUtils.java:1160
+)
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:225)
+ ... 37 more
+--- Nested Exception ---
+java.io.FileNotFoundException: \tmp\preFetch (The system cannot find the path sp
+ecified)
+ at java.io.FileOutputStream.open(Native Method)
+ at java.io.FileOutputStream.<init>(Unknown Source)
+ at java.io.FileOutputStream.<init>(Unknown Source)
+ at org.apache.tools.ant.util.FileUtils.createNewFile(FileUtils.java:1160
+)
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:225)
+ at org.apache.tools.ant.taskdefs.Touch.touch(Touch.java:178)
+ at org.apache.tools.ant.taskdefs.Touch.execute(Touch.java:160)
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:386)
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:386)
+ at org.apache.tools.ant.taskdefs.CallTarget.execute(CallTarget.java:106)
+
+ at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
+ at org.apache.tools.ant.Task.perform(Task.java:364)
+ at org.apache.tools.ant.Target.execute(Target.java:341)
+ at org.apache.tools.ant.Target.performTasks(Target.java:369)
+ at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
+ at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRu
+nner.java:635)
+ at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRu
+nner.java:539)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
+ at java.lang.reflect.Method.invoke(Unknown Source)
+ at org.eclipse.ant.core.AntRunner.run(AntRunner.java:488)
+ at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformAct
+ivator.java:335)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja
+va:273)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja
+va:129)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
+ at java.lang.reflect.Method.invoke(Unknown Source)
+ at org.eclipse.core.launcher.Main.basicRun(Main.java:185)
+ at org.eclipse.core.launcher.Main.run(Main.java:704)
+ at org.eclipse.core.launcher.Main.main(Main.java:688)
+
+Total time: 14 seconds \ No newline at end of file
diff --git a/Article-PDE-Automation/automation.html b/Article-PDE-Automation/automation.html
new file mode 100644
index 0000000..e18d553
--- /dev/null
+++ b/Article-PDE-Automation/automation.html
@@ -0,0 +1,1568 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+ <head>
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+
+ <title>Build and Test Automation for plug-ins and features</title>
+ <link type="text/css" rel="stylesheet" href="../default_style.css">
+ <link type="text/css" rel="stylesheet" href="automation_style.css">
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <div align="right">
+ &nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2005 Markus Barchfeld</font>
+
+ <table border="0" cellpadding="2" cellspacing="0" width="100%">
+ <tbody>
+ <tr>
+ <td colspan="2" align="left" bgcolor="#0080c0" valign="top">
+ <b><font face="Arial,Helvetica"><font color="#ffffff">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div align="left">
+ <h1><img src="../images/Idea.jpg" align="middle" height="86" width=
+ "120"></h1>
+ </div>
+
+ <p>&nbsp;</p>
+
+ <h1 align="center">Build and Test Automation for plug-ins and features</h1>
+
+ <blockquote>
+ <p><b>Summary</b><br>
+ Eclipse offers the possibility to build plug-ins automatically outside
+ the Eclipse IDE, which is called "headless build". Eclipse itself is
+ built headless and since Eclipse is an assembly of plug-ins, this feature
+ is also available for any other plug-in. Although the set up of automatic
+ building and testing requires only a couple of files, it can be tedious
+ work to do nonetheless. This article shares the experiences and lessons
+ learned while setting up automatic building and testing for an
+ Open-Source Eclipse plug-in called RDT, Ruby Development Tools.</p>
+
+ <p><b>By Markus Barchfeld, Zuehlke Engineering</b><br>
+ <font size="-1">May 29, 2005</font></p>
+ </blockquote>
+ <hr width="100%">
+
+ <h3>Environment</h3>
+
+ <p>All the techniques, examples and screen shots covered in this article
+ refer to Eclipse 3.0. If you want to follow the examples, you will need an
+ Eclipse 3.0.x installation. They might work with Eclipse 3.1 as well, but
+ it is untested.</p>
+
+ <p>The first part of this article gives an overview of the building steps
+ and artifacts of the headless build and introduces the required files to
+ build RDT as example. The second part shows how the Eclipse Test Framework
+ can be leveraged to extend the automatic build by running a suite of test
+ cases on the built plug-ins.</p>
+
+ <h2>Part 1 - Automated Build</h2>
+
+ <h3>Build a feature using PDE GUI Tools</h3>
+
+ <p>Starting the development of a plug-in is quite easy with the PDE
+ environment. There are tutorials and examples available which create sample
+ plug-in projects in the workspace. Compilation is done automatically from
+ the IDE and running the project can be easily achieved with starting a
+ runtime workbench, thanks to the self hosting feature of Eclipse.</p>
+
+ <p>For deployment you need to create a zip file which contains at least the
+ plugin.xml and a jar file with the classes of the plug-in. The inclusion of
+ further files (e.g. html files, images) can be controlled with the
+ build.properties file, the PDE (Plug-in Development Environment) provides
+ the "Build Properties Editor" for convenient editing of the file. <a href=
+ "#pdeHelpBuildProperties">[1]</a> explains the content of build.properties.
+ Fig. 1 shows the menu entry for the creation of an Ant build file. The
+ build file will be called build.xml and be located in the same directory as
+ the plugin.xml. The build file creation can be controlled with
+ build.properties. Some of the properties are described in <a href=
+ "#pdeHelpGenAnt">[2]</a>, see also Fig. 5. If you have the need to
+ customize the build process beyond the possibilities of build.properties, a
+ custom build file can be provided. Of course, the custom build file must
+ provide the same "interface" as the generated build file has, i.e. there
+ are some mandatory targets, which are explained in <a href=
+ "#usingPDEBuild">[12]</a>.</p>
+
+ <div class="figure">
+ <img style="width: 441px; height: 113px;" alt="Create Ant Build File"
+ src="createAntBuildFile.png">
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 1</span>. Create Ant Build file<br>
+ </div>
+ </div>
+ <br>
+ <br>
+
+
+ <p>The simplest method of deployment is to choose a zip file as the
+ deliverable and then to unzip the build output into the plugins directory
+ of your target Eclipse installation. More sophisticated deployment options
+ are update sites and product extensions. If the project grows then you may
+ to split it up into several plug-in projects, at least plug-in projects
+ which contain GUI components and Core plug-in projects which do not contain
+ GUI components. They can still be built and deployed separately, but having
+ an Eclipse feature provides additional advantages and so you probably want
+ to wrap up the plug-ins with a feature project.</p>
+
+ <p>Fig. 2 shows the Feature Manifest Editor. The Export... button opens the
+ Feature Export Dialog (Fig. 3) with which you can create the deliverable:
+ either a single zip file or the file structure for an update site. Behind
+ the scenes the feature build process just builds every contained plug-in as
+ described above and then collects the results. All the generated build
+ files are temporary and will be deleted after the build has finished. The
+ build file generation for every contained plug-in works in exactly the same
+ way as if called from the "Create Ant Build File" menu entry, which also
+ means that the build.properties file of every plug-in is considered in the
+ same way as if the plug-in would be built standalone.</p>
+
+ <p>Additionally there is a build.xml file created for the feature project.
+ Like the plug-ins build file, the build.xml for the feature can be created
+ with the PDE Tools-&gt;Create Ant Build File context menu on the
+ feature.xml file. Similar to the plug-ins, there is a build.properties file
+ for the feature which can be used to customize the build process. E.g: the
+ files you choose to include into a binary build are defined in the
+ bin.includes property in build.properties. Some of the properties of
+ build.properties can be conveniently set with the Feature Manifest Editor.
+ E.g the bin.includes property can be assembled on the "Build" tab with a
+ tree control and check boxes.</p>
+
+ <p>Although the Feature Export Dialog allows storing the build-action in a
+ single build script, it is not yet the solution for a fully automated build
+ process, because this script can not be run outside of an Eclipse
+ workbench. Its purpose is to save the settings chosen in the Feature Export
+ Dialog and conveniently rerun the same export function again by choosing
+ Run-&gt;Ant Build (<a href="#bugsHeadlessInvokation">[3]</a>). For building
+ outside of Eclipse, PDE provides some Ant tasks which are explained in <a
+ href="#pdeHelpGenCommandLine">[4]</a>. But In order to use them you don't
+ have to create Ant scripts from scratch. There is already an infrastructure
+ for headless builds, which can be leveraged.</p>
+
+ <div class="figure">
+ <img src="featureManifestEditor.png" height="421" width="518">
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 2</span>. Feature Manifest Editor
+ </div>
+ </div>
+
+ <p>&nbsp;</p>
+
+ <div class="figure">
+ <img src="exportFeaturesDialog.png" height="487" width="378">
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 3</span>. Export Features Dialog
+ </div>
+ </div>
+
+ <h3>Build headless</h3>
+
+ <p>There are many reasons for creating a batch build process such as
+ providing a nightly or continuous build. This requires a fully automatic
+ build which can even start with the retrieval of the sources from CVS.
+ Eclipse itself is built in that way and because "everything is a plug-in"
+ the mechanisms can also be applied for the build of arbitrary plug-ins.
+ However it is necessary to bundle your plug-ins into a feature project if
+ you want to use headless build. If there is no real need to deploy your
+ plug-in(s) using a feature, a feature project can also be used for the
+ build process only. In this case there will be no feature manifest added to
+ the deliverable.</p>
+
+ <p>The infrastructure is provided by the PDE and the RelEng (Release
+ Engineering) plug-ins. The org.eclipse.releng.basebuilder plug-in contains
+ a complete Eclipse installation for the build, but any Eclipse-SDK is
+ sufficient. The org.eclipse.releng.eclipsebuilder plug-in contains control
+ files for the build of parts like JDT, PDE, and all the other plug-ins
+ which are part of the Eclipse distribution.</p>
+
+ <p>Although the build.xml provided in org.eclipse.releng.eclipsebuilder
+ looks like a plain Ant build file, there are Ant-Tasks required which are
+ provided from the PDE. Therefore the script must be executed in an Eclipse
+ environment. Because it would not be suitable for batch processing to start
+ up the Eclipse workbench, there is a "headless" startup mode provided,
+ which means that Eclipse is started without loading GUI plug-ins. To start
+ up a headless Eclipse instance which then executes an Ant build file,
+ Eclipse must be started as AntRunner application. An example is given in
+ Fig. 10.</p>
+
+ <h4>Building sdk.examples headless</h4>
+
+ <p>As an example, let's build one of the Eclipse deliverables headless. The
+ feature sdk.examples is chosen, because it is quite small, the deliverable
+ is about 1.8 Mb (<a href="#eclipsExamples">[5])</a>. The headless build
+ takes about 10 minutes on my 1.6Ghz Win XP laptop, most of the time used
+ for fetching the sources via a 64k internet connection. In addition to an
+ Eclipse installation there are two prerequisites for the headless
+ build:</p>
+
+ <ul>
+ <li><a target="extra" href="http://www.cvshome.org/">CVS</a> client
+ version 1.10 or higher on system path.</li>
+
+ <li><a target="extra" href=
+ "http://www.info-zip.org/pub/infozip/">Info-Zip</a> zip and unzip
+ executables on system path.</li>
+ </ul>
+
+ <p>The first step is to get org.eclipse.releng.eclipsebuilder:</p>
+<pre>
+D:\build&gt;cvs -d :pserver:anonymous@dev.eclipse.org:/home/eclipse export -r R3_0_2 org.eclipse.releng.eclipsebuilder
+</pre>
+
+ <p>The readme.html in org.eclipse.releng.eclipsebuilder (<a href=
+ "#eclipsebuilderReadme">[6])</a> describes how to build a component. By
+ default, components are built with an Eclipse instance (build host) defined
+ in org.eclipse.releng.basebuilder. But because the basebuilder is rather
+ large, we can also use an existing Eclipse-3.0.2 installation as build
+ host. Because it is not assured that the Eclipse-3.0.2 host can compile the
+ current Eclipse components, we use the 3.0.2 version of eclipsebuilder in
+ this example. In order to fetch the 3.0.2 version of sdk.examples instead
+ of the HEAD version, we have to modify
+ org.eclipse.releng.eclipsebuilder/sdk.examples/build.properties and set the
+ property mapVersionTag appropriately:</p>
+<pre>
+mapVersionTag=R3_0_2
+</pre>
+
+ <p>Now the build can be started from the command line:</p>
+<pre>
+D:\build\org.eclipse.releng.eclipsebuilder&gt;set ECLIPSE_HOME=D:\eclipse\eclipse-3.0.2
+D:\build\org.eclipse.releng.eclipsebuilder&gt;java -cp %ECLIPSE_HOME%\startup.jar org.eclipse.core.launcher.Main
+ -application org.eclipse.ant.core.antRunner -buildfile build.xml
+ -Dcomponent=sdk.examples -Dconfigs="*,*,*" -Dbaseos=win32 -Dbasews=win32 -Dbasearch=x86 -Djavacfailonerror=true
+ -Dpde.build.scripts=%ECLIPSE_HOME%/plugins/org.eclipse.pde.build_3.0.1/scripts -DbaseLocation=%ECLIPSE_HOME%
+</pre>
+
+ <p>The property "component" is used to define that the files in the
+ sdk.examples subdirectory are used in the headless build, which are
+ build.properties and customTargets.xml. The build takes place in
+ D:\build\org.eclipse.releng.eclipsebuilder\src by default. This can be
+ changed with the property buildDirectory. Either by adding
+ -DbuildDirectory=${basedir}/newDirectory to the command above or by
+ changing buildDirectory in
+ org.eclipse.releng.eclipsebuilder/sdk.examples/build.properties.</p>
+
+ <p>After the build has finished, the deliverable and compile logs can be
+ found in the build output directory, a subdirectory of the build directory.
+ The name of the output directory is defined by the buildLabel property. By
+ default it starts with "I-" and includes the time stamp of the build
+ time.</p>
+
+ <p>The baseLocation is used during the build to provide missing plug-ins,
+ i.e., plug-ins which are not part of the deliverable to build and have
+ therefore not been fetched from CVS. After the plug-ins have been fetched,
+ PDE reads in the plug-ins and creates a build time Eclipse host. If
+ baseLocation is given, the Eclipse installation at baseLocation is added to
+ the build time Eclipse host. In our case this is necessary, because
+ sdk.examples depends on the plug-ins in the Eclipse SDK and can therefore
+ not be built standalone. Note that the baseLocation is independent of the
+ build host and therefore the build host can be another version of Eclipse.
+ In the example we could use Eclipse 3.0.2 as build host and Eclipse 3.0 as
+ baseLocation. The baseLocation may not contain any of the plug-ins to be
+ built. If the baseLocation contained the sdk.examples, an error would
+ occur.</p>
+
+ <p>The next section looks behind the scenes of the headless build.</p>
+
+ <h3>Build Phases</h3>
+
+ <p>Fig. 4 shows the files which drive the build process. While build.xml
+ and genericTargets.xml are provided from the PDE feature, there are two
+ files to be provided by the plugin to be built: the customTargets.xml and
+ build.properties. Examples for these two files can be found in
+ org.eclipse.releng.eclipsebuilder\sdk.examples, if you did not download
+ org.eclipse.releng.eclipsebuilder in the last section, see <a href=
+ "#eclipsebuilderReadme">[7]</a>. The build.properties file allows
+ customizing various build parameters, for a reference see Fig. 5. Fig. 6
+ shows the interaction of three build files, build.xml, genericTargets.xml
+ and customTargets.xml, which accomplishes the build. The main phases of the
+ build process are declared in build.xml: PreBuild, Fetch, Generate,
+ Process, Assemble and PostBuild.</p>
+
+ <div class="figure">
+ <table class="contentTable" cellspacing="2">
+ <tbody>
+ <tr>
+ <th>File name</th>
+
+ <th>Location</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td><b>build.xml</b></td>
+
+ <td>org.eclipse.pde.build_&lt;version&gt;/scripts</td>
+
+ <td>This is the main build script and provides a skeleton for the
+ build process: from prebuild to postbuild targets</td>
+ </tr>
+
+ <tr>
+ <td><b>genericTargets.xml</b></td>
+
+ <td>org.eclipse.pde.build_&lt;version&gt;/scripts</td>
+
+ <td>Contains targets like fetchElement, generateScript,
+ processElement, assembleElement</td>
+ </tr>
+
+ <tr>
+ <td><b>customTargets.xml</b></td>
+
+ <td>value of property <i>builder</i></td>
+
+ <td>This build script resides in the location specified by the
+ property <i>builder</i>. It is included from the main build.xml
+ file and delegates to targets in genericTargets. The main
+ responsibilities are in defining the features to build and to fetch
+ the map files.</td>
+ </tr>
+
+ <tr>
+ <td><b>build.properties</b></td>
+
+ <td>value of property <i>builder</i></td>
+
+ <td>This build script resides in the location specified by the
+ property <i>builder</i>. It contains properties for fetching the
+ sources, building and compiling.</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 4</span>. Files for controlling the
+ build process
+ </div>
+ </div>
+ <br>
+ <br>
+
+
+ <div class="figure">
+ <table class="contentTable" cellspacing="2">
+ <tbody>
+ <tr>
+ <th>Category</th>
+
+ <th>Name</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td rowspan="3">Build folder</td>
+
+ <td>buildDirectory</td>
+
+ <td>The relative path to a directory where the source for the build
+ will be exported, where scripts will be generated and where the end
+ products of the build will be located. On Windows systems, this
+ directory should be close to the drive root to avoid path length
+ limitations particularly at compile time.</td>
+ </tr>
+
+ <tr>
+ <td>baseLocation</td>
+
+ <td>A directory separate from ${buildDirectory} which contains
+ pre-built plug-ins against which to compile. ${baseLocation} must
+ not contain any features, plug-ins or fragments which are already
+ or will be located in ${buildDirectory}.</td>
+ </tr>
+
+ <tr>
+ <td>baseos,basews,basearch,basenl</td>
+
+ <td>The os, ws, arch and nl values of the pre-built Eclipse found
+ in ${baseLocation}.</td>
+ </tr>
+
+ <tr>
+ <td rowspan="7">Build target (what is being built)</td>
+
+ <td>configs</td>
+
+ <td>An ampersand separated list of configurations to build for an
+ element where a configuration is specified as
+ &lt;os&gt;,&lt;ws&gt;,&lt;arch&gt;.<br>
+ ie.configs="win32,win32,x86 &amp; linux, motif, x86 &amp; linux,
+ gtk, x86". Typically used to build a feature that is os, ws, arch
+ specific. A non-platform specific configuration is specified with
+ "*,*,*".</td>
+ </tr>
+
+ <tr>
+ <td>collectingFolder</td>
+
+ <td>The directory in which built features and plug-ins are
+ gathered. This is typically set to "eclipse".</td>
+ </tr>
+
+ <tr>
+ <td>archivePrefix</td>
+
+ <td>The top level directory in assembled distribution. This is
+ typically set to "eclipse".</td>
+ </tr>
+
+ <tr>
+ <td>buildType</td>
+
+ <td>A letter "I, N, S, R or M" used to identify builds as being one
+ of the following:<br>
+ <br>
+ I - Integration<br>
+ N - Nightly<br>
+ S - Stable<br>
+ R - Release<br>
+ M - Maintenance<br>
+ </td>
+ </tr>
+
+ <tr>
+ <td>buildId</td>
+
+ <td>The build name. Default set to "build" in template
+ build.properties.</td>
+ </tr>
+
+ <tr>
+ <td>buildLabel</td>
+
+ <td>Refers to the name of the directory which will contain the end
+ result of the build. Set to ${buildType}.${buildId} in template
+ build.properties. This directory will be created in the
+ ${buildDirectory}.</td>
+ </tr>
+
+ <tr>
+ <td>timestamp</td>
+
+ <td>A timestamp used to fill in value for buildid in about.mappings
+ files. Also used to name build output directory, i.e.
+ I-build-&lt;timestamp&gt;.</td>
+ </tr>
+
+ <tr>
+ <td rowspan="2">Repository</td>
+
+ <td>mapVersionTag</td>
+
+ <td>Sets the tag attribute in a call to the <a target="extra" href=
+ "http://ant.apache.org/manual/CoreTasks/cvs.html">Ant &lt;cvs&gt;
+ task</a> to check out the map file project.</td>
+ </tr>
+
+ <tr>
+ <td>fetchTag</td>
+
+ <td>Sets the tag or branch when exporting modules used in the
+ build. For example, setting fetchTag=HEAD will fetch the HEAD
+ stream of the source for all features, plug-ins and fragments
+ listed in the map files instead of fetching the tag specified in
+ the map entry for that element. For example this is being used in
+ the eclipse build process to produce the nightly build.</td>
+ </tr>
+
+ <tr>
+ <td rowspan="6">Java Compiler</td>
+
+ <td>bootclasspath</td>
+
+ <td>Sets the value for the attribute "bootclasspath" in calls to
+ the <a target="extra" href=
+ "http://ant.apache.org/manual/CoreTasks/javac.html">Ant
+ &lt;javac&gt; task</a> in a plug-in's build.xml.</td>
+ </tr>
+
+ <tr>
+ <td>javacDebugInfo</td>
+
+ <td>Sets the value for the attribute "debug" in calls to the <a
+ target="extra" href=
+ "http://ant.apache.org/manual/CoreTasks/javac.html">Ant
+ &lt;javac&gt; task</a> in a plug-in's build.xml. Determines if
+ debug info is included in the output jars. Set to on in template
+ build.properties.</td>
+ </tr>
+
+ <tr>
+ <td>javacFailOnError</td>
+
+ <td>Sets the value for the attribute "failonerror" in calls to the
+ <a target="extra" href=
+ "http://ant.apache.org/manual/CoreTasks/javac.html">Ant
+ &lt;javac&gt; task</a> in a plug-in's build.xml. Build will
+ continue even if there are compilation errors when this is set to
+ false.</td>
+ </tr>
+
+ <tr>
+ <td>javacSource</td>
+
+ <td>Sets the value for the attribute "source" in calls to the <a
+ target="extra" href=
+ "http://ant.apache.org/manual/CoreTasks/javac.html">Ant
+ &lt;javac&gt; task</a> in a plug-in's build.xml. Sets the value of
+ the -source command line switch for javac version 1.4. Used when
+ compiling the jars for the plug-ins. Default set to 1.3 in
+ generated build.xml for plug-ins and fragments.</td>
+ </tr>
+
+ <tr>
+ <td>javacTarget</td>
+
+ <td>Sets the value for the attribute "target" in calls to the <a
+ target="extra" href=
+ "http://ant.apache.org/manual/CoreTasks/javac.html">Ant
+ &lt;javac&gt; task</a> in a plug-in's build.xml. Sets the value of
+ the -target command line switch for javac. Used when compiling the
+ jars for the plug-ins. Default set to 1.1 in generated build.xml
+ for plug-ins and fragments.</td>
+ </tr>
+
+ <tr>
+ <td>javacVerbose</td>
+
+ <td>Sets the value for the attribute "verbose" in calls to the <a
+ target="extra" href=
+ "http://ant.apache.org/manual/CoreTasks/javac.html">Ant
+ &lt;javac&gt; task</a> in a plug-in's build.xml. Asks the compiler
+ for verbose output. Default set to true.</td>
+ </tr>
+
+ <tr>
+ <td>misc</td>
+
+ <td>zipargs</td>
+
+ <td>Arguments to send to the zip executable. Setting it to -y on
+ Linux preserves symbolic links.</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 5</span>. build.properties
+ </div>
+ </div>
+ <br>
+ <br>
+
+
+ <div class="figure">
+ <img src="buildInteractionDiagram.png">
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 6</span>. Script interaction for the
+ build process<br>
+ </div>
+ </div>
+
+ <h4>PreBuild and Fetch phase</h4>
+
+ <p>Fig. 7 gives an overview of the main activities and the files created
+ from these activities for the complete build process. The getMapFiles and
+ concatenate activities are part of the PreBuild phase; fetch and getFromCVS
+ are part of the Fetch phase.</p>
+
+ <p>The most important task in the PreBuild phase is to retrieve map files,
+ which is implemented in the getMapFiles target in customTargets.xml.
+ Usually the getMapFiles target consists of a CVS command to fetch the map
+ files. A map file is a java property file which contains mappings of
+ elements to their CVS locations and access methods. It consists of one map
+ file entry for each feature being built, its &lt;plugin&gt; elements, and
+ its &lt;includes&gt; elements (i.e. nested features and their plug-ins).
+ Adding a plug-in or fragment to a feature therefore requires updating the
+ map files with the new element.</p>
+
+ <p>Map file entries use the following format:</p>
+<pre>
+feature|fragment|plugin@elementId=&lt;cvs tag&gt;,&lt;access method&gt;:&lt;cvsuser&gt;@&lt;cvs repository&gt;,&lt;cvs password&gt;[,&lt;repository path&gt; (no starting slash) ]
+</pre>
+
+ <p>The &lt;repository path&gt; is only required when the module (or
+ directory) containing the source for the element does not match the
+ elementId or if the directory is not at the root of the repository. Because
+ all the map files are concatenated into a single file called Directory.txt
+ after getMapFiles has finished, the format of directory.txt described in <a
+ href="#pdeHelpGenCommandLine">[4]</a> applies also to the format of a map
+ file.</p>
+
+ <p>The fetch phase starts with the creation of an ant script called
+ retrieve.xml, which contains a build target for fetching the feature.xml.
+ Then this target will be executed and the information about the provided
+ plug-ins of the feature is read in. For every provided plug-in a
+ corresponding build target will be added to the fetch build script. Both
+ files (retrieve.xml and feature.xml) are only temporary. They will be
+ deleted after the fetch build script has been generated.</p>
+
+ <p>The fetch build script is named fetch_&lt;element_id&gt;.xml, where
+ &lt;element_id&gt; is substituted with the feature id read from the
+ feature.xml file (not the property "id" given in customTargets.xml).
+ Running the default target "fetch" of this build script calls the target
+ getFromCVS for the feature itself and all included plug-ins. The sources of
+ the plugins are not fetched again in the case of an existing plugin.xml.
+ So, if you run the full build twice in the same directory, the sources for
+ the plug-ins are not fetched twice. But you need to have a working CVS
+ connection nonetheless, because the retrieve.xml file is created and
+ executed in any case. Therefore you would end up with an incomplete
+ fetch_&lt;element_id&gt;.xml file if you run the fetch phase and did not
+ have CVS connection.</p>
+ <br>
+ <br>
+
+
+ <div class="figure">
+ <img src="fetchProcessActivity.png" height="780" width="464">
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 7</span>. File flow of the build
+ process
+ </div>
+ </div>
+
+ <h4>Generate Phase</h4>
+
+ <p>After the feature and plug-ins have been copied to the build target
+ directory, the build scripts are generated in the same way as they would be
+ with the PDE GUI (see above). The created files are:</p>
+
+ <ul>
+ <li>a build file in every plug-in directory (unless custom build files
+ are used)</li>
+
+ <li>a build file in the feature directory</li>
+
+ <li>assemble_&lt;element_id&gt;.all.xml and
+ assemble_&lt;element_id&gt;.all.xml</li>
+ </ul>
+
+ <h4>Process and Assemble Phase</h4>
+
+ <p>At this point of the build process the build files are in place and the
+ compilation is started from a call to processElement in genericTargets.xml.
+ This in turn calls the target build.jars in the build.xml file in the
+ feature directory. There the compilation starts and the warning and error
+ messages of the java compiler are collected separately for each jar file.
+ The files are named &lt;jarFileName&gt;.bin.log and reside in a
+ subdirectory "temp.folder". Later these files are gathered and copied to
+ the build output directory.</p>
+
+ <p>The assembly is started from the assembleElement target in
+ genericTargets.xml which then calls a target named assemble.${id} in
+ customTargets.xml. This gives the chance to do some work before or after
+ the assembly, but the main part of the work can just be delegated to the
+ assemble.${id}.all.xml in the build target directory.</p>
+
+ <p>The assemble script copies all the build results to a temporary
+ subdirectory in the build target directory and finally zips them up. The
+ files being collected are feature manifest files (feature.xml), plug-in
+ manifest files (plugin.xml) and the built jar files. The inclusion of
+ arbitrary files can be specified with the bin.includes property of the
+ plug-in's build.properties file <a href=
+ "#pdeHelpBuildProperties">([1]</a>).</p>
+
+ <h4>PostBuild Phase</h4>
+
+ <p>This is a build hook which is empty per default and allows performing
+ actions with the build output. We will use this later for test
+ automation.</p>
+
+ <blockquote>
+ <p><img src="../images/tip.gif" height="13" width="62"> After
+ modifications to the build files you can save time if you run only a
+ particular phase of the build process. E.g. if you changed a property
+ which only affects the process phase, you can run this phase alone by
+ appending process to the -buildfile argument in the command line:</p>
+<pre>
+java org.eclipse.core.launcher.Main -application org.eclipse.ant.core.antRunner -buildfile %buildfile% process
+</pre>
+ </blockquote>
+
+ <h3>How to build your Plug-In</h3>
+
+ <p>Now we have built sdk.examples headless and have an overview of the
+ build process. Build automation for your plug-in is not far away anymore
+ with one constraint: you need to provide a feature project if you want to
+ fully leverage the headless build as you have seen it for sdk.examples. So,
+ if you don't have a feature project created yet, now is the time. With the
+ IDE you can create a feature project with
+ File-&gt;New-&gt;Project...-&gt;Plug-in Development-&gt;Feature Project. In
+ the wizard which opens enter a feature name and then select all the
+ plug-ins you want to include in your build. If you do not want to deploy
+ your plug-in(s) as a feature, you can configure the feature project so that
+ it is only be used to drive the build process but will not be included in
+ the deliverable. Therefore just remove the bin.includes property from the
+ build.properties file of the feature project.</p>
+
+ <p>Using the feature there need to be 4 files defined in order to provide a
+ one step build:</p>
+
+ <ul>
+ <li>a map file for fetching the sources</li>
+
+ <li>customTargets.xml</li>
+
+ <li>build.properties</li>
+
+ <li>a shell script, which starts an Eclipse instance as AntRunner</li>
+ </ul>
+
+ <p>Fig. 8 shows a part of the map file for RDT. The CVS method used is ext,
+ which allows to configure access parameters like user name, password or SSH
+ proxy locally. In the case that pserver should be used, the getMapFiles
+ target of customTargets.xml replaces ext with pserver.</p>
+
+ <div class="figure" style="text-align: left;">
+<pre>
+ feature@org.rubypeople.rdt=HEAD,:ext:cvs.sf.net:/cvsroot/rubyeclipse,,org.rubypeople.rdt-feature
+ plugin@org.kxml2=HEAD,:ext:cvs.sf.net:/cvsroot/rubyeclipse,
+ plugin@org.rubypeople.rdt=HEAD,:ext:cvs.sf.net:/cvsroot/rubyeclipse,
+ plugin@org.rubypeople.rdt.core=HEAD,:ext:cvs.sf.net:/cvsroot/rubyeclipse,
+</pre>
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 8</span>. A section from rdt.map
+ </div>
+ </div>
+
+ <p>As seen above customTargets.xml is the build file which provides hooks
+ to customize the build process. A template for customTargets.xml can be
+ found in <a href="#pdeScripts">[9]</a>. Fig. 9 shows the parts of the
+ customTargets.xml file which have to be modified as a minimum for the build
+ process:</p>
+
+ <ol>
+ <li>Define the Feature to be built in the allElements target. The given
+ id is not the Feature id as defined in the feature manifest but only an
+ identifier for the lookup in the map file.</li>
+
+ <li>Retrieve map files in the getMapFiles target. Usually the map files
+ are fetched from CVS and copied to the maps subdirectory of
+ ${buildDirectory}.</li>
+
+ <li>Provide a target called assemble.&lt;id&gt;. This can just delegate
+ to the assemble script which has been created in the generate phase of
+ the build process.</li>
+ </ol>
+
+ <div class="figure">
+ <div style="text-align: left;">
+<pre>
+&lt;target name="allElements"&gt;
+ &lt;ant antfile="${genericTargets}" target="${target}" &gt;
+ &lt;property name="type" value="feature" /&gt;
+ &lt;property name="id" value="org.rubypeople.rdt" /&gt;
+ &lt;/ant&gt;
+&lt;/target&gt;
+&lt;target name="getMapFiles"&gt;
+ &lt;property name="cvsRoot" value=":ext:cvs.sf.net:/cvsroot/rubyeclipse" /&gt;
+ &lt;cvs cvsroot="${cvsRoot}"
+ dest="${buildDirectory}/maps"
+ command="export -r ${mapVersionTag} org.rubypeople.rdt.build/map"/&gt;
+&lt;/target&gt;
+&lt;target name="assemble.org.rubypeople.rdt"&gt;
+ &lt;ant antfile="${assembleScriptName}" dir="${buildDirectory}"&gt;
+ &lt;property name="zipargs" value="" /&gt;
+ &lt;/ant&gt;
+&lt;/target&gt;
+</pre>
+ </div>
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 9</span>. Mandatory changes in
+ customTargets.xml
+ </div>
+ </div>
+
+ <h4>Build RDT as example</h4>
+
+ <p>All the files which configure the headless build for RDT can be found in
+ <a href="#buildBootstrapFilesRdt">[10]</a>. In order to build RDT, you must
+ have an Eclipse 3.0.x installation, CVS installed and CVS access to the
+ internet (firewall!). The sources will be fetched from cvs.sf.net, which
+ provides anonymous access.</p>
+
+ <p>First we need to get the bootstrap for the headless build:</p>
+<pre>
+cvs -d :pserver:anonymous@cvs.sf.net:/cvsroot/rubyeclipse export -r R0_5_0 org.rubypeople.rdt.build/bootstrap
+</pre>
+
+ <p>After a successful retrieval you will find the following files: README,
+ run.bat, run.sh, customTargets.xml and build.properties. The map file
+ defines to fetch the HEAD version of all plug-ins. In order to get stable
+ sources, the property fetchTag is set in build.properties and overwrites
+ the settings from the map file. See <a href="#pdeScripts">[9]</a> for a
+ description of the build file options. Now change the variables in the run
+ script (run.bat on windows or run.sh on UNIX) so that they reflect your PCs
+ environment.</p>
+
+ <ul>
+ <li>Adapt eclipseDir and pdeBuildPluginVersion to the Eclipse
+ installation you want to use for the build</li>
+
+ <li>Set the buildDirectory&nbsp;</li>
+
+ <li>The variable docbook.root can be commented out</li>
+
+ <li>The variable pluginAutomaticBuildDir must be set to the absolute path
+ of the bootstrap directory</li>
+
+ <li>If java 1.4.x is not available on the classpath, vm must be set to
+ the location of a java 1.4.x executable.&nbsp;</li>
+ </ul>
+
+ <p>Now the execution of the run script should build RDT. If it does not,
+ test your skills in handling the lengthy Ant stack traces.</p>
+
+ <blockquote>
+ <p><img src="../images/tip.gif" height="13" width="62">The
+ build.properties file which is provided as template in <a href=
+ "#pdeScripts">[9]</a> builds a result zip file which contains paths with
+ "eclipse" prefix, e.g. "eclipse/feature/...". This is inconvenient if the
+ zip file should be extracted into a renamed Eclipse installation
+ directory, e.g. eclipse-3.0.2. Therefore the archive path names should be
+ relative to the eclipse installation directory, which can be achieved by
+ setting the properties collectingFolder and archivePrefix to ".".</p>
+ </blockquote>
+
+ <h4>Debug the Build Process</h4>
+
+ <p>If you reach a point where the error messages during the build are more
+ confusing than helpful, you can debug the build run. A first measure to
+ take is to set the AntRunner to verbose mode: add a "-verbose" behind the
+ AntRunner argument in the java command line. This gives detailed
+ information about which Ant targets are executed. It is particularly useful
+ for debugging problems with accessing CVS. If that does not help, the build
+ run itself can be debugged. Instead of starting the build host from a shell
+ script (.sh or .bat) you can start the build host from the Eclipse IDE with
+ a Run Configuration. The custom Ant Tasks which PDE provides reside in the
+ org.eclipse.pde.build plug-in project and set breakpoints or catch
+ exceptions. Here is a step-by-step guide on how to set up an AntRunner
+ Run-time Workbench:</p>
+
+ <ol>
+ <li>Start Eclipse and switch to an empty workspace</li>
+
+ <li>File&gt;Import, External plug-ins and Fragments</li>
+
+ <li>Select "Projects with source folders"</li>
+
+ <li>Add all plug-ins with org.eclipse.pde.*</li>
+
+ <li>
+ Create a Run-time Workbench run configuration (Run-&gt;Run..., Run-time
+ Workbench)
+
+ <ol>
+ <li>Choose "org.eclipse.ant.core.antRunner" as "Run an
+ application"</li>
+
+ <li>
+ Add Program Arguments:
+
+ <ol>
+ <li>-Dbuilder=$builder, where $builder is the directory where
+ your customTargets.xml is located</li>
+
+ <li>-DbaseLocation=$baseLocation, where $baseLocation is the
+ directory of your Eclipse installation (see above)</li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+
+ <li>Add a breakpoint, e.g. in the method "generate" in
+ org.eclipse.pde.build/src-pdebuild/org.eclipse.pde.internal.build.FetchScriptGenerator</li>
+
+ <li>Start the debug session</li>
+ </ol>
+
+ <div class="figure">
+ <img style="width: 794px; height: 605px;" alt=
+ "Run Configuration for building sdk.examples" src=
+ "buildRunConfiguration.png"><br>
+
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 10</span>. Run configuration for
+ building sdk.examples<br>
+ </div>
+ </div>
+
+ <p>Fig. 10 shows the Run configuration dialog for building sdk.examples,
+ which we have built from command line above. The full Program Arguments
+ are:</p>
+<pre>
+-buildfile "D:\build\org.eclipse.releng.eclipsebuilder\build.xml" -Dcomponent=sdk.examples -Dconfigs="*,*,*"
+-Dbaseos=win32 -Dbasews=win32 -Dbasearch=x86 -Djavacfailonerror=true
+-Dpde.build.scripts=D:/eclipse/eclipse-3.0.2/plugins/org.eclipse.pde.build_3.0.1/scripts -DbaseLocation=D:\eclipse\eclipse-3.0.2
+</pre>
+
+ <p>Note the location of the build workspace. The log file in
+ D:\build\build-workspace\.metadata\.log often provides useful information
+ if a build fails.</p>
+
+ <h4>Include sources</h4>
+
+ <p>Unfortunately the headless build does not support all of the settings as
+ they are provided by the Feature Export Dialog (Fig. 3). For example, the
+ inclusion of source jar files is not possible. This lack can be
+ circumvented by using a source feature or plug-in. Building a source
+ feature is quite convenient and needs only two entries to be added:</p>
+
+ <ol>
+ <li>
+ Add a Line to build.properties of your feature project:
+<pre>
+generate.feature@org.rubypeople.rdt.source=org.rubypeople.rdt
+</pre>
+ </li>
+
+ <li>
+ Add an xml element to feature.xml:
+<pre>
+&lt;includes id="org.rubypeople.rdt.source" version="0.0.0"/&gt;
+</pre>
+ If the version is set to 0.0.0, the version of the containing plug-in
+ will be used.
+ </li>
+ </ol>
+
+ <p>Further customization of the source feature generation can be achieved
+ by creating the subdirectories "sourceTemplatePlugin" and
+ "sourceTemplateFeature" in your feature project. These directories should
+ contain the files that are included in the root of the generated source
+ feature and plug-in. The feature.xml and plugin.xml files are not required
+ since these are generated. A build.properties is required in the
+ sourceTemplatePlugin directory. This should contain a "bin.includes"
+ setting as well as the entry "sourcePlugin = true". The plugin.xml file and
+ src/ directory should be listed in bin.includes.</p>
+
+ <blockquote>
+ <p><img src="../images/tip.gif" height="13" width="62"> If there is an
+ includes tag in feature.xml, building with the Export... button from the
+ Feature Manifest Editor fails (<a href=
+ "#generateSourceFeatureBug">[16]</a>). As a workaround the feature.xml of
+ the RDT project contains only an xml comment. The comment will be
+ replaced with the includes tag in the postFetch target in
+ customTargets.xml. The generate.feature property must be treated in a
+ similar way.</p>
+ </blockquote>
+
+ <h4>Build for Update Site</h4>
+
+ <p>If you want to build files for an update site customTargets.xml can be
+ modified to call the build.update.jar target of the feature build file. The
+ results can then be copied to the update site location. Fig. 11 shows the
+ changes in customTargets.xml, following the idea in <a href=
+ "#discussionUpdateSiteBuild">[11]</a>.</p>
+
+ <div class="figure">
+ <div style="text-align: left;">
+<pre>
+&lt;target name="postBuild"&gt;
+ &lt;property name="UpdateSiteStagingLocation" value="${buildDirectory}/updateSite"/&gt;
+ &lt;property name="sitePackagePrefix" value="org.rubypeople.updatesite"/&gt;
+ &lt;antcall target="generateUpdateSite"/&gt;
+&lt;/target&gt;
+&lt;target name="generateUpdateSite"&gt;
+ &lt;!-- Create the directory structure --&gt;
+ &lt;mkdir dir="${UpdateSiteStagingLocation}"/&gt;
+ &lt;mkdir dir="${UpdateSiteStagingLocation}/features"/&gt;
+ &lt;mkdir dir="${UpdateSiteStagingLocation}/plugins"/&gt;
+ &lt;!-- Build the jar files --&gt;
+ &lt;antcall target="allElements"&gt;
+ &lt;param name="genericTargets" value="${builder}/customTargets.xml"/&gt;
+ &lt;param name="target" value="updateSiteExport"/&gt;
+ &lt;/antcall&gt;
+ &lt;antcall target="copySiteXmlFromCvs"/&gt;
+ &lt;antcall target="createNightlyBuildSiteXml"/&gt;
+&lt;/target&gt;
+&lt;target name="updateSiteExport"&gt;
+ &lt;ant antfile="build.xml" dir="${buildDirectory}/features/${id}/" target="build.update.jar"&gt;
+ &lt;property name="feature.destination" value="${UpdateSiteStagingLocation}/features"/&gt;
+ &lt;property name="plugin.destination" value="${UpdateSiteStagingLocation}/plugins"/&gt;
+ &lt;/ant&gt;
+&lt;/target&gt;
+&lt;target name="copySiteXmlFromCvs" unless="isNightlyBuild"&gt;
+ &lt;!-- connect to CVS and fetch site.xml, copy to ${UpdateSiteStagingLocation}/site.xml afterwards --&gt;
+&lt;/target&gt;
+&lt;target name="createNightlyBuildSiteXml" if="isNightlyBuild"&gt;
+ &lt;!-- create ${UpdateSiteStagingLocation}/site.xml which contains only the nighlty build version --&gt;
+&lt;/target&gt;
+</pre>
+ </div>
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 11</span>. Building for update site
+ </div>
+ </div>
+
+ <h2>Part 2 - Automated Tests</h2>
+
+ <p>After the deliverable has been created the wish may arise to deploy it
+ and to run a test suite with unit and integration tests. The reasons to do
+ this automatically as well and present the results along with the
+ deliverable are manifold:</p>
+
+ <ul>
+ <li>find integration errors, run the tests in different
+ configurations</li>
+
+ <li>give a hint on the quality of the code, particularly useful for
+ nightly builds</li>
+
+ <li>run the tests in a defined environment as opposed to the workbench of
+ the developer</li>
+ </ul>
+
+ <p>Fortunately, Eclipse provides a framework for test automation, which can
+ also be leveraged for test automation of arbitrary Eclipse features. The
+ test results of every Eclipse build are publicly available in the Eclipse
+ download directories; see <a href="#discussionUpdateSiteBuild">13</a> for
+ the test results of the 3.0.2 build.</p>
+
+ <h3>Eclipse Test Framework</h3>
+
+ <p>For running the tests on your PC, get the
+ eclipse-Automated-Tests-&lt;version&gt;.zip, which contains a zip file with
+ the unit tests (eclipse-junit-tests-&lt;version&gt;.zip), shell scripts,
+ build files and documentation. The steps for running the tests are
+ described in the file testFramework.html (<a href="#testFramework">14</a>).
+ Basically the shell script runtests starts up a new AntRunner Eclipse
+ instance which executes one of the targets of the test.xml build file.
+ Therefore an eclipse installation must exist in the eclipse subdirectory,
+ which is called the build host in the following. If there is no build host
+ installation, the script tries to unzip an SDK zip which it assumes to be
+ the same directory. In addition to that the script extracts the
+ org.eclipse.test plug-in from the eclipse-junit-tests-&lt;version&gt;.zip
+ into the build host installation.<br>
+ <br>
+ In order to run the some of the tests of the JDT, the following steps are
+ necessary:</p>
+
+ <ol>
+ <li>Download eclipse-Automated-Tests-3.0.2.zip (<a href=
+ "#eclipseAutomatedTests">15</a>) and unzip to
+ $ECLIPSE_AUTOMATED_TESTS</li>
+
+ <li>Copy eclipse-SDK-3.0.2 to $ECLIPSE_AUTOMATED_TESTS</li>
+
+ <li>cd to $ECLIPSE_AUTOMATED_TESTS and type "runtests.bat jdtui"</li>
+ </ol>
+
+ <p>The last step executes the non-interactive UI tests for the JDT (there
+ are also interactive UI Tests which require the interaction of a test
+ person to assure the layout and interactive behaviour of dialogs for
+ example). Although the tests are non-interactive you will watch a workbench
+ come up and during the execution of the test suite you can witness projects
+ being created and closed, editors being opened and so on. After the test
+ run has finished, the test results will be placed in
+ $ECLIPSE_AUTOMATED_TESTS/results in html and xml format.<br>
+ <br>
+ While the tests run, we can have look behind the scenes. Fig. 12 lists the
+ build files for test automation; Fig. 13 shows the interaction between
+ them. At first the runtests script creates the build host and launches an
+ Eclipse instance as AntRunner. The AntRunner executes the jdt target of
+ test.xml. During the process another eclipse-installation will take place
+ in $ECLIPSE_AUTOMATED_TESTS/test-eclipse, called the test host in the
+ following. The test host also consists of the provided SDK and the full
+ content of eclipse-junit-tests-3.0.2.zip. A test host instance is then
+ launched, with the application type org.eclipse.test.uitestapplication
+ (target uitest in library.xml, see below). The class name of the test suite
+ is passed to the uitestapplication. After the test suite has completed, the
+ test results can be found in $ECLIPSE_AUTOMATED_TESTS/results.</p>
+
+ <div class="figure">
+ <center style="margin-bottom: 1em;">
+ <table class="contentTable" cellspacing="2">
+ <tbody>
+ <tr>
+ <th>file name</th>
+
+ <th>location</th>
+
+ <th>description</th>
+ </tr>
+
+ <tr>
+ <td><b>test.xml</b></td>
+
+ <td>unzip location of eclipse-Automated-Tests.zip</td>
+
+ <td>This script provides the entry point for testing, the
+ runtests target</td>
+ </tr>
+
+ <tr>
+ <td><b>test.xml</b></td>
+
+ <td>plug-in directory of the test suite to be run</td>
+
+ <td>Must provide a run target. Main purpose is to set properties
+ and delegate to the ui-test target in library.xml. After the
+ tests have run the collect target in library is called to create
+ the result files. A skeleton can be found in <a href=
+ "#testFramework">14.</a> </td>
+ </tr>
+
+ <tr>
+ <td><b>library.xml</b></td>
+
+ <td>plugins/org.eclipse.test, delivered in
+ eclipse-junit-tests-&lt;version&gt;.zip, which itself is part of
+ eclipse-Automated-Tests-&lt;version&gt;.zip</td>
+
+ <td>This build script contains the eclipse-test target which
+ launches a new eclipse instance within which the tests will be
+ executed. Tests can be run with or without UI.</td>
+ </tr>
+ </tbody>
+ </table>
+ </center>
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 12</span>. Files for controlling the
+ test process
+ </div>
+ </div>
+ <br>
+ <br>
+ <br>
+
+
+ <div class="figure">
+ <img style="width: 861px; height: 554px;" alt=
+ "Interaction Diagram for the test process" src=
+ "runTestsInteractionDiagram.png"><br>
+
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 13</span>. Script interaction for the
+ test process
+ </div>
+ </div>
+
+ <h3>Automate Tests for your Plug-In</h3>
+
+ <p>Now it is time to think about the effort to automate the tests for your
+ plug-in. At the time I automated the tests for RDT, the tests resided in
+ extra plug-ins and there was an AllTests suite, which gathered all the
+ tests. With these preconditions, there were 3 steps on the road to test
+ automation:</p>
+
+ <ul>
+ <li>Build a deployable which includes the tests</li>
+
+ <li>Add a test.xml file in the plug-in, which contains the AllTests
+ suite</li>
+
+ <li>Add post-build behavior in customTargets.xml</li>
+ </ul>
+
+ <h4>Build a deployable which includes the tests</h4>
+
+ <p>Because the deliverable for your plug-in (the zip file or update site
+ files) should not contain the tests, another zip file for the tests must be
+ created, called test deliverable in the following. If you followed the
+ pattern of the Eclipse plug-ins and created a tests plug-in project for
+ each of your plug-ins, this can easily be achieved. If there is more than
+ one test plug-in project, a test feature can be created to bundle them.
+ Therefore you can add a feature project. Alternatively, if you want to keep
+ the number of projects small and do not have the need to create the feature
+ interactively from the feature manifest file, you can add a subdirectory to
+ the existing feature project. The map file can then be used to customize
+ the fetch process to create a feature directory with the content of the
+ subdirectory. An example is given in the first line of Fig. 14.</p>
+
+ <div class="fileContent">
+ feature@org.rubypeople.rdt-tests=HEAD,:ext:cvs.sf.net:/cvsroot/rubyeclipse,,org.rubypeople.rdt-feature/unit-tests-feature<br>
+
+ plugin@org.rubypeople.rdt.ui.tests=HEAD,:ext:cvs.sf.net:/cvsroot/rubyeclipse,<br>
+
+ plugin@org.rubypeople.rdt.debug.core.tests=HEAD,:ext:cvs.sf.net:/cvsroot/rubyeclipse,<br>
+
+ ...<br>
+
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 14</span>. Section from rdt.map for
+ test feature
+ </div>
+ </div>
+
+ <p>Building the test deliverable is identical to building the deliverable
+ itself. If you can use the same build properties as for the deliverable,
+ just add an additional entry to the allElements target in
+ customTargets.xml. Fig. 15 shows how the allElements target is adapted for
+ RDT in order to create the deliverable and test deliverable in one
+ step.</p>
+
+ <div class="fileContent">
+<pre>
+&lt;target name="allElements"&gt;&lt;target name="allElements"&gt;
+
+ ...
+
+ &lt;ant antfile="${genericTargets}" target="${target}" &gt;
+ &lt;property name="type" value="feature" /&gt;
+ &lt;property name="id" value="org.rubypeople.rdt-tests" /&gt;
+ &lt;/ant&gt;
+&lt;/target&gt;
+&lt;target name="postBuild"&gt;
+ &lt;antcall target="test"&gt;&lt;/antcall&gt;
+&lt;/target&gt;
+
+&lt;target name="test"&gt;
+ &lt;echo message="Setting up tests in ${eclipseAutomatedTestHome}"/&gt;
+
+ &lt;copy file="${buildDirectory}/${buildLabel}/org.rubypeople.rdt-${buildId}.zip" tofile="${eclipseAutomatedTestHome}/eclipse-SDK-RDT-${buildId}.zip" /&gt;
+ &lt;copy file="${buildDirectory}/${buildLabel}/org.rubypeople.rdt-tests-${buildId}.zip" tofile="${eclipseAutomatedTestHome}/eclipse-junit-tests-rdt-${buildId}.zip" /&gt;
+
+ &lt;ant antfile="${eclipseAutomatedTestHome}/test.xml" target="runtests" dir="${eclipseAutomatedTestHome}"&gt;
+ &lt;property name="os" value="${baseos}" /&gt;
+ &lt;property name="ws" value="${basews}" /&gt;
+ &lt;property name="arch" value="${basearch}" /&gt;
+ &lt;property name="testPlugin" value="org.rubypeople.rdt.tests.all_0.5.0" /&gt;
+ &lt;property name="report" value="org.rubypeople.rdt.tests.all" /&gt;
+ &lt;/ant&gt;
+&lt;/target&gt;
+</pre>
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 15</span>. Targets from
+ customTargets.xml for testing
+ </div>
+ </div>
+
+ <h4>Add a test.xml</h4>
+
+ <p>A test.xml file must exist for every test plug-in you want to run.
+ Because every test run starts up a new eclipse instance, it is convenient
+ to have a plug-in which bundles all the tests into a single AllTests suite.
+ Then there is only one test run and there must only be one test.xml file
+ maintained. A template for such a test.xml file can be found in <a href=
+ "#testFramework">14</a>. Fig. 16 shows important targets of the test.xml
+ for the RDT plug-in containing the AllTests suite. The entry point is the
+ run target, which is called from ${eclipseAutomatedTestHome}/test.xml. Its
+ prerequisites are init, suite and cleanup. The suite target calls ui-test
+ in library.xml with the necessary properties to start up the test host and
+ run TS_RdtAllTests.</p>
+
+ <div class="fileContent">
+<pre>
+ &lt;target name="init"&gt;
+ &lt;tstamp/&gt;
+ &lt;delete&gt;
+ &lt;fileset dir="${eclipse-home}" includes="org*.xml"/&gt;
+ &lt;/delete&gt;
+ &lt;/target&gt;
+
+ &lt;!-- This target defines the tests that need to be run. --&gt;
+ &lt;target name="suite"&gt;
+ &lt;property name="rdt-folder" value="${eclipse-home}/rdt_folder"/&gt;
+ &lt;delete dir="${rdt-tests-workspace}" quiet="true"/&gt;
+ &lt;ant target="ui-test" antfile="${library-file}" dir="${eclipse-home}"&gt;
+ &lt;property name="data-dir" value="${rdt-tests-workspace}"/&gt;
+ &lt;property name="plugin-name" value="${plugin-name}"/&gt;
+ &lt;property name="classname" value="org.rubypeople.rdt.tests.all.TS_RdtAllTests"/&gt;
+
+ &lt;property name="vmargs" value="-Drdt.rubyInterpreter=&amp;quot;${rdt.rubyInterpreter}&amp;quot;"/&gt;
+
+ &lt;/ant&gt;
+ &lt;/target&gt;
+
+
+ &lt;!-- This target holds code to cleanup the testing environment after --&gt;
+ &lt;!-- after all of the tests have been run. You can use this target to --&gt;
+ &lt;!-- delete temporary files that have been created. --&gt;
+ &lt;target name="cleanup"&gt;
+ &lt;/target&gt;
+
+ &lt;!-- This target runs the test suite. Any actions that need to happen --&gt;
+ &lt;!-- after all the tests have been run should go here. --&gt;
+ &lt;target name="run" depends="init,suite,cleanup"&gt;
+ &lt;ant target="collect" antfile="${library-file}" dir="${eclipse-home}"&gt;
+ &lt;property name="includes" value="org*.xml"/&gt;
+ &lt;property name="output-file" value="${plugin-name}.xml"/&gt;
+ &lt;/ant&gt;
+ &lt;/target&gt;
+</pre>
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 16</span>. Important targets of
+ org.rubypeople.rdt.tests.all/test.xml<br>
+ </div>
+ </div>
+
+ <h4>Add post-build behavior in customTargets.xml</h4>
+
+ <p>Fig. 15 shows the test target of customTargets.xml, which is executed in
+ the PostBuild phase of the build process. The property
+ eclipseAutomatedTestHome is set to the directory into which
+ eclipse-Automated-Tests-&lt;version&gt;.zip has been extracted. The first
+ step in the test target is to copy the two deliverables into this
+ directory, following a naming schema which is given in
+ ${eclipseAutomatedTestHome}/test.xml. By using these names, the runtests
+ target of test.xml extracts the deliverables into the test host
+ installation (in ${eclipseAutomatedTestHome}/test-eclipse/eclipse). The
+ second step is to call the runtests target of
+ ${eclipseAutomatedTestHome}/test.xml. The property testPlugin defines which
+ tests to run and the report property defines the name of the generated
+ report.</p>
+
+ <p>Compared to the example above, where we ran the tests jdt ui, there is
+ no need to create the build host in $ECLIPSE_AUTOMATED_TESTS/eclipse,
+ because the target runtests in test.xml is directly called from the
+ postbuild target in customTargets.xml. So the build host for the automatic
+ build is reused as build host for the automatic tests. Fig. 17 shows the
+ difference compared to Fig. 13.</p>
+
+ <div class="figure">
+ <img alt="Interaction Diagram for the test process" src=
+ "runTestsRdtInteractionDiagram.png"><br>
+
+
+ <div class="figure-caption">
+ <span class="figure-number">Fig 17</span>. Script interaction for the
+ test process<br>
+ </div>
+ </div>
+
+ <blockquote>
+ <p><img src="../images/tip.gif" height="13" width="62">PDE JUnit tests
+ open up a workbench window. If you run your tests on a remote *nix box,
+ you can use Xvfb (X virtual frame buffer) to provide a dummy environment
+ for displaying windows.</p>
+ </blockquote>
+
+ <h4>Run the RDT tests</h4>
+
+ <p>If you want to run the RDT tests, follow the instructions above for
+ building RDT and set the following additional properties in run.bat or
+ run.sh:</p>
+
+ <ul>
+ <li>unset dontRunTests</li>
+
+ <li>set eclipseAutomatedTestHome to the directory into which you
+ extracted eclipse-Automated-Tests-3.0.2.zip</li>
+
+ <li>unset rubyInterpreter if you don't have ruby installed (which will
+ result in failed tests)</li>
+ </ul>
+
+ <p>After you call run.bat or run.sh the tests will be executed in the
+ postBuild phase. If you want to run the tests separately, you can insert
+ the build target after the -build property in the antRunner command
+ line:</p>
+<pre>
+%vm% -cp %eclipseDir%\startup.jar ... org.eclipse.core.launcher.Main -application org.eclipse.ant.core.antRunner -buildfile %buildfile% postBuild -data ...
+</pre>
+
+ <h1>Conclusion</h1>
+
+ <p>Hopefully this article could help you in setting up project automation
+ for your Eclipse plug-in project. It has shown the automation mechanisms
+ used in building Eclipse itself and how they are leveraged to build and
+ test arbitrary plug-ins automatically with a single command. Further
+ project automation can be achieved from the inside or from the outside:
+ From the inside by using the hooks provided in the build files for
+ activities like enhanced reporting. From the outside by calling the build
+ command as part of a broader build process from tools like CruiseControl or
+ Maven.<br>
+ For the discussion of questions about this article and experiences with
+ Eclipse build and test automation in general, I'd like to invite you to the
+ RDT developer wiki [<a href="#feedbackPage">17</a>] or to e-mail me [<a
+ href="#mbarchfeContact">18]</a>.</p>
+
+ <h1>Acknowledgments</h1>
+
+ <p>I would like to thank Sonia Dimitrov and Pascal Rapicault for their
+ article draft, which I have weaved into this article. Many thanks also to
+ Pat McCarthy for his valuable comments.</p>
+
+ <h3>Reference</h3>
+
+ <table>
+ <tbody>
+ <tr>
+ <td valign="top"><a name="pdeHelpBuildProperties">[1]</a> </td>
+
+ <td><a href=
+ "http://help.eclipse.org/help30/topic/org.eclipse.pde.doc.user/guide/pde_feature_generating_build.htm"
+ class="referenceLink">PDE Help on build.properties</a>, Eclipse 3.0
+ Help</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="pdeHelpGenAnt">[2]</a> </td>
+
+ <td><a href=
+ "http://help.eclipse.org/help30/topic/org.eclipse.pde.doc.user/guide/pde_feature_generating_ant.htm"
+ class="referenceLink">PDE Help on Generating Build Files</a>,
+ Eclipse 3.0 Help</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="bugsHeadlessInvokation">[3]</a> </td>
+
+ <td><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=65146"
+ class="referenceLink">Generated feature build scripts and headless
+ invokation</a> , Eclipse Bugs</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="pdeHelpGenCommandLine">[4]</a> </td>
+
+ <td><a href=
+ "http://help.eclipse.org/help30/index.jsp?topic=/org.eclipse.pde.doc.user/guide/pde_feature_generating_antcommandline.htm"
+ class="referenceLink">PDE Help on headless build</a> , Eclipse 3.0
+ Help</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="eclipsExamples">[5]</a> </td>
+
+ <td><a href=
+ "http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.0-200406251208/eclipse-examples-3.0-win32.zip"
+ class="referenceLink">eclipse-examples-3.0-win32.zip</a> , Eclipse
+ Download Area</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="eclipsebuilderReadme">[6]</a> </td>
+
+ <td><a href=
+ "http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.releng.eclipsebuilder/readme.html?rev=1.24"
+ class=
+ "referenceLink">org.eclipse.releng.eclipsebuilder/readme.html</a> ,
+ Eclipse CVS</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="sdkExamplesBuildFiles">[7]</a> </td>
+
+ <td><a href=
+ "http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.releng.eclipsebuilder/sdk.examples"
+ class=
+ "referenceLink">org.eclipse.releng.eclipsebuilder/sdk.examples</a>,
+ Eclipse CVS</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="jdtFeature">[8]</a> </td>
+
+ <td><a href=
+ "http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt-feature/"
+ class="referenceLink">JDT feature</a> , Eclipse CVS</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="pdeScripts">[9]</a> </td>
+
+ <td><a href=
+ "http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.pde.build/scripts"
+ class="referenceLink">org.eclipse.pde.build/scripts</a>, Eclipse
+ CVS</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="buildBootstrapFilesRdt">[10]</a> </td>
+
+ <td><a href=
+ "http://cvs.sourceforge.net/viewcvs.py/rubyeclipse/org.rubypeople.rdt.build/bootstrap/">
+ RDT bootstrap files for headless build</a>, RDT CVS</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="discussionUpdateSiteBuild">[11]</a> </td>
+
+ <td><a href=
+ "http://dev.eclipse.org/newslists/news.eclipse.platform/msg25629.html"
+ class="referenceLink">Way to automatically build for update
+ site?</a> , Eclipse News</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="usingPDEBuild">[12]</a> </td>
+
+ <td><a href=
+ "http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.pde.build/notes/usingPDEBuild.html?rev=1.8"
+ class="referenceLink">Using PDE Build</a>, Eclipse CVS</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="eclipseTestResults">[13]</a> </td>
+
+ <td><a href=
+ "ftp://download.eclipse.org/R-3.0.2-200503110845/testresults" class=
+ "referenceLink">Eclipse Test Results for 3.0.2</a>, Eclipse Download
+ Area</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="testFramework">[14]</a> </td>
+
+ <td><a href=
+ "ftp://download.eclipse.org/R-3.0.2-200503110845/testframework.html"
+ class="referenceLink">testframework.html</a>, Eclipse Download
+ Area</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="eclipseAutomatedTests">[15]</a> </td>
+
+ <td><a href=
+ "http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.0-200406251208/eclipse-Automated-Tests-3.0.zip"
+ class="referenceLink">eclipse-Automated-Tests-3.0.2.zip</a>, Eclipse
+ Download Area</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="generateSourceFeatureBug">[16]</a> </td>
+
+ <td><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=86299"
+ class="referenceLink">generate.feature and building using export
+ button in feature.xml</a> , Eclipse Bugs</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="feedbackPage">[17]</a> </td>
+
+ <td><a href="http://213.203.244.123/wiki/Automatic_Build.wiki.phtml"
+ class="referenceLink">feedback page</a>, RDT developer wiki</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><a name="mbarchfeContact">[18]</a> </td>
+
+ <td><a href="http://sourceforge.net/users/mbarchfe/" class=
+ "referenceLink">contact</a>, user page at sf.net</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <p><small>ref: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=87151">bug
+ 87151</a></small></p>
+
+ <p><small>Java and all Java-based trademarks and logos are trademarks or
+ registered trademarks of Sun Microsystems, Inc. in the United States, other
+ countries, or both.</small></p>
+ </body>
+</html>
+
diff --git a/Article-PDE-Automation/automation_style.css b/Article-PDE-Automation/automation_style.css
new file mode 100644
index 0000000..e8c4780
--- /dev/null
+++ b/Article-PDE-Automation/automation_style.css
@@ -0,0 +1,25 @@
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
+.contentTable { background-color: white; }
+.contentTable TD,TH { background-color: whitesmoke; text-align: left;}
+div.figure { background-color: whitesmoke; text-align: center;}
+div.fileContent { background-color: whitesmoke; text-align: left;}
+div.figure-caption { text-align: center; border-top-width: thin; border-right-width: thin; border-bottom-width: thin; border-left-width: thin; border-top-style: solid; border-top-color: #FFFFFF;}
+span.figure-number { font-weight: bold;}
+pre.program { margin-left: 1em; margin-right: 1em; padding: 5px; background-color: whitesmoke;}
+dt {font-weight: bold; margin-left: 2ex;}
+dd { margin-left: 5ex;}
+a.cite { text-decoration: none; background-color: whitesmoke;
+.referenceLink { font-style: italic;}
+
diff --git a/Article-PDE-Automation/buildInteractionDiagram.png b/Article-PDE-Automation/buildInteractionDiagram.png
new file mode 100644
index 0000000..01b5969
--- /dev/null
+++ b/Article-PDE-Automation/buildInteractionDiagram.png
Binary files differ
diff --git a/Article-PDE-Automation/buildRunConfiguration.png b/Article-PDE-Automation/buildRunConfiguration.png
new file mode 100644
index 0000000..24db40f
--- /dev/null
+++ b/Article-PDE-Automation/buildRunConfiguration.png
Binary files differ
diff --git a/Article-PDE-Automation/createAntBuildFile.png b/Article-PDE-Automation/createAntBuildFile.png
new file mode 100644
index 0000000..0aadefa
--- /dev/null
+++ b/Article-PDE-Automation/createAntBuildFile.png
Binary files differ
diff --git a/Article-PDE-Automation/exportFeaturesDialog.png b/Article-PDE-Automation/exportFeaturesDialog.png
new file mode 100644
index 0000000..0a09599
--- /dev/null
+++ b/Article-PDE-Automation/exportFeaturesDialog.png
Binary files differ
diff --git a/Article-PDE-Automation/featureManifestEditor.png b/Article-PDE-Automation/featureManifestEditor.png
new file mode 100644
index 0000000..9f40738
--- /dev/null
+++ b/Article-PDE-Automation/featureManifestEditor.png
Binary files differ
diff --git a/Article-PDE-Automation/fetchProcessActivity.png b/Article-PDE-Automation/fetchProcessActivity.png
new file mode 100644
index 0000000..203f69b
--- /dev/null
+++ b/Article-PDE-Automation/fetchProcessActivity.png
Binary files differ
diff --git a/Article-PDE-Automation/figureOrdering.rb b/Article-PDE-Automation/figureOrdering.rb
new file mode 100644
index 0000000..02169c6
--- /dev/null
+++ b/Article-PDE-Automation/figureOrdering.rb
@@ -0,0 +1,51 @@
+
+def createFigureList(input)
+ figures = [] ;
+ input.each {
+ | line |
+ case line
+ when /Fig (\d*)(<.*$)/
+ puts "Found Figure: #{$1}"
+ figures << $1.to_i
+ when /Fig.[^\s]/
+ puts "WARNING: No space after figure reference: " + line ;
+ end
+ }
+ return figures ;
+end
+
+def createMap(figures)
+ map = Hash.new ;
+ (1..figures.length).each {
+ | i |
+ map[figures[i-1]] = i;
+ }
+ return map ;
+end
+
+def replace(input, map, output)
+ replacedReferences = []
+ input.each {
+ | line |
+ output.write line.gsub(/(:?Fig(:?\.)?) (\d*)/) {
+ | s |
+ replacedReferences << $3.to_i if $2 == "." ;
+ "Fig#{$2} #{map[$3.to_i]}"
+ }
+ }
+ unreplacedReferences = map.keys.sort ;
+ unreplacedReferences.delete_if { | ref | replacedReferences.include?(ref) }
+ puts "Unreplaced References: "
+ puts unreplacedReferences ;
+end
+
+input = File.open("article.html")
+figures = createFigureList(input) ;
+map = createMap(figures)
+map.keys.sort.each { |k| puts "#{k} => #{map[k]}" }
+$stdout.sync = true
+#puts "Replace (y/n)?" ;
+#gets.chomp
+input.rewind
+replace(input, map, File.new("article_replaced.html", "w")) ;
+
diff --git a/Article-PDE-Automation/runTestsInteractionDiagram.png b/Article-PDE-Automation/runTestsInteractionDiagram.png
new file mode 100644
index 0000000..c369190
--- /dev/null
+++ b/Article-PDE-Automation/runTestsInteractionDiagram.png
Binary files differ
diff --git a/Article-PDE-Automation/runTestsRdtInteractionDiagram.png b/Article-PDE-Automation/runTestsRdtInteractionDiagram.png
new file mode 100644
index 0000000..866a0a9
--- /dev/null
+++ b/Article-PDE-Automation/runTestsRdtInteractionDiagram.png
Binary files differ
diff --git a/Article-PDE-does-plugins/PDE-intro.html b/Article-PDE-does-plugins/PDE-intro.html
new file mode 100644
index 0000000..f004104
--- /dev/null
+++ b/Article-PDE-does-plugins/PDE-intro.html
@@ -0,0 +1,359 @@
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<title>PDE Does Plug-ins</title>
+<link rel="stylesheet" href="../default_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080">
+<div align="right"><font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2003 International Business Machines Corporation. All rights reserved</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+
+<h1 ALIGN="CENTER">PDE Does Plug-ins</h1>
+
+<blockquote>
+<b>Summary</b>
+
+<br>
+ <font face="Arial">The Plug-in Development Environment (PDE) provides a set
+ of tools that assist the developer in every stage of plug-in development from
+ genesis to deployment. This article chronicles the creation, development, testing,
+ building, and deployment of a simple &quot;Hello World&quot; plug-in using a
+ subset of these tools.</font>
+ <p><b> By Wassim Melhem and Dejan Glozic, IBM Canada Ltd.</b><br>
+ <font size="-1">September 8, 2003</font></p>
+</blockquote>
+
+<hr width="100%">
+<h2>Why PDE?</h2>
+<p>A plug-in is the fundamental building block of the Eclipse platform. Eclipse
+ is the sum of its constituent plug-ins, where each plug-in contributes functionality
+ to the platform and is activated when the functionality it provides is needed.
+ Structurally, each plug-in resides in a subdirectory called eclipse/plugins
+ in the Eclipse installation, and contains a manifest (plugin.xml) file that
+ describes its content to the Eclipse runtime. A plug-in may also include a Java&trade;
+ code library and other resource files it needs, such as icons, properties files,
+ etc.</p>
+<p align="center">
+<img border="0" src="images/directory.gif" width="575" height="369"></p>
+<p align="left"> Writing an Eclipse plug-in is straight forward, but not exactly
+ trivial. The task entails creating a manifest file, writing Java source code,
+ compiling the code into a library, testing it and packaging the plug-in into
+ a form that is suitable for deployment. This task can be quite intricate, depending
+ on the complexity of the plug-in and the developer's Eclipse expertise. Enter
+ PDE.</p>
+<p>The Plug-in Development Environment (PDE) is a set of tools designed to assist
+ the Eclipse developer in developing, testing, debugging, building, and deploying
+ Eclipse plug-ins while working inside the Eclipse workbench. Keeping with
+ Eclipse's philosophy of seamless integration of components, PDE is not a separately
+ launched tool. PDE integrates itself in the workbench by providing platform
+ contributions, such as editors, wizards, views and a launcher, which users can
+ easily access from any perspective without interrupting their work flow. </p>
+<p>This article showcases a subset of PDE tools that are available in Eclipse
+ 2.1 by chronicling the journey of one plug-in from genesis to deployment. The
+ plug-in will contribute to the Eclipse workbench a menu containing a single
+ item which, when selected, will pop up a dialog containing the phrase &quot;Hello,
+ world!&quot;</p>
+<h2>Configuring PDE</h2>
+<p>In order for PDE to provide a development environment that is identical to
+the runtime environment in which the plug-in will be later deployed, one needs
+to specify the <b>Target</b> <b>Platform</b>. Target<b> </b>platform refers to the set of plug-ins with which the plug-in
+being developed will be deployed. At runtime, most plug-ins require other plug-ins to be on their class path in order to
+run properly. At development time, a plug-in, which is
+represented as a project in the workspace, similarly requires that all the libraries for its required
+plug-ins be on its build path in order for its code to compile without errors. </p>
+<p>Libraries for required plug-ins can be easily made available to the workspace
+plug-in by simply specifying the installation location of the target platform.
+PDE scans and lists all the plug-ins found at that location, but only the
+plug-ins explicitly selected by the user will constitute the target platform and
+can be used by plug-ins in the workspace; the rest are ignored.</p>
+<p align="center">
+<img border="0" src="images/target_platform.gif" width="586" height="478" ></p>
+<p align="left">
+<img src="images/tip.gif" width="62" height="13"> Plug-ins from the target
+platform are
+not part of the workspace, and their contents therefore cannot be browsed in Eclipse's Navigator
+and Package
+Explorer views. PDE thus provides a <b>Plug-ins </b>
+view where the directory structure of these external plug-ins can be browsed and
+external files can be opened (in read-only mode, of course).</p>
+<h2>Creating a New Plug-in Project</h2>
+<p>In the workspace, a plug-in is encapsulated in a single project. At its
+top level, the project must contain a manifest file, describing the plug-in
+content, and a build.properties file, containing information that is used
+to guide the build process. To create a plug-in project,
+PDE provides a <b>New Plug-in Project </b>wizard, which can be found under the
+<b>Plug-in Development</b> category in the <b>New Project</b> creation wizard.
+This wizard not only creates the plug-in project, it also gives the developer a quick
+start by generating the two essential plug-in files and, optionally, some Java
+code.</p>
+<p align="center">
+<img border="0" src="images/plugin_project_1.gif" width="500" height="500" ></p>
+<p align="left">Most plug-ins, including the &quot;Hello World&quot; plug-in, are meant
+to contain executable Java code and must therefore be housed in a Java project.
+In such cases, one can specify the source folder that will contain
+the plug-in code during development, and the library where the compiled code
+will be packaged. PDE maps the library name to the source
+folder and saves that information in the plug-in project's build.properties
+file, so that it can be used later during the build process. One can
+also specify the output folder, where the Java compiler will place the compiled
+*.class files of the project. When launching a runtime workbench instance to run
+or debug the plug-in, PDE will put this output folder on the plug-in
+runtime classpath, thus allowing the runtime class loader to locate and load the
+freshly generated class files.</p>
+<p align="left"> <img src="images/tip.gif" width="62" height="13"> Not all plug-ins contain Java code.
+Plug-ins such as documentation plug-ins contain only non-Java resources, and
+can therefore be sufficiently contained in simple projects. In fact, it is
+desirable to create simple projects for such plug-ins, so that they would not
+unnecessarily be subjected to Java builders.</p>
+<p align="center">
+<img border="0" src="images/plugin_project_2.gif" width="500" height="500" ></p>
+<p align="left">
+The ability to create a plug-in with a ready-to-run extension is appealing,
+particularly to novice Eclipse developers. Therefore, templates for
+Eclipse's more popular extensions are available during the plug-in project
+creation process. Writing an Eclipse extension always
+involves adding markup to the manifest file, and if required, accompanying Java
+code that gets executed upon the invocation of the extension. The
+code generation wizards generate all the markup and code needed to produce a
+customizable and fully-functioning extension. </p>
+<p>Selecting the &quot;Hello, World&quot; template wizard from the list above
+ results in the creation of a &quot;Hello World&quot; plug-in that is ready to
+ run. That is great, but would make this paper extremely short. In
+ this example, we will create a blank plug-in project, so that we can demonstrate
+ how to write a plug-in from scratch.</p>
+<p>As a result of our selections, the wizard generates the plug-in project, the
+ manifest file, the build.properties file and initializes the content of these
+ two files based on the data entered in the wizard. Let us now proceed with the
+ implementation of the plug-in, starting with the editing of the manifest file.</p>
+<p align="center">
+<img border="0" src="images/project.gif" width="295" height="180"></p>
+<h2>Editing the Plug-in Manifest File</h2>
+<p>The manifest file describes the content of the plug-in to the Eclipse runtime.
+ In addition to basic plug-in information such as plug-in identifier, version,
+ etc., this file contains four main sections:</p>
+<ol>
+ <li>A Dependencies section listing all the plug-ins required by the plug-in.
+ A plug-in must list as dependencies all the plug-ins needed for its code to
+ compile and all the plug-ins contributing extension points that it is using.</li>
+ <li>An Extensions section declaring all the functionalities that this plug-in
+ contributes to the platform by extending other plug-ins' extension points.</li>
+ <li>A Runtime section declaring the libraries where the plug-in code is
+ packaged. At runtime, the class loader searches these libraries when
+ loading the plug-in's classes.</li>
+ <li>An Extension Points section declaring new function points defined by this
+ plug-in which other plug-ins can extend (i.e., provide an implementation for).
+ For example, the Platform UI plug-in provides an editor extension point, which
+ other plug-ins can extend to implement and contribute a new editor to the
+ platform.</li>
+</ol>
+<p>Let us now edit the different sections of the plug-in
+manifest file using the PDE multi-page UI editor, the default editor for manifest
+files in Eclipse.</p>
+<h3 align="left">Dependencies</h3>
+<p>Contributing a menu to the workbench requires extending the <i>actionSets</i>
+ extension point that is defined by the <i>org.eclipse.ui</i> plug-in. Therefore,
+ the &quot;Hello World&quot; plug-in must declare this plug-in as a dependency.
+ By doing so, in addition to providing access to the extension point, the libraries
+ of <i> org.eclipse.ui</i> will be on the plug-in's runtime classpath.</p>
+<p align="center">
+<img border="0" src="images/dependencies_page.gif" width="532" height="380"></p>
+<p>The list of required plug-ins solely determines the libraries that will be
+ on the plug-in's runtime classpath. PDE takes charge of the vital task of computing
+ the plug-in project's classpath during development time, so that it accurately
+ reflects the runtime classpath. Upon saving the manifest file, PDE automatically
+ updates the project's classpath to reflect changes made to the dependency list,
+ if any. This feature is an invaluable utility because the alternative, i.e.,
+ computing the classpath manually, is tedious and error-prone.</p>
+<p>The list of required plug-ins should not contain unused entries. An incomplete list of dependencies is easy to spot at development
+time because the plug-in's code will not compile in the workspace.
+Extraneous entries, on the other hand, are harder to spot because they are
+benign at development time, but can slow down class loading at runtime as extra
+libraries on the plug-in's runtime classpath will unnecessarily be searched. PDE, therefore, provides a <b>
+Find Unused Dependencies</b> utility as an item in the required plug-ins list's
+context menu, which scans the dependency list for extraneous entries and offers
+to remove them.</p>
+<p> <img src="images/tip.gif" width="61" height="13"> The plug-ins <i>
+org.eclipse.core.boot</i> and <i>org.eclipse.core.runtime</i> are implicitly
+available for all plug-ins at runtime, and therefore need not be explicitly
+listed as required plug-ins.</p>
+<h3>Extensions</h3>
+<p style="font-family: arial, helvetica, geneva; font-size: 10pt">A plug-in can
+contribute new functionality to the platform by adding an extension to extension
+points declared by other plug-ins. The extension declaration must follow the schema
+defined by the extension point it contributes to. The schema can be as simple or as complex as the author of the
+extension point defines it to be. </p>
+<p style="font-family: arial, helvetica, geneva; font-size: 10pt">Adding a new
+ extension on the Extensions page of the manifest editor involves creating nested
+ elements using the context menu, and setting attribute values for these elements
+ in the Properties view. When adding a new extension, PDE uses the grammar of
+ the extension point to fill the context menu with valid element names and populate
+ the property view with the legal attributes for the selected element.</p>
+<p style="font-family: arial, helvetica, geneva; font-size: 10pt">Menus and menu
+ items, which, along with toolbar actions, are collectively referred to as action
+ sets, can be added to the workbench by contributing to the <i>org.eclipse.ui.actionSets</i>
+ extension point. The top-level element of this extension is an 'actionSet'
+ element specifying its unique internal identifier, as well as its label and
+ visibility in the workbench. When the attribute 'visible' is set to 'true',
+ the action set will be visible in all perspectives; otherwise, the action set
+ will have to be manually added to a perspective by choosing <b>Window &gt; Customize
+ Perspective... &gt; Other</b>.</p>
+<p align="center">
+<img border="0" src="images/extensions.gif" width="602" height="233"></p>
+<p align="left">
+The 'menu' element specifies the label of the menu as it will appear in the
+workbench and the internal identifier of the menu.</p>
+<p align="center">
+<img border="0" src="images/extensions2.gif" width="523" height="230"></p>
+<p align="left">
+The 'separator' element creates a menu separator that also serves as a group to
+which the menu item will be added.</p>
+<p align="center">
+<img border="0" src="images/extensions3.gif" width="502" height="232"></p>
+<p align="left"> The 'action' element specifies the actual menu item. Using
+ the menu's identifier and the separator's name, the 'menubarPath' attribute
+ indicates the slot where the item is to be placed. When the menu action
+ is selected, the class that will be executed to display the &quot;Hello, world!&quot;
+ message is the one specified by the 'class' attribute. The schema indicates
+ that this class must implement the interface <i>org.eclipse.ui.IWorkbenchWindowActionDelegate</i>;
+ PDE therefore customizes the value field for the 'class' property to allow one
+ to specify and generates on the spot a Java class that implements the specified
+ interface.</p>
+<p align="center">
+<img border="0" src="images/extensions4.gif" width="682" height="381"></p>
+<p align="left"> PDE generates the class, complete with the stubs for all the
+ required methods. The init(..) and run(..) method need to be manually
+ fleshed out as below:</p>
+<p>
+<img border="0" src="images/sample_action_code.gif" width="588" height="502"></p>
+<h3>Runtime</h3>
+<p>During the plug-in project creation process, we had specified that the code is to be packaged in a library named 'helloworld.jar'.
+The library's type, visibility, and content can be set
+on the <b>Runtime</b> page of the manifest editor.</p>
+<p align="center">
+<img border="0" src="images/runtime_page.gif" width="495" height="555" ></p>
+<p>A library's <b>type</b> plays an important role at runtime. If a library is
+ declared to contain both code and resources, accessing a resource or a class
+ file from such a library results in the activation of the plug-in. On the other
+ hand, accessing a resource from a library that is declared to contain only resources,
+ e.g., libraries that only contain NL-*.properties files, does not activate the
+ plug-in. </p>
+<p>In order to speed up class loading, one should always declare the package
+prefixes that are found in each library. A library will not be searched
+during class loading unless its list of package prefixes contains a prefix for
+the fully qualified name of the class being searched for. Libraries that
+do not declare a list of package prefixes will be searched during the loading of
+every class.</p>
+<p>During development, the library JAR has not been created yet. The <b>Library Content</b> section lists the source folders
+that will be compiled into the selected library during the build process.
+Whenever the user modifies this list, PDE automatically updates the appropriate entries in the plug-in
+project's build.properties file.</p>
+<h3>Extension Points</h3>
+<p>Defining a new extension point requires the writing of a schema, which all
+clients of the extension point must then follow in order to be processed
+correctly at runtime. PDE provides an editor for the composition of such a
+schema. However, since the &quot;Hello World&quot; plug-in does not contribute new
+extension points, we will leave the discussion of extension points and schemas
+for a future article.</p>
+<h2>Testing the Plug-in</h2>
+<p>PDE contributes to the platform a launcher that allows one to test and debug
+plug-ins. One can create and run a runtime workbench launch configuration
+to spawn a second (runtime) workbench instance, whose constituent plug-ins are
+the workspace plug-ins and all selected external plug-ins in the target platform. The
+runtime workbench instance thus previews the behavior of the plug-ins in the
+environment in which they will later be deployed.</p>
+<p>The runtime workbench instance is launched in development mode (i.e., with
+ the <i>-dev</i> option), so the output folder of the plug-in project is put
+ on the runtime classpath of the corresponding plug-in. This allows the runtime
+ class loader to always locate and load the plug-in's freshest class files. All
+ other execution options and settings with which to launch the runtime workbench
+ are set in the launch configuration itself. These settings include the JRE,
+ VM arguments, and all the program execution options supported by the Eclipse
+ platform. The workspace location for the runtime workbench is also specified
+ in the configuration, and must be different from the workspace location of the
+ host platform as one definitely needs to test their plug-in in a sandbox. One
+ may create multiple configurations to test their plug-ins under different conditions.</p>
+<p align="center">
+<img border="0" src="images/launcher_1.gif" width="671" height="525"></p>
+<p> <img src="images/tip.gif" width="61" height="13"> PDE uses the values specified
+ on the <b>Plug-in Development &gt; Target Environment</b> preference page to
+ set the default values for the -<i>os</i>, -<i>ws</i>, -<i>arch</i> and -<i>nl</i>
+ arguments in the configuration. Changes made to these values in the configuration
+ are local to that configuration. Changes made to values on the preference page
+ affect the defaults for all configurations that are created thereafter.</p>
+<p align="left"> When the launch configuration in our example is run, the runtime
+ workbench will appear within seconds. The &quot;Hello World Menu&quot; menu
+ will appear at the top, containing one item &quot;Hello World Action&quot;.
+ When this item is selected, a dialog pops us to greet the world.</p>
+<p align="center">
+<img border="0" src="images/dialog.gif" width="497" height="235"></p>
+<h2>Exporting the Plug-in into a Deployable Zip</h2>
+<p>The last stage in the life cycle of a workspace plug-in is its packaging in
+a format that will make it easily deployable in any Eclipse-based product.</p>
+<p>The process of packaging a plug-in project is driven by the build.properties
+ configuration file. This file is structured as a set of key-value pairs, where
+ the keys are defined by Eclipse's build process, and provides information about
+ the mapping of source folder to jars, what files to include in the packaged
+ plug-in, what files to exclude, etc.</p>
+<p>Two of these keys are used in the building
+of the &quot;Hello World&quot; plug-in:</p>
+<ul>
+ <li><b><font face="Arial">source.&lt;library&gt;</font></b> - The value is a
+ comma-separated list of the source folders to be compiled into the library
+ specified. This key is maintained up-to-date by PDE using the data entered
+ on the Runtime page of the manifest editor.</li>
+ <li><b><font face="Arial">bin.includes</font></b> - The value is a comma-separated
+ list of the files and folders to include in the binary build. While an initial
+ value for this key is set by PDE during the plug-in project creation process,
+ it is up to the developer to maintain this key and explicitly specify all
+ the files and folders to be included in the packaged plug-in. For this sample
+ plug-in, plugin.xml and helloworld.jar are the only two files to be included
+ in the build.</li>
+</ul>
+<p>To package and export the plug-in, the <b>Deployable Plug-ins and Fragments
+</b>export wizard is used.</p>
+<p align="center">
+<img border="0" src="images/export_wizard.gif" width="563" height="550"></p>
+<p align="left">The zip file generated then simply needs to be unzipped into the installation
+directory of any Eclipse-based product and the plug-in becomes part of that
+product.</p>
+<p align="center">
+<img border="0" src="images/deploy.gif" width="570" height="295"></p>
+<h2 align="left">Conclusion</h2>
+<p align="left">Using a simple &quot;Hello World&quot; plug-in as an example,
+ this article demonstrates how PDE provides all the tools necessary to develop
+ an Eclipse plug-in more easily and more quickly. The plug-in project creation
+ wizard gives a quick start by generating the project along with the plugin.xml
+ and build.properties files. The code generation wizards generate code
+ and markup for Eclipse's more popular extension points, so that a novice Eclipse
+ developer can get their first plug-in up and running in a few minutes.
+ The manifest editor generates a syntactically and semantically valid manifest
+ file. The runtime workbench launcher allows the testing and debugging
+ of the plug-in in an environment that is identical to the runtime environment
+ in which it will be deployed. Finally, the plug-in export wizard turns
+ the tedious build and packaging process into a simple one-step operation.</p>
+<p align="left">While plug-ins seem to take center stage in the Eclipse architecture,
+ other components such as fragments, features and update sites play an important
+ role in the development of Eclipse products. In future articles we will discuss
+ the PDE tools available for the development of these components, as well as
+ take a detailed look at how to define new extension points.</p>
+
+<p><small>IBM is a registered trademark of International Business Machines Corporation
+ in the United States, other countries, or both.</small></p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+ trademarks of Sun Microsystems, Inc. in the United States, other countries,
+ or both.</small></p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/Article-PDE-does-plugins/images/Idea.jpg b/Article-PDE-does-plugins/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-PDE-does-plugins/images/Idea.jpg
Binary files differ
diff --git a/Article-PDE-does-plugins/images/compilers.gif b/Article-PDE-does-plugins/images/compilers.gif
new file mode 100644
index 0000000..8c98bac
--- /dev/null
+++ b/Article-PDE-does-plugins/images/compilers.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/dependencies_page.gif b/Article-PDE-does-plugins/images/dependencies_page.gif
new file mode 100644
index 0000000..f6c2afd
--- /dev/null
+++ b/Article-PDE-does-plugins/images/dependencies_page.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/deploy.gif b/Article-PDE-does-plugins/images/deploy.gif
new file mode 100644
index 0000000..3130df2
--- /dev/null
+++ b/Article-PDE-does-plugins/images/deploy.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/dialog.gif b/Article-PDE-does-plugins/images/dialog.gif
new file mode 100644
index 0000000..74d98dc
--- /dev/null
+++ b/Article-PDE-does-plugins/images/dialog.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/directory.gif b/Article-PDE-does-plugins/images/directory.gif
new file mode 100644
index 0000000..0cdd7e8
--- /dev/null
+++ b/Article-PDE-does-plugins/images/directory.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/export_wizard.gif b/Article-PDE-does-plugins/images/export_wizard.gif
new file mode 100644
index 0000000..a19e60d
--- /dev/null
+++ b/Article-PDE-does-plugins/images/export_wizard.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/extensions.gif b/Article-PDE-does-plugins/images/extensions.gif
new file mode 100644
index 0000000..6575538
--- /dev/null
+++ b/Article-PDE-does-plugins/images/extensions.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/extensions2.gif b/Article-PDE-does-plugins/images/extensions2.gif
new file mode 100644
index 0000000..15f4f54
--- /dev/null
+++ b/Article-PDE-does-plugins/images/extensions2.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/extensions3.gif b/Article-PDE-does-plugins/images/extensions3.gif
new file mode 100644
index 0000000..103d473
--- /dev/null
+++ b/Article-PDE-does-plugins/images/extensions3.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/extensions4.gif b/Article-PDE-does-plugins/images/extensions4.gif
new file mode 100644
index 0000000..950fa80
--- /dev/null
+++ b/Article-PDE-does-plugins/images/extensions4.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/launcher_1.gif b/Article-PDE-does-plugins/images/launcher_1.gif
new file mode 100644
index 0000000..aad680f
--- /dev/null
+++ b/Article-PDE-does-plugins/images/launcher_1.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/plugin_project_1.gif b/Article-PDE-does-plugins/images/plugin_project_1.gif
new file mode 100644
index 0000000..11e1b6f
--- /dev/null
+++ b/Article-PDE-does-plugins/images/plugin_project_1.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/plugin_project_2.gif b/Article-PDE-does-plugins/images/plugin_project_2.gif
new file mode 100644
index 0000000..79cefe4
--- /dev/null
+++ b/Article-PDE-does-plugins/images/plugin_project_2.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/project.gif b/Article-PDE-does-plugins/images/project.gif
new file mode 100644
index 0000000..108cf81
--- /dev/null
+++ b/Article-PDE-does-plugins/images/project.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/runtime_page.gif b/Article-PDE-does-plugins/images/runtime_page.gif
new file mode 100644
index 0000000..c00dca0
--- /dev/null
+++ b/Article-PDE-does-plugins/images/runtime_page.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/sample_action_code.gif b/Article-PDE-does-plugins/images/sample_action_code.gif
new file mode 100644
index 0000000..39055e5
--- /dev/null
+++ b/Article-PDE-does-plugins/images/sample_action_code.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/target_platform.gif b/Article-PDE-does-plugins/images/target_platform.gif
new file mode 100644
index 0000000..5ed9b72
--- /dev/null
+++ b/Article-PDE-does-plugins/images/target_platform.gif
Binary files differ
diff --git a/Article-PDE-does-plugins/images/tip.gif b/Article-PDE-does-plugins/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-PDE-does-plugins/images/tip.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/doc/allclasses-frame.html b/Article-Plug-in-architecture/doc/allclasses-frame.html
new file mode 100644
index 0000000..bead2ef
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/allclasses-frame.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+All Classes
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameHeadingFont">
+<B>All Classes</B></FONT>
+<BR>
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/service/errortest/Dummy.html" TARGET="classFrame">Dummy</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/service/echo/Echo.html" TARGET="classFrame">Echo</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html" TARGET="classFrame">Exponentiation</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/service/ui/FunctionsGrid.html" TARGET="classFrame">FunctionsGrid</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html" TARGET="classFrame">FunctionsViewPart</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/service/ui/IFunction.html" TARGET="classFrame"><I>IFunction</I></A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/listener/subject/IListener.html" TARGET="classFrame"><I>IListener</I></A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/demo/IProcessMember.html" TARGET="classFrame"><I>IProcessMember</I></A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html" TARGET="classFrame">ListenerX</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html" TARGET="classFrame">ListenerX</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html" TARGET="classFrame">ListenerY</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html" TARGET="classFrame">ListenerY</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/service/multiplication/Multiplication.html" TARGET="classFrame">Multiplication</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/demo/PrintMemberIdentity.html" TARGET="classFrame">PrintMemberIdentity</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html" TARGET="classFrame">PrintMemberMenuAction</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/demo/ProcessExtensions.html" TARGET="classFrame">ProcessExtensions</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html" TARGET="classFrame">ProcessServiceMembers</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/listener/subject/Subject.html" TARGET="classFrame">Subject</A>
+<BR>
+<A HREF="com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html" TARGET="classFrame">UpdateMenuAction</A>
+<BR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/IProcessMember.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/IProcessMember.html
new file mode 100644
index 0000000..6963027
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/IProcessMember.html
@@ -0,0 +1,181 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Interface IProcessMember
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/IProcessMember.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IProcessMember.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.demo</FONT>
+<BR>
+Interface IProcessMember</H2>
+<DL>
+<DT><B>All Known Implementing Classes:</B> <DD><A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html">PrintMemberIdentity</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public interface <B>IProcessMember</B></DL>
+
+<P>
+Callback interface for processing each extension-point member
+ in generic extension processing.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html#process(org.eclipse.core.runtime.IExtension, org.eclipse.core.runtime.IConfigurationElement)">process</A></B>(org.eclipse.core.runtime.IExtension&nbsp;extension,
+ org.eclipse.core.runtime.IConfigurationElement&nbsp;member)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Process a particular member (top-level element) of an extension.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="process(org.eclipse.core.runtime.IExtension, org.eclipse.core.runtime.IConfigurationElement)"><!-- --></A><H3>
+process</H3>
+<PRE>
+public java.lang.Object <B>process</B>(org.eclipse.core.runtime.IExtension&nbsp;extension,
+ org.eclipse.core.runtime.IConfigurationElement&nbsp;member)</PRE>
+<DL>
+<DD>Process a particular member (top-level element) of an extension.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>extension</CODE> - The extension being processed.<DD><CODE>member</CODE> - The configuration element of the member of the extension to be processed.<DT><B>Returns:</B><DD>&nbsp;</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/IProcessMember.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IProcessMember.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/PrintMemberIdentity.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/PrintMemberIdentity.html
new file mode 100644
index 0000000..f765499
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/PrintMemberIdentity.html
@@ -0,0 +1,258 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class PrintMemberIdentity
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/PrintMemberIdentity.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="PrintMemberIdentity.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.demo</FONT>
+<BR>
+Class PrintMemberIdentity</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.demo.PrintMemberIdentity</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>PrintMemberIdentity</B><DT>extends java.lang.Object<DT>implements <A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A></DL>
+
+<P>
+Extension-point member-processing implementation class to print
+ identifying information about a member.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html#PrintMemberIdentity(java.lang.String)">PrintMemberIdentity</A></B>(java.lang.String&nbsp;memberLabelAttribute)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructor.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html#process(org.eclipse.core.runtime.IExtension, org.eclipse.core.runtime.IConfigurationElement)">process</A></B>(org.eclipse.core.runtime.IExtension&nbsp;extension,
+ org.eclipse.core.runtime.IConfigurationElement&nbsp;member)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Process a particular member (top-level element) of an extension.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html#test(java.lang.String, java.lang.String)">test</A></B>(java.lang.String&nbsp;extensionPoint,
+ java.lang.String&nbsp;memberLabelAttribute)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Print identification information for each member of each extension
+ of an extension-point.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="PrintMemberIdentity(java.lang.String)"><!-- --></A><H3>
+PrintMemberIdentity</H3>
+<PRE>
+public <B>PrintMemberIdentity</B>(java.lang.String&nbsp;memberLabelAttribute)</PRE>
+<DL>
+<DD>Constructor.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>memberLabelAttribute</CODE> - Name of an XML attribute of an extension member's
+ element acting as a label for that member.</DL>
+</DD>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="process(org.eclipse.core.runtime.IExtension, org.eclipse.core.runtime.IConfigurationElement)"><!-- --></A><H3>
+process</H3>
+<PRE>
+public java.lang.Object <B>process</B>(org.eclipse.core.runtime.IExtension&nbsp;extension,
+ org.eclipse.core.runtime.IConfigurationElement&nbsp;member)</PRE>
+<DL>
+<DD><B>Description copied from interface: <CODE><A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A></CODE></B></DD>
+<DD>Process a particular member (top-level element) of an extension.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE><A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html#process(org.eclipse.core.runtime.IExtension, org.eclipse.core.runtime.IConfigurationElement)">process</A></CODE> in interface <CODE><A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A></CODE></DL>
+</DD>
+<DD>Following copied from interface: <CODE>com.bolour.sample.eclipse.demo.IProcessMember</CODE></DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>extension</CODE> - The extension being processed.<DD><CODE>member</CODE> - The configuration element of the member of the extension to be processed.<DT><B>Returns:</B><DD>&nbsp;</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="test(java.lang.String, java.lang.String)"><!-- --></A><H3>
+test</H3>
+<PRE>
+public static void <B>test</B>(java.lang.String&nbsp;extensionPoint,
+ java.lang.String&nbsp;memberLabelAttribute)</PRE>
+<DL>
+<DD>Print identification information for each member of each extension
+ of an extension-point.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>extensionPoint</CODE> - The fully-qualified id of the extension-point.<DD><CODE>memberLabelAttribute</CODE> - Name of an XML attribute of each member to use
+ as its label.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/PrintMemberIdentity.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="PrintMemberIdentity.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html
new file mode 100644
index 0000000..3a11038
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html
@@ -0,0 +1,280 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class PrintMemberMenuAction
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/PrintMemberMenuAction.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/demo/ProcessExtensions.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="PrintMemberMenuAction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.demo</FONT>
+<BR>
+Class PrintMemberMenuAction</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.demo.PrintMemberMenuAction</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>org.eclipse.ui.IActionDelegate, org.eclipse.ui.IWorkbenchWindowActionDelegate</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>PrintMemberMenuAction</B><DT>extends java.lang.Object<DT>implements org.eclipse.ui.IWorkbenchWindowActionDelegate</DL>
+
+<P>
+Event handler for menu to print extension members.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#PrintMemberMenuAction()">PrintMemberMenuAction</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#dispose()">dispose</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#init(org.eclipse.ui.IWorkbenchWindow)">init</A></B>(org.eclipse.ui.IWorkbenchWindow&nbsp;window)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#run(org.eclipse.jface.action.IAction)">run</A></B>(org.eclipse.jface.action.IAction&nbsp;action)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The extension processing demo menu handler.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)">selectionChanged</A></B>(org.eclipse.jface.action.IAction&nbsp;action,
+ org.eclipse.jface.viewers.ISelection&nbsp;selection)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="PrintMemberMenuAction()"><!-- --></A><H3>
+PrintMemberMenuAction</H3>
+<PRE>
+public <B>PrintMemberMenuAction</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="dispose()"><!-- --></A><H3>
+dispose</H3>
+<PRE>
+public void <B>dispose</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>dispose</CODE> in interface <CODE>org.eclipse.ui.IWorkbenchWindowActionDelegate</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="init(org.eclipse.ui.IWorkbenchWindow)"><!-- --></A><H3>
+init</H3>
+<PRE>
+public void <B>init</B>(org.eclipse.ui.IWorkbenchWindow&nbsp;window)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>init</CODE> in interface <CODE>org.eclipse.ui.IWorkbenchWindowActionDelegate</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="run(org.eclipse.jface.action.IAction)"><!-- --></A><H3>
+run</H3>
+<PRE>
+public void <B>run</B>(org.eclipse.jface.action.IAction&nbsp;action)</PRE>
+<DL>
+<DD>The extension processing demo menu handler. Uses the class
+ <code>PrintMenuIdentity</code> to print identifying information
+ on each member of the <code>actionSets</code> extension-point.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>run</CODE> in interface <CODE>org.eclipse.ui.IActionDelegate</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)"><!-- --></A><H3>
+selectionChanged</H3>
+<PRE>
+public void <B>selectionChanged</B>(org.eclipse.jface.action.IAction&nbsp;action,
+ org.eclipse.jface.viewers.ISelection&nbsp;selection)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>selectionChanged</CODE> in interface <CODE>org.eclipse.ui.IActionDelegate</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/PrintMemberMenuAction.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/demo/ProcessExtensions.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="PrintMemberMenuAction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/ProcessExtensions.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/ProcessExtensions.html
new file mode 100644
index 0000000..f2b6b75
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/ProcessExtensions.html
@@ -0,0 +1,219 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class ProcessExtensions
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ProcessExtensions.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ProcessExtensions.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.demo</FONT>
+<BR>
+Class ProcessExtensions</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.demo.ProcessExtensions</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>ProcessExtensions</B><DT>extends java.lang.Object</DL>
+
+<P>
+Generic extension-processing class: for looping over all members
+ of all extensions of an extension-point, and calling a processing function on each.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/ProcessExtensions.html#ProcessExtensions()">ProcessExtensions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/ProcessExtensions.html#process(java.lang.String, com.bolour.sample.eclipse.demo.IProcessMember)">process</A></B>(java.lang.String&nbsp;xpid,
+ <A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A>&nbsp;processor)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loop over all members of all extensions of an extension-point.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="ProcessExtensions()"><!-- --></A><H3>
+ProcessExtensions</H3>
+<PRE>
+public <B>ProcessExtensions</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="process(java.lang.String, com.bolour.sample.eclipse.demo.IProcessMember)"><!-- --></A><H3>
+process</H3>
+<PRE>
+public static void <B>process</B>(java.lang.String&nbsp;xpid,
+ <A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A>&nbsp;processor)</PRE>
+<DL>
+<DD>Loop over all members of all extensions of an extension-point.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>xpid</CODE> - The fully-qualified name of the extension-point.<DD><CODE>processor</CODE> - An object to call back on with each member of the extension-point.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ProcessExtensions.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ProcessExtensions.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/IProcessMember.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/IProcessMember.html
new file mode 100644
index 0000000..8d6a60f
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/IProcessMember.html
@@ -0,0 +1,150 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Interface com.bolour.sample.eclipse.demo.IProcessMember
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IProcessMember.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Interface<br>com.bolour.sample.eclipse.demo.IProcessMember</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Packages that use <A HREF="../../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.demo"><B>com.bolour.sample.eclipse.demo</B></A></TD>
+<TD>
+Generic extension processing demo.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.demo"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Uses of <A HREF="../../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A> in <A HREF="../../../../../../com/bolour/sample/eclipse/demo/package-summary.html">com.bolour.sample.eclipse.demo</A></FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2>Classes in <A HREF="../../../../../../com/bolour/sample/eclipse/demo/package-summary.html">com.bolour.sample.eclipse.demo</A> that implement <A HREF="../../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html">PrintMemberIdentity</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Extension-point member-processing implementation class to print
+ identifying information about a member.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2>Methods in <A HREF="../../../../../../com/bolour/sample/eclipse/demo/package-summary.html">com.bolour.sample.eclipse.demo</A> with parameters of type <A HREF="../../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B>ProcessExtensions.</B><B><A HREF="../../../../../../com/bolour/sample/eclipse/demo/ProcessExtensions.html#process(java.lang.String, com.bolour.sample.eclipse.demo.IProcessMember)">process</A></B>(java.lang.String&nbsp;xpid,
+ <A HREF="../../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A>&nbsp;processor)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loop over all members of all extensions of an extension-point.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IProcessMember.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/PrintMemberIdentity.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/PrintMemberIdentity.html
new file mode 100644
index 0000000..420ce32
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/PrintMemberIdentity.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.demo.PrintMemberIdentity
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="PrintMemberIdentity.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.demo.PrintMemberIdentity</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.demo.PrintMemberIdentity
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="PrintMemberIdentity.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/PrintMemberMenuAction.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/PrintMemberMenuAction.html
new file mode 100644
index 0000000..05ff55b
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/PrintMemberMenuAction.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.demo.PrintMemberMenuAction
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="PrintMemberMenuAction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.demo.PrintMemberMenuAction</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.demo.PrintMemberMenuAction
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="PrintMemberMenuAction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/ProcessExtensions.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/ProcessExtensions.html
new file mode 100644
index 0000000..6cf771f
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/class-use/ProcessExtensions.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.demo.ProcessExtensions
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../com/bolour/sample/eclipse/demo/ProcessExtensions.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ProcessExtensions.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.demo.ProcessExtensions</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.demo.ProcessExtensions
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../com/bolour/sample/eclipse/demo/ProcessExtensions.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ProcessExtensions.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-frame.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-frame.html
new file mode 100644
index 0000000..832d85a
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-frame.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.demo
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../../com/bolour/sample/eclipse/demo/package-summary.html" TARGET="classFrame">com.bolour.sample.eclipse.demo</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="IProcessMember.html" TARGET="classFrame"><I>IProcessMember</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="PrintMemberIdentity.html" TARGET="classFrame">PrintMemberIdentity</A>
+<BR>
+<A HREF="PrintMemberMenuAction.html" TARGET="classFrame">PrintMemberMenuAction</A>
+<BR>
+<A HREF="ProcessExtensions.html" TARGET="classFrame">ProcessExtensions</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-summary.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-summary.html
new file mode 100644
index 0000000..97357de
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-summary.html
@@ -0,0 +1,164 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.demo
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV PACKAGE&nbsp;
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package com.bolour.sample.eclipse.demo
+</H2>
+
+Generic extension processing demo.
+<P>
+<B>See: </B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="IProcessMember.html"><I>IProcessMember</I></A></B></TD>
+<TD>Callback interface for processing each extension-point member
+ in generic extension processing.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="PrintMemberIdentity.html">PrintMemberIdentity</A></B></TD>
+<TD>Extension-point member-processing implementation class to print
+ identifying information about a member.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="PrintMemberMenuAction.html">PrintMemberMenuAction</A></B></TD>
+<TD>Event handler for menu to print extension members.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="ProcessExtensions.html">ProcessExtensions</A></B></TD>
+<TD>Generic extension-processing class: for looping over all members
+ of all extensions of an extension-point, and calling a processing function on each.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package com.bolour.sample.eclipse.demo Description
+</H2>
+
+<P>
+<h2>
+Generic extension processing demo.
+</h2>
+
+<p>
+This package includes a demo of extension processing.
+The plug-in provides a menu item <i>Demo-&gt;Print&nbsp;Extension&nbsp;Members</i>.
+Invoking this menu item prints a list of the members of the <i>actionSets</i>
+extension to the console.
+
+<p>
+By providing explicit parameters to the demo test procedure in class
+<code>PrintMemberIdentity</code> you can
+print out member lists of other extension-points.
+
+<p>
+And by providing your own member-processing class that implements
+the <code>IProcessMember</code> interface in this package, you can provide
+custom extension processing procedures for members of an
+extension-point.
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV PACKAGE&nbsp;
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-tree.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-tree.html
new file mode 100644
index 0000000..8c347a1
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-tree.html
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: com.bolour.sample.eclipse.demo Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package com.bolour.sample.eclipse.demo
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.demo.<A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html"><B>PrintMemberIdentity</B></A> (implements com.bolour.sample.eclipse.demo.<A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.demo.<A HREF="../../../../../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html"><B>PrintMemberMenuAction</B></A> (implements org.eclipse.ui.IWorkbenchWindowActionDelegate)
+<LI TYPE="circle">class com.bolour.sample.eclipse.demo.<A HREF="../../../../../com/bolour/sample/eclipse/demo/ProcessExtensions.html"><B>ProcessExtensions</B></A></UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">interface com.bolour.sample.eclipse.demo.<A HREF="../../../../../com/bolour/sample/eclipse/demo/IProcessMember.html"><B>IProcessMember</B></A></UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;<A HREF="../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-use.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-use.html
new file mode 100644
index 0000000..c59d570
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/demo/package-use.html
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Package com.bolour.sample.eclipse.demo
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>com.bolour.sample.eclipse.demo</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Packages that use <A HREF="../../../../../com/bolour/sample/eclipse/demo/package-summary.html">com.bolour.sample.eclipse.demo</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.demo"><B>com.bolour.sample.eclipse.demo</B></A></TD>
+<TD>
+Generic extension processing demo.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.demo"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Classes in <A HREF="../../../../../com/bolour/sample/eclipse/demo/package-summary.html">com.bolour.sample.eclipse.demo</A> used by <A HREF="../../../../../com/bolour/sample/eclipse/demo/package-summary.html">com.bolour.sample.eclipse.demo</A><TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../../../com/bolour/sample/eclipse/demo/class-use/IProcessMember.html#com.bolour.sample.eclipse.demo"><B>IProcessMember</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback interface for processing each extension-point member
+ in generic extension processing.</TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html
new file mode 100644
index 0000000..1c82bd6
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html
@@ -0,0 +1,216 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class ListenerX
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ListenerX.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerX.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.listener.firstlistener</FONT>
+<BR>
+Class ListenerX</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.listener.firstlistener.ListenerX</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>ListenerX</B><DT>extends java.lang.Object<DT>implements <A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></DL>
+
+<P>
+Callback object of type X.
+<P>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html#ListenerX()">ListenerX</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html#listen()">listen</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trivial listener class: print out an information message to standard output.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="ListenerX()"><!-- --></A><H3>
+ListenerX</H3>
+<PRE>
+public <B>ListenerX</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="listen()"><!-- --></A><H3>
+listen</H3>
+<PRE>
+public void <B>listen</B>()</PRE>
+<DL>
+<DD>Trivial listener class: print out an information message to standard output.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html#listen()">listen</A></CODE> in interface <CODE><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ListenerX.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerX.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html
new file mode 100644
index 0000000..7299ab1
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html
@@ -0,0 +1,216 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class ListenerY
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ListenerY.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerY.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.listener.firstlistener</FONT>
+<BR>
+Class ListenerY</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.listener.firstlistener.ListenerY</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>ListenerY</B><DT>extends java.lang.Object<DT>implements <A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></DL>
+
+<P>
+Callback object of type Y.
+<P>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html#ListenerY()">ListenerY</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html#listen()">listen</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trivial listener class: print out an information message to standard output.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="ListenerY()"><!-- --></A><H3>
+ListenerY</H3>
+<PRE>
+public <B>ListenerY</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="listen()"><!-- --></A><H3>
+listen</H3>
+<PRE>
+public void <B>listen</B>()</PRE>
+<DL>
+<DD>Trivial listener class: print out an information message to standard output.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html#listen()">listen</A></CODE> in interface <CODE><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ListenerY.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerY.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/class-use/ListenerX.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/class-use/ListenerX.html
new file mode 100644
index 0000000..786c730
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/class-use/ListenerX.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.listener.firstlistener.ListenerX
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerX.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.listener.firstlistener.ListenerX</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.listener.firstlistener.ListenerX
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerX.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/class-use/ListenerY.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/class-use/ListenerY.html
new file mode 100644
index 0000000..0626b06
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/class-use/ListenerY.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.listener.firstlistener.ListenerY
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerY.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.listener.firstlistener.ListenerY</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.listener.firstlistener.ListenerY
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerY.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-frame.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-frame.html
new file mode 100644
index 0000000..0a61890
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-frame.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.listener.firstlistener
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-summary.html" TARGET="classFrame">com.bolour.sample.eclipse.listener.firstlistener</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="ListenerX.html" TARGET="classFrame">ListenerX</A>
+<BR>
+<A HREF="ListenerY.html" TARGET="classFrame">ListenerY</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-summary.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-summary.html
new file mode 100644
index 0000000..df9d3c2
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-summary.html
@@ -0,0 +1,130 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.listener.firstlistener
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/demo/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package com.bolour.sample.eclipse.listener.firstlistener
+</H2>
+
+A sample listener plug-in package.
+<P>
+<B>See: </B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="ListenerX.html">ListenerX</A></B></TD>
+<TD>Callback object of type X.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="ListenerY.html">ListenerY</A></B></TD>
+<TD>Callback object of type Y.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package com.bolour.sample.eclipse.listener.firstlistener Description
+</H2>
+
+<P>
+<h2>
+A sample listener plug-in package.
+</h2>
+
+<p>
+Provides two listeners that extend the <code>listeners</code>
+extension-point of the plug-in <code>com.bolour.sample.eclipse.listener.subject</code>.
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/demo/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-tree.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-tree.html
new file mode 100644
index 0000000..78c47ab
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-tree.html
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: com.bolour.sample.eclipse.listener.firstlistener Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/demo/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package com.bolour.sample.eclipse.listener.firstlistener
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html"><B>ListenerX</B></A> (implements com.bolour.sample.eclipse.listener.subject.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html"><B>ListenerY</B></A> (implements com.bolour.sample.eclipse.listener.subject.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>)
+</UL>
+</UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/demo/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-use.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-use.html
new file mode 100644
index 0000000..a2638d2
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/firstlistener/package-use.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Package com.bolour.sample.eclipse.listener.firstlistener
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>com.bolour.sample.eclipse.listener.firstlistener</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.listener.firstlistener
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html
new file mode 100644
index 0000000..ab3e62d
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html
@@ -0,0 +1,216 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class ListenerX
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ListenerX.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerX.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.listener.secondlistener</FONT>
+<BR>
+Class ListenerX</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.listener.secondlistener.ListenerX</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>ListenerX</B><DT>extends java.lang.Object<DT>implements <A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></DL>
+
+<P>
+Callback object of type X.
+<P>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html#ListenerX()">ListenerX</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html#listen()">listen</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trivial listener class: print out an information message to standard output.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="ListenerX()"><!-- --></A><H3>
+ListenerX</H3>
+<PRE>
+public <B>ListenerX</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="listen()"><!-- --></A><H3>
+listen</H3>
+<PRE>
+public void <B>listen</B>()</PRE>
+<DL>
+<DD>Trivial listener class: print out an information message to standard output.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html#listen()">listen</A></CODE> in interface <CODE><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ListenerX.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerX.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html
new file mode 100644
index 0000000..420263b
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html
@@ -0,0 +1,216 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class ListenerY
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ListenerY.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerY.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.listener.secondlistener</FONT>
+<BR>
+Class ListenerY</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.listener.secondlistener.ListenerY</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>ListenerY</B><DT>extends java.lang.Object<DT>implements <A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></DL>
+
+<P>
+Callback object of type Y.
+<P>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html#ListenerY()">ListenerY</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html#listen()">listen</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trivial listener class: print out an information message to standard output.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="ListenerY()"><!-- --></A><H3>
+ListenerY</H3>
+<PRE>
+public <B>ListenerY</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="listen()"><!-- --></A><H3>
+listen</H3>
+<PRE>
+public void <B>listen</B>()</PRE>
+<DL>
+<DD>Trivial listener class: print out an information message to standard output.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html#listen()">listen</A></CODE> in interface <CODE><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ListenerY.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerY.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/class-use/ListenerX.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/class-use/ListenerX.html
new file mode 100644
index 0000000..7ed114c
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/class-use/ListenerX.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.listener.secondlistener.ListenerX
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerX.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.listener.secondlistener.ListenerX</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.listener.secondlistener.ListenerX
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerX.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/class-use/ListenerY.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/class-use/ListenerY.html
new file mode 100644
index 0000000..eb3d8f7
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/class-use/ListenerY.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.listener.secondlistener.ListenerY
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerY.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.listener.secondlistener.ListenerY</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.listener.secondlistener.ListenerY
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ListenerY.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-frame.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-frame.html
new file mode 100644
index 0000000..bfd70cd
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-frame.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.listener.secondlistener
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/package-summary.html" TARGET="classFrame">com.bolour.sample.eclipse.listener.secondlistener</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="ListenerX.html" TARGET="classFrame">ListenerX</A>
+<BR>
+<A HREF="ListenerY.html" TARGET="classFrame">ListenerY</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-summary.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-summary.html
new file mode 100644
index 0000000..c82fafa
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-summary.html
@@ -0,0 +1,130 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.listener.secondlistener
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package com.bolour.sample.eclipse.listener.secondlistener
+</H2>
+
+A sample listener plug-in package.
+<P>
+<B>See: </B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="ListenerX.html">ListenerX</A></B></TD>
+<TD>Callback object of type X.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="ListenerY.html">ListenerY</A></B></TD>
+<TD>Callback object of type Y.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package com.bolour.sample.eclipse.listener.secondlistener Description
+</H2>
+
+<P>
+<h2>
+A sample listener plug-in package.
+</h2>
+
+<p>
+Provides two listeners that extend the <code>listeners</code>
+extension-point of the plug-in <code>com.bolour.sample.eclipse.listener.subject</code>.
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-tree.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-tree.html
new file mode 100644
index 0000000..11f889b
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-tree.html
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: com.bolour.sample.eclipse.listener.secondlistener Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package com.bolour.sample.eclipse.listener.secondlistener
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html"><B>ListenerX</B></A> (implements com.bolour.sample.eclipse.listener.subject.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html"><B>ListenerY</B></A> (implements com.bolour.sample.eclipse.listener.subject.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>)
+</UL>
+</UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-use.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-use.html
new file mode 100644
index 0000000..79a5ba8
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/secondlistener/package-use.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Package com.bolour.sample.eclipse.listener.secondlistener
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>com.bolour.sample.eclipse.listener.secondlistener</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.listener.secondlistener
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/IListener.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/IListener.html
new file mode 100644
index 0000000..e2263a1
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/IListener.html
@@ -0,0 +1,175 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Interface IListener
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/IListener.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IListener.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.listener.subject</FONT>
+<BR>
+Interface IListener</H2>
+<DL>
+<DT><B>All Known Implementing Classes:</B> <DD><A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html">ListenerX</A>, <A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html">ListenerX</A>, <A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html">ListenerY</A>, <A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html">ListenerY</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public interface <B>IListener</B></DL>
+
+<P>
+Callback interface for listeners.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html#listen()">listen</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Notification callback method.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="listen()"><!-- --></A><H3>
+listen</H3>
+<PRE>
+public void <B>listen</B>()</PRE>
+<DL>
+<DD>Notification callback method.</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/IListener.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IListener.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/Subject.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/Subject.html
new file mode 100644
index 0000000..bb918f6
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/Subject.html
@@ -0,0 +1,248 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class Subject
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Subject.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Subject.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_org.eclipse.core.runtime.Plugin">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.listener.subject</FONT>
+<BR>
+Class Subject</H2>
+<PRE>
+java.lang.Object
+ |
+ +--org.eclipse.core.runtime.Plugin
+ |
+ +--<B>com.bolour.sample.eclipse.listener.subject.Subject</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>Subject</B><DT>extends org.eclipse.core.runtime.Plugin</DL>
+
+<P>
+Sample <i>subject</i> plug-in for the <i>listener</i> extension pattern.
+ The subject plug-in provides a <code>listeners</code> extension-point, and
+ notifes the extension members of this extension-point when its state is updated
+ via the <code>update</code> method.
+ <p>
+ Extension processing by this plug-in obtains references to its listeners
+ from all of its extensions, and saves these references for future notification.
+ When the state of the plugin is changed through the <code>update</code> method,
+ these listeners are notified.
+ <p>
+ The plug-in class is used as a natural place to house the
+ extension and notification processing. No specific activation/deactivation
+ processing is required by this plug-in. So strictly speaking, a plug-in
+ class is not necessary for this plug-in. Nevertheless, the plug-in instance
+ provides a convenient place to do the basic work required of this plug-in.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="fields_inherited_from_class_org.eclipse.core.runtime.Plugin"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Fields inherited from class org.eclipse.core.runtime.Plugin</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME, PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/Subject.html#Subject(org.eclipse.core.runtime.IPluginDescriptor)">Subject</A></B>(org.eclipse.core.runtime.IPluginDescriptor&nbsp;descriptor)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/Subject.html#update()">update</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Update the state of the subject.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.eclipse.core.runtime.Plugin"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class org.eclipse.core.runtime.Plugin</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>find, find, getDescriptor, getLog, getPluginPreferences, getStateLocation, initializeDefaultPluginPreferences, isDebugging, openStream, openStream, savePluginPreferences, setDebugging, shutdown, startup, toString</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="Subject(org.eclipse.core.runtime.IPluginDescriptor)"><!-- --></A><H3>
+Subject</H3>
+<PRE>
+public <B>Subject</B>(org.eclipse.core.runtime.IPluginDescriptor&nbsp;descriptor)</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="update()"><!-- --></A><H3>
+update</H3>
+<PRE>
+public void <B>update</B>()</PRE>
+<DL>
+<DD>Update the state of the subject. Causes notifications
+ to be broadcast to the subject's listeners.</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Subject.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Subject.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_org.eclipse.core.runtime.Plugin">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html
new file mode 100644
index 0000000..dee15e6
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html
@@ -0,0 +1,276 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class UpdateMenuAction
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/UpdateMenuAction.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/Subject.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="UpdateMenuAction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.listener.subject</FONT>
+<BR>
+Class UpdateMenuAction</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.listener.subject.UpdateMenuAction</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>org.eclipse.ui.IActionDelegate, org.eclipse.ui.IWorkbenchWindowActionDelegate</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>UpdateMenuAction</B><DT>extends java.lang.Object<DT>implements org.eclipse.ui.IWorkbenchWindowActionDelegate</DL>
+
+<P>
+Menu event handler for testing <code>listeners</code> notification.
+<P>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#UpdateMenuAction()">UpdateMenuAction</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#dispose()">dispose</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#init(org.eclipse.ui.IWorkbenchWindow)">init</A></B>(org.eclipse.ui.IWorkbenchWindow&nbsp;window)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#run(org.eclipse.jface.action.IAction)">run</A></B>(org.eclipse.jface.action.IAction&nbsp;action)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Event handler for the update menu action.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)">selectionChanged</A></B>(org.eclipse.jface.action.IAction&nbsp;action,
+ org.eclipse.jface.viewers.ISelection&nbsp;selection)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="UpdateMenuAction()"><!-- --></A><H3>
+UpdateMenuAction</H3>
+<PRE>
+public <B>UpdateMenuAction</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="dispose()"><!-- --></A><H3>
+dispose</H3>
+<PRE>
+public void <B>dispose</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>dispose</CODE> in interface <CODE>org.eclipse.ui.IWorkbenchWindowActionDelegate</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="init(org.eclipse.ui.IWorkbenchWindow)"><!-- --></A><H3>
+init</H3>
+<PRE>
+public void <B>init</B>(org.eclipse.ui.IWorkbenchWindow&nbsp;window)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>init</CODE> in interface <CODE>org.eclipse.ui.IWorkbenchWindowActionDelegate</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="run(org.eclipse.jface.action.IAction)"><!-- --></A><H3>
+run</H3>
+<PRE>
+public void <B>run</B>(org.eclipse.jface.action.IAction&nbsp;action)</PRE>
+<DL>
+<DD>Event handler for the update menu action.
+ Updates the state of the plugin instance.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>run</CODE> in interface <CODE>org.eclipse.ui.IActionDelegate</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)"><!-- --></A><H3>
+selectionChanged</H3>
+<PRE>
+public void <B>selectionChanged</B>(org.eclipse.jface.action.IAction&nbsp;action,
+ org.eclipse.jface.viewers.ISelection&nbsp;selection)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>selectionChanged</CODE> in interface <CODE>org.eclipse.ui.IActionDelegate</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/UpdateMenuAction.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/Subject.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="UpdateMenuAction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/IListener.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/IListener.html
new file mode 100644
index 0000000..cb692e6
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/IListener.html
@@ -0,0 +1,140 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Interface com.bolour.sample.eclipse.listener.subject.IListener
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IListener.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Interface<br>com.bolour.sample.eclipse.listener.subject.IListener</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Packages that use <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.listener.firstlistener"><B>com.bolour.sample.eclipse.listener.firstlistener</B></A></TD>
+<TD>
+A sample listener plug-in package.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.listener.firstlistener"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Uses of <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A> in <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-summary.html">com.bolour.sample.eclipse.listener.firstlistener</A></FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2>Classes in <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-summary.html">com.bolour.sample.eclipse.listener.firstlistener</A> that implement <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html">ListenerX</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback object of type X.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html">ListenerY</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback object of type Y.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IListener.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/Subject.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/Subject.html
new file mode 100644
index 0000000..9367405
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/Subject.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.listener.subject.Subject
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/subject/Subject.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Subject.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.listener.subject.Subject</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.listener.subject.Subject
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/subject/Subject.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Subject.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/UpdateMenuAction.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/UpdateMenuAction.html
new file mode 100644
index 0000000..4c37aed
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/class-use/UpdateMenuAction.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.listener.subject.UpdateMenuAction
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="UpdateMenuAction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.listener.subject.UpdateMenuAction</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.listener.subject.UpdateMenuAction
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="UpdateMenuAction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-frame.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-frame.html
new file mode 100644
index 0000000..ab34750
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-frame.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.listener.subject
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-summary.html" TARGET="classFrame">com.bolour.sample.eclipse.listener.subject</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="IListener.html" TARGET="classFrame"><I>IListener</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="Subject.html" TARGET="classFrame">Subject</A>
+<BR>
+<A HREF="UpdateMenuAction.html" TARGET="classFrame">UpdateMenuAction</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-summary.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-summary.html
new file mode 100644
index 0000000..bb3d1d0
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-summary.html
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.listener.subject
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package com.bolour.sample.eclipse.listener.subject
+</H2>
+
+A plug-in acting as the subject of observations.
+<P>
+<B>See: </B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="IListener.html"><I>IListener</I></A></B></TD>
+<TD>Callback interface for listeners.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="Subject.html">Subject</A></B></TD>
+<TD>Sample <i>subject</i> plug-in for the <i>listener</i> extension pattern.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="UpdateMenuAction.html">UpdateMenuAction</A></B></TD>
+<TD>Menu event handler for testing <code>listeners</code> notification.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package com.bolour.sample.eclipse.listener.subject Description
+</H2>
+
+<P>
+<h2>
+A plug-in acting as the subject of observations.
+</h2>
+
+<p>
+Updates to this plug-in cause notifications to be broadcast to all
+extension members of the plug-in's <code>listeners</code> extension-point.
+Each extension member provides a custom listener callback object implementing the
+<code>IListener</code> interface.
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-tree.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-tree.html
new file mode 100644
index 0000000..d70af7b
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-tree.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: com.bolour.sample.eclipse.listener.subject Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package com.bolour.sample.eclipse.listener.subject
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class org.eclipse.core.runtime.Plugin<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.subject.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/Subject.html"><B>Subject</B></A></UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.subject.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html"><B>UpdateMenuAction</B></A> (implements org.eclipse.ui.IWorkbenchWindowActionDelegate)
+</UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">interface com.bolour.sample.eclipse.listener.subject.<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/IListener.html"><B>IListener</B></A></UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/secondlistener/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-use.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-use.html
new file mode 100644
index 0000000..4846d5a
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/listener/subject/package-use.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Package com.bolour.sample.eclipse.listener.subject
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>com.bolour.sample.eclipse.listener.subject</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Packages that use <A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-summary.html">com.bolour.sample.eclipse.listener.subject</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.listener.firstlistener"><B>com.bolour.sample.eclipse.listener.firstlistener</B></A></TD>
+<TD>
+A sample listener plug-in package.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.listener.firstlistener"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Classes in <A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-summary.html">com.bolour.sample.eclipse.listener.subject</A> used by <A HREF="../../../../../../com/bolour/sample/eclipse/listener/firstlistener/package-summary.html">com.bolour.sample.eclipse.listener.firstlistener</A><TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/class-use/IListener.html#com.bolour.sample.eclipse.listener.firstlistener"><B>IListener</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback interface for listeners.</TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/Echo.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/Echo.html
new file mode 100644
index 0000000..b9cbf1c
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/Echo.html
@@ -0,0 +1,224 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class Echo
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Echo.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Echo.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.service.echo</FONT>
+<BR>
+Class Echo</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.service.echo.Echo</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>Echo</B><DT>extends java.lang.Object<DT>implements <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></DL>
+
+<P>
+Service implementing the echo function.
+ No specific initialization is required for an instance of this function.
+ All information required for the function's computation is built-in.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/Echo.html#Echo()">Echo</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/Echo.html#compute(long)">compute</A></B>(long&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Implementation of the echo function.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="Echo()"><!-- --></A><H3>
+Echo</H3>
+<PRE>
+public <B>Echo</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="compute(long)"><!-- --></A><H3>
+compute</H3>
+<PRE>
+public long <B>compute</B>(long&nbsp;x)</PRE>
+<DL>
+<DD>Implementation of the echo function.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html#compute(long)">compute</A></CODE> in interface <CODE><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>x</CODE> - The function argument.<DT><B>Returns:</B><DD>The function argument is echoed as its return value.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Echo.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Echo.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/class-use/Echo.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/class-use/Echo.html
new file mode 100644
index 0000000..d45067b
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/class-use/Echo.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.service.echo.Echo
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/echo/Echo.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Echo.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.service.echo.Echo</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.echo.Echo
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/echo/Echo.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Echo.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-frame.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-frame.html
new file mode 100644
index 0000000..a5e413b
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-frame.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.echo
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-summary.html" TARGET="classFrame">com.bolour.sample.eclipse.service.echo</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="Echo.html" TARGET="classFrame">Echo</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-summary.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-summary.html
new file mode 100644
index 0000000..173f8b4
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-summary.html
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.echo
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package com.bolour.sample.eclipse.service.echo
+</H2>
+
+An echo plug-in.
+<P>
+<B>See: </B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="Echo.html">Echo</A></B></TD>
+<TD>Service implementing the echo function.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package com.bolour.sample.eclipse.service.echo Description
+</H2>
+
+<P>
+<h2>
+An echo plug-in.
+</h2>
+
+<p>
+Extends the arithmetic function invocation extension-point
+<i>com.bolour.sample.eclipse.listener.ui.functions</i>.
+Provide the <i>echo</i> arithmetic function to the
+service UI plug-in.
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-tree.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-tree.html
new file mode 100644
index 0000000..ddc1ddc
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-tree.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: com.bolour.sample.eclipse.service.echo Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package com.bolour.sample.eclipse.service.echo
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.echo.<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/Echo.html"><B>Echo</B></A> (implements com.bolour.sample.eclipse.service.ui.<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>)
+</UL>
+</UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/listener/subject/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-use.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-use.html
new file mode 100644
index 0000000..3d431dc
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/echo/package-use.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Package com.bolour.sample.eclipse.service.echo
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>com.bolour.sample.eclipse.service.echo</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.echo
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/Dummy.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/Dummy.html
new file mode 100644
index 0000000..0012edf
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/Dummy.html
@@ -0,0 +1,184 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class Dummy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Dummy.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Dummy.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Object">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.service.errortest</FONT>
+<BR>
+Class Dummy</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.service.errortest.Dummy</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>Dummy</B><DT>extends java.lang.Object</DL>
+
+<P>
+Example class that does not implement the <code>IFunction</code> interface.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/Dummy.html#Dummy()">Dummy</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="Dummy()"><!-- --></A><H3>
+Dummy</H3>
+<PRE>
+public <B>Dummy</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Dummy.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Dummy.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Object">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/class-use/Dummy.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/class-use/Dummy.html
new file mode 100644
index 0000000..5c0c3e5
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/class-use/Dummy.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.service.errortest.Dummy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/errortest/Dummy.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Dummy.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.service.errortest.Dummy</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.errortest.Dummy
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/errortest/Dummy.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Dummy.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-frame.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-frame.html
new file mode 100644
index 0000000..d2e5ea4
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-frame.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.errortest
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/package-summary.html" TARGET="classFrame">com.bolour.sample.eclipse.service.errortest</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="Dummy.html" TARGET="classFrame">Dummy</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-summary.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-summary.html
new file mode 100644
index 0000000..d8572d0
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-summary.html
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.errortest
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package com.bolour.sample.eclipse.service.errortest
+</H2>
+
+Test plugin for <code>functions</code> extension errors.
+<P>
+<B>See: </B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="Dummy.html">Dummy</A></B></TD>
+<TD>Example class that does not implement the <code>IFunction</code> interface.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package com.bolour.sample.eclipse.service.errortest Description
+</H2>
+
+<P>
+<h2>
+Test plugin for <code>functions</code> extension errors.
+</h2>
+
+<p>
+Provides an extension of <i>com.bolour.sample.eclipse.service.ui.functions</i>
+with various configuration errors. This extension is normally
+commented out. To test for errors, uncomment the extension
+in the plugin.xml file of this plugin, and recycle Eclipse.
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-tree.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-tree.html
new file mode 100644
index 0000000..3a4d8f6
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-tree.html
@@ -0,0 +1,104 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: com.bolour.sample.eclipse.service.errortest Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package com.bolour.sample.eclipse.service.errortest
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.errortest.<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/Dummy.html"><B>Dummy</B></A></UL>
+</UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-use.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-use.html
new file mode 100644
index 0000000..70d8333
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/errortest/package-use.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Package com.bolour.sample.eclipse.service.errortest
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>com.bolour.sample.eclipse.service.errortest</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.errortest
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html
new file mode 100644
index 0000000..f879dbc
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html
@@ -0,0 +1,271 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class Exponentiation
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Exponentiation.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Exponentiation.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.service.exponentiation</FONT>
+<BR>
+Class Exponentiation</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.service.exponentiation.Exponentiation</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>org.eclipse.core.runtime.IExecutableExtension, <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>Exponentiation</B><DT>extends java.lang.Object<DT>implements <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>, org.eclipse.core.runtime.IExecutableExtension</DL>
+
+<P>
+Callback class for exponentiation functions.
+
+ <p>
+ This class provides a generic exponentiation function.
+ A particular instance of this class is parameterized by
+ a specific exponent to be used by that instance in
+ exponentiation. The exponent is provided to this instance
+ via an XML attribute called <code>constant</code> in its extension
+ specification.
+
+ <p>
+ Because this class implementes the <code>IExecutableExtension</code>
+ interface, the standard callback creation method of Eclipse,
+ namely <code>IConfigurationElement.createExecutableExtension</code>
+ knows to initialize a created instance of the class by calling
+ the <code>IExecutableExtension</code> method <code>setInitializationData</code>.
+ This method extracts the value of the <i>constant</i> attribute
+ and initializes the instance with its integer value as the
+ exponent for later computations.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html#Exponentiation()">Exponentiation</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html#compute(long)">compute</A></B>(long&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Implementation of the exponentiation operation.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)">setInitializationData</A></B>(org.eclipse.core.runtime.IConfigurationElement&nbsp;member,
+ java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;data)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialization method for instances of Exponentiation.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="Exponentiation()"><!-- --></A><H3>
+Exponentiation</H3>
+<PRE>
+public <B>Exponentiation</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="compute(long)"><!-- --></A><H3>
+compute</H3>
+<PRE>
+public long <B>compute</B>(long&nbsp;x)</PRE>
+<DL>
+<DD>Implementation of the exponentiation operation.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html#compute(long)">compute</A></CODE> in interface <CODE><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></CODE></DL>
+</DD>
+<DD>Following copied from interface: <CODE>com.bolour.sample.eclipse.service.ui.IFunction</CODE></DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>x</CODE> - A long integer input argument.<DT><B>Returns:</B><DD>The result of the callback function.<DT><B>Throws:</B><DD><CODE>java.lang.ArithmeticException</CODE> - In case of an error.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)"><!-- --></A><H3>
+setInitializationData</H3>
+<PRE>
+public void <B>setInitializationData</B>(org.eclipse.core.runtime.IConfigurationElement&nbsp;member,
+ java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;data)
+ throws org.eclipse.core.runtime.CoreException</PRE>
+<DL>
+<DD>Initialization method for instances of Exponentiation.
+ The exponent for this particular listener is provided in the <code>constant</code>
+ XML attribute of its extension element.
+ Extract the exponent and remember it for use in later computations.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>setInitializationData</CODE> in interface <CODE>org.eclipse.core.runtime.IExecutableExtension</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>See Also: </B><DD><CODE>IExecutableExtension.setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Exponentiation.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Exponentiation.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/class-use/Exponentiation.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/class-use/Exponentiation.html
new file mode 100644
index 0000000..da2e84b
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/class-use/Exponentiation.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.service.exponentiation.Exponentiation
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Exponentiation.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.service.exponentiation.Exponentiation</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.exponentiation.Exponentiation
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Exponentiation.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-frame.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-frame.html
new file mode 100644
index 0000000..6153689
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-frame.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.exponentiation
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-summary.html" TARGET="classFrame">com.bolour.sample.eclipse.service.exponentiation</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="Exponentiation.html" TARGET="classFrame">Exponentiation</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-summary.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-summary.html
new file mode 100644
index 0000000..8bbee53
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-summary.html
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.exponentiation
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package com.bolour.sample.eclipse.service.exponentiation
+</H2>
+
+An exponentiation plug-in.
+<P>
+<B>See: </B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="Exponentiation.html">Exponentiation</A></B></TD>
+<TD>Callback class for exponentiation functions.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package com.bolour.sample.eclipse.service.exponentiation Description
+</H2>
+
+<P>
+<h2>
+An exponentiation plug-in.
+</h2>
+
+<p>
+Extends the arithmetic function invocation extension-point
+<i>com.bolour.sample.eclipse.listener.ui.functions</i>.
+Provide the exponentiation arithmetic function to the
+service UI plug-in.
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-tree.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-tree.html
new file mode 100644
index 0000000..52dbeb1
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-tree.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: com.bolour.sample.eclipse.service.exponentiation Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package com.bolour.sample.eclipse.service.exponentiation
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.exponentiation.<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html"><B>Exponentiation</B></A> (implements org.eclipse.core.runtime.IExecutableExtension, com.bolour.sample.eclipse.service.ui.<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>)
+</UL>
+</UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/errortest/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-use.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-use.html
new file mode 100644
index 0000000..c3cde34
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/exponentiation/package-use.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Package com.bolour.sample.eclipse.service.exponentiation
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>com.bolour.sample.eclipse.service.exponentiation</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.exponentiation
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/Multiplication.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/Multiplication.html
new file mode 100644
index 0000000..b0257e8
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/Multiplication.html
@@ -0,0 +1,269 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class Multiplication
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Multiplication.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Multiplication.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.service.multiplication</FONT>
+<BR>
+Class Multiplication</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.service.multiplication.Multiplication</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>org.eclipse.core.runtime.IExecutableExtension, <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>Multiplication</B><DT>extends java.lang.Object<DT>implements <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>, org.eclipse.core.runtime.IExecutableExtension</DL>
+
+<P>
+Callback class for the multiplication function.
+
+ <p>
+ This class provides a generic multiplication function.
+ A particular instance of this class is parameterized by
+ a specific factor to be used in multiplications.
+ The factor is provided to this instance via a custom XML attribute called
+ <i>constant</i> in its extension specification.
+
+ <p>
+ Because this class implements the <i>IExecutableExtension</i>
+ interface, the standard callback creation method of Eclipse,
+ namely, <code>IConfigurationElement.createExecutableExtension</code>
+ knows to initialize a created instance of the class by calling
+ the <code>IExecutableExtension</code> method <code>setInitializationData</code>.
+ This method extracts the value of the <code>constant</code> attribute
+ and initializes the instance with its integer value as the factor
+ for later multiplications.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/Multiplication.html#Multiplication()">Multiplication</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/Multiplication.html#compute(long)">compute</A></B>(long&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Implementation of the multiplication function.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/Multiplication.html#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)">setInitializationData</A></B>(org.eclipse.core.runtime.IConfigurationElement&nbsp;member,
+ java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;data)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialization method for instances of MultiplicationService.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="Multiplication()"><!-- --></A><H3>
+Multiplication</H3>
+<PRE>
+public <B>Multiplication</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="compute(long)"><!-- --></A><H3>
+compute</H3>
+<PRE>
+public long <B>compute</B>(long&nbsp;x)</PRE>
+<DL>
+<DD>Implementation of the multiplication function.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html#compute(long)">compute</A></CODE> in interface <CODE><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></CODE></DL>
+</DD>
+<DD>Following copied from interface: <CODE>com.bolour.sample.eclipse.service.ui.IFunction</CODE></DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>x</CODE> - A long integer input argument.<DT><B>Returns:</B><DD>The result of the callback function.<DT><B>Throws:</B><DD><CODE>java.lang.ArithmeticException</CODE> - In case of an error.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)"><!-- --></A><H3>
+setInitializationData</H3>
+<PRE>
+public void <B>setInitializationData</B>(org.eclipse.core.runtime.IConfigurationElement&nbsp;member,
+ java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;data)
+ throws org.eclipse.core.runtime.CoreException</PRE>
+<DL>
+<DD>Initialization method for instances of MultiplicationService.
+ The multiplication factor for this particular listener is a custom XML attribute of its extension element.
+ Extract the power and remember it for use in this operation.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>setInitializationData</CODE> in interface <CODE>org.eclipse.core.runtime.IExecutableExtension</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>See Also: </B><DD><CODE>IExecutableExtension.setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/Multiplication.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Multiplication.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/class-use/Multiplication.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/class-use/Multiplication.html
new file mode 100644
index 0000000..eeb65b8
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/class-use/Multiplication.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.service.multiplication.Multiplication
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/multiplication/Multiplication.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Multiplication.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.service.multiplication.Multiplication</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.multiplication.Multiplication
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/multiplication/Multiplication.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Multiplication.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-frame.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-frame.html
new file mode 100644
index 0000000..b37b03f
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-frame.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.multiplication
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-summary.html" TARGET="classFrame">com.bolour.sample.eclipse.service.multiplication</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="Multiplication.html" TARGET="classFrame">Multiplication</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-summary.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-summary.html
new file mode 100644
index 0000000..479db05
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-summary.html
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.multiplication
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package com.bolour.sample.eclipse.service.multiplication
+</H2>
+
+A multiplication plug-in.
+<P>
+<B>See: </B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="Multiplication.html">Multiplication</A></B></TD>
+<TD>Callback class for the multiplication function.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package com.bolour.sample.eclipse.service.multiplication Description
+</H2>
+
+<P>
+<h2>
+A multiplication plug-in.
+</h2>
+
+<p>
+Extends the arithmetic function invocation extension-point
+<code>com.bolour.sample.eclipse.service.ui.functions</code>.
+Provides a multiplication function, parameterized by a constant
+multiplication factor.
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-tree.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-tree.html
new file mode 100644
index 0000000..fde2ba8
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-tree.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: com.bolour.sample.eclipse.service.multiplication Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package com.bolour.sample.eclipse.service.multiplication
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.multiplication.<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/Multiplication.html"><B>Multiplication</B></A> (implements org.eclipse.core.runtime.IExecutableExtension, com.bolour.sample.eclipse.service.ui.<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>)
+</UL>
+</UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-use.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-use.html
new file mode 100644
index 0000000..f5e581d
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/multiplication/package-use.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Package com.bolour.sample.eclipse.service.multiplication
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>com.bolour.sample.eclipse.service.multiplication</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.multiplication
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/FunctionsGrid.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/FunctionsGrid.html
new file mode 100644
index 0000000..aa8661a
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/FunctionsGrid.html
@@ -0,0 +1,229 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class FunctionsGrid
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/FunctionsGrid.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionsGrid.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.service.ui</FONT>
+<BR>
+Class FunctionsGrid</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.service.ui.FunctionsGrid</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>FunctionsGrid</B><DT>extends java.lang.Object</DL>
+
+<P>
+User interface grid for arithmetic functions.
+ Provides a function input and a function result field.
+ Allows user interface widgets (a button and an associated label) to be
+ made available to the user for invoking a configured function.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html#FunctionsGrid(org.eclipse.swt.widgets.Composite)">FunctionsGrid</A></B>(org.eclipse.swt.widgets.Composite&nbsp;parent)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create the skeletal layout of the function invocation view.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html#addFunction(com.bolour.sample.eclipse.service.ui.IFunction, java.lang.String, java.lang.String, java.lang.Integer)">addFunction</A></B>(<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>&nbsp;function,
+ java.lang.String&nbsp;functionName,
+ java.lang.String&nbsp;label,
+ java.lang.Integer&nbsp;constant)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add a new row to the functions grid for a member function.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="FunctionsGrid(org.eclipse.swt.widgets.Composite)"><!-- --></A><H3>
+FunctionsGrid</H3>
+<PRE>
+public <B>FunctionsGrid</B>(org.eclipse.swt.widgets.Composite&nbsp;parent)</PRE>
+<DL>
+<DD>Create the skeletal layout of the function invocation view.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parent</CODE> - The parent of the view.</DL>
+</DD>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="addFunction(com.bolour.sample.eclipse.service.ui.IFunction, java.lang.String, java.lang.String, java.lang.Integer)"><!-- --></A><H3>
+addFunction</H3>
+<PRE>
+public void <B>addFunction</B>(<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>&nbsp;function,
+ java.lang.String&nbsp;functionName,
+ java.lang.String&nbsp;label,
+ java.lang.Integer&nbsp;constant)</PRE>
+<DL>
+<DD>Add a new row to the functions grid for a member function.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>function</CODE> - Reference to the function to call when
+ this row's button is selected.<DD><CODE>functionName</CODE> - The name of the function.<DD><CODE>label</CODE> - Text of the associated label.<DD><CODE>constant</CODE> - The constant of computation (for display only).</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/FunctionsGrid.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionsGrid.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html
new file mode 100644
index 0000000..2bf1969
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html
@@ -0,0 +1,306 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class FunctionsViewPart
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/FunctionsViewPart.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionsViewPart.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.service.ui</FONT>
+<BR>
+Class FunctionsViewPart</H2>
+<PRE>
+java.lang.Object
+ |
+ +--org.eclipse.ui.part.WorkbenchPart
+ |
+ +--org.eclipse.ui.part.ViewPart
+ |
+ +--<B>com.bolour.sample.eclipse.service.ui.FunctionsViewPart</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>org.eclipse.core.runtime.IAdaptable, org.eclipse.core.runtime.IExecutableExtension, org.eclipse.ui.IViewPart, org.eclipse.ui.IWorkbenchPart</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>FunctionsViewPart</B><DT>extends org.eclipse.ui.part.ViewPart</DL>
+
+<P>
+Eclipse user interface view for invoking service functions.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="fields_inherited_from_class_org.eclipse.ui.IWorkbenchPart"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Fields inherited from interface org.eclipse.ui.IWorkbenchPart</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>PROP_TITLE</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html#FunctionsViewPart()">FunctionsViewPart</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html#createPartControl(org.eclipse.swt.widgets.Composite)">createPartControl</A></B>(org.eclipse.swt.widgets.Composite&nbsp;parent)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html#dispose()">dispose</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html#setFocus()">setFocus</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.eclipse.ui.part.ViewPart"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class org.eclipse.ui.part.ViewPart</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>getViewSite, init, init, saveState</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.eclipse.ui.part.WorkbenchPart"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class org.eclipse.ui.part.WorkbenchPart</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>addPropertyListener, firePropertyChange, getAdapter, getConfigurationElement, getDefaultImage, getSite, getTitle, getTitleImage, getTitleToolTip, removePropertyListener, setInitializationData, setSite, setTitle, setTitleImage, setTitleToolTip</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.eclipse.ui.IWorkbenchPart"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from interface org.eclipse.ui.IWorkbenchPart</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>addPropertyListener, getSite, getTitle, getTitleImage, getTitleToolTip, removePropertyListener</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.eclipse.core.runtime.IAdaptable"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from interface org.eclipse.core.runtime.IAdaptable</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>getAdapter</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="FunctionsViewPart()"><!-- --></A><H3>
+FunctionsViewPart</H3>
+<PRE>
+public <B>FunctionsViewPart</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="createPartControl(org.eclipse.swt.widgets.Composite)"><!-- --></A><H3>
+createPartControl</H3>
+<PRE>
+public void <B>createPartControl</B>(org.eclipse.swt.widgets.Composite&nbsp;parent)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>createPartControl</CODE> in class <CODE>org.eclipse.ui.part.WorkbenchPart</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="dispose()"><!-- --></A><H3>
+dispose</H3>
+<PRE>
+public void <B>dispose</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>dispose</CODE> in class <CODE>org.eclipse.ui.part.WorkbenchPart</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setFocus()"><!-- --></A><H3>
+setFocus</H3>
+<PRE>
+public void <B>setFocus</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>setFocus</CODE> in class <CODE>org.eclipse.ui.part.WorkbenchPart</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/FunctionsViewPart.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionsViewPart.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/IFunction.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/IFunction.html
new file mode 100644
index 0000000..1512b9b
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/IFunction.html
@@ -0,0 +1,179 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Interface IFunction
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/IFunction.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IFunction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.service.ui</FONT>
+<BR>
+Interface IFunction</H2>
+<DL>
+<DT><B>All Known Implementing Classes:</B> <DD><A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html">Exponentiation</A>, <A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/Multiplication.html">Multiplication</A>, <A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/Echo.html">Echo</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public interface <B>IFunction</B></DL>
+
+<P>
+Callback interface for extension functions.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html#compute(long)">compute</A></B>(long&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback method for arithmetic computation.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="compute(long)"><!-- --></A><H3>
+compute</H3>
+<PRE>
+public long <B>compute</B>(long&nbsp;x)
+ throws java.lang.ArithmeticException</PRE>
+<DL>
+<DD>Callback method for arithmetic computation.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>x</CODE> - A long integer input argument.<DT><B>Returns:</B><DD>The result of the callback function.<DT><B>Throws:</B><DD><CODE>java.lang.ArithmeticException</CODE> - In case of an error.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/IFunction.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IFunction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html
new file mode 100644
index 0000000..89f8599
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html
@@ -0,0 +1,228 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Class ProcessServiceMembers
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ProcessServiceMembers.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ProcessServiceMembers.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+com.bolour.sample.eclipse.service.ui</FONT>
+<BR>
+Class ProcessServiceMembers</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>com.bolour.sample.eclipse.service.ui.ProcessServiceMembers</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>ProcessServiceMembers</B><DT>extends java.lang.Object</DL>
+
+<P>
+Extension processing logic for the <code>functions</code> extension-point.
+ Extract specific information about each function. Create callback
+ function object when required.
+<P>
+<DL>
+<DT><B>Author: </B><DD>Azad</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html#ProcessServiceMembers()">ProcessServiceMembers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html#process(com.bolour.sample.eclipse.service.ui.FunctionsGrid)">process</A></B>(<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html">FunctionsGrid</A>&nbsp;grid)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Perform initial extension processing for the members of the
+ <code>functions</code> extension-point.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><clinit>, clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="ProcessServiceMembers()"><!-- --></A><H3>
+ProcessServiceMembers</H3>
+<PRE>
+public <B>ProcessServiceMembers</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="process(com.bolour.sample.eclipse.service.ui.FunctionsGrid)"><!-- --></A><H3>
+process</H3>
+<PRE>
+public static void <B>process</B>(<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html">FunctionsGrid</A>&nbsp;grid)
+ throws org.eclipse.ui.WorkbenchException</PRE>
+<DL>
+<DD>Perform initial extension processing for the members of the
+ <code>functions</code> extension-point. Make calls to the user interface
+ module to add the functions of an extension to the UI functions grid.
+ For each function, a virtual proxy callback object is created and handed
+ to the user interface module. The proxy class is a nested top-level
+ class and is therefore known at compile time. The actual (real) callback
+ objects configured into extensions are instantiated and initialized in
+ a lazy fashion by the proxy callback objects.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>grid</CODE> - The UI functions grid exposing the functions configured
+ into <code>functions</code> extensions.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/ProcessServiceMembers.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ProcessServiceMembers.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/FunctionsGrid.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/FunctionsGrid.html
new file mode 100644
index 0000000..2f1ab88
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/FunctionsGrid.html
@@ -0,0 +1,133 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.service.ui.FunctionsGrid
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionsGrid.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.service.ui.FunctionsGrid</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Packages that use <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html">FunctionsGrid</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.service.ui"><B>com.bolour.sample.eclipse.service.ui</B></A></TD>
+<TD>
+A UI plugin for invoking integer arithmetic operations.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.service.ui"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Uses of <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html">FunctionsGrid</A> in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A></FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2>Methods in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A> with parameters of type <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html">FunctionsGrid</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B>ProcessServiceMembers.</B><B><A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html#process(com.bolour.sample.eclipse.service.ui.FunctionsGrid)">process</A></B>(<A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html">FunctionsGrid</A>&nbsp;grid)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Perform initial extension processing for the members of the
+ <code>functions</code> extension-point.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionsGrid.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/FunctionsViewPart.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/FunctionsViewPart.html
new file mode 100644
index 0000000..e706cb4
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/FunctionsViewPart.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.service.ui.FunctionsViewPart
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionsViewPart.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.service.ui.FunctionsViewPart</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.ui.FunctionsViewPart
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionsViewPart.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/IFunction.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/IFunction.html
new file mode 100644
index 0000000..0298b12
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/IFunction.html
@@ -0,0 +1,225 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Interface com.bolour.sample.eclipse.service.ui.IFunction
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IFunction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Interface<br>com.bolour.sample.eclipse.service.ui.IFunction</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Packages that use <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.service.echo"><B>com.bolour.sample.eclipse.service.echo</B></A></TD>
+<TD>
+An echo plug-in.&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.service.exponentiation"><B>com.bolour.sample.eclipse.service.exponentiation</B></A></TD>
+<TD>
+An exponentiation plug-in.&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.service.multiplication"><B>com.bolour.sample.eclipse.service.multiplication</B></A></TD>
+<TD>
+A multiplication plug-in.&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.service.ui"><B>com.bolour.sample.eclipse.service.ui</B></A></TD>
+<TD>
+A UI plugin for invoking integer arithmetic operations.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.service.echo"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Uses of <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A> in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/echo/package-summary.html">com.bolour.sample.eclipse.service.echo</A></FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2>Classes in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/echo/package-summary.html">com.bolour.sample.eclipse.service.echo</A> that implement <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../../com/bolour/sample/eclipse/service/echo/Echo.html">Echo</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Service implementing the echo function.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.service.exponentiation"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Uses of <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A> in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-summary.html">com.bolour.sample.eclipse.service.exponentiation</A></FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2>Classes in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-summary.html">com.bolour.sample.eclipse.service.exponentiation</A> that implement <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html">Exponentiation</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback class for exponentiation functions.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.service.multiplication"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Uses of <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A> in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/multiplication/package-summary.html">com.bolour.sample.eclipse.service.multiplication</A></FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2>Classes in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/multiplication/package-summary.html">com.bolour.sample.eclipse.service.multiplication</A> that implement <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../../../com/bolour/sample/eclipse/service/multiplication/Multiplication.html">Multiplication</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback class for the multiplication function.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.service.ui"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Uses of <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A> in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A></FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2>Methods in <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A> with parameters of type <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B>FunctionsGrid.</B><B><A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html#addFunction(com.bolour.sample.eclipse.service.ui.IFunction, java.lang.String, java.lang.String, java.lang.Integer)">addFunction</A></B>(<A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>&nbsp;function,
+ java.lang.String&nbsp;functionName,
+ java.lang.String&nbsp;label,
+ java.lang.Integer&nbsp;constant)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add a new row to the functions grid for a member function.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IFunction.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/ProcessServiceMembers.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/ProcessServiceMembers.html
new file mode 100644
index 0000000..c09ab7c
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/class-use/ProcessServiceMembers.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Class com.bolour.sample.eclipse.service.ui.ProcessServiceMembers
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ProcessServiceMembers.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>com.bolour.sample.eclipse.service.ui.ProcessServiceMembers</B></H2>
+</CENTER>
+No usage of com.bolour.sample.eclipse.service.ui.ProcessServiceMembers
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ProcessServiceMembers.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-frame.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-frame.html
new file mode 100644
index 0000000..9884f3a
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-frame.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.ui
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html" TARGET="classFrame">com.bolour.sample.eclipse.service.ui</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="IFunction.html" TARGET="classFrame"><I>IFunction</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="FunctionsGrid.html" TARGET="classFrame">FunctionsGrid</A>
+<BR>
+<A HREF="FunctionsViewPart.html" TARGET="classFrame">FunctionsViewPart</A>
+<BR>
+<A HREF="ProcessServiceMembers.html" TARGET="classFrame">ProcessServiceMembers</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-summary.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-summary.html
new file mode 100644
index 0000000..646d2d7
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-summary.html
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Package com.bolour.sample.eclipse.service.ui
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;NEXT PACKAGE</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package com.bolour.sample.eclipse.service.ui
+</H2>
+
+A UI plugin for invoking integer arithmetic operations.
+<P>
+<B>See: </B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="IFunction.html"><I>IFunction</I></A></B></TD>
+<TD>Callback interface for extension functions.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="FunctionsGrid.html">FunctionsGrid</A></B></TD>
+<TD>User interface grid for arithmetic functions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="FunctionsViewPart.html">FunctionsViewPart</A></B></TD>
+<TD>Eclipse user interface view for invoking service functions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="ProcessServiceMembers.html">ProcessServiceMembers</A></B></TD>
+<TD>Extension processing logic for the <code>functions</code> extension-point.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package com.bolour.sample.eclipse.service.ui Description
+</H2>
+
+<P>
+<h2>
+A UI plugin for invoking integer arithmetic operations.
+</h2>
+
+<p>
+Provides the user interface for invoking arithmetic functions.
+
+<p>
+Defines an extension-point <code>functions</code> for plugging arithmetic
+functions into a system. Each member of each extension of this
+extension-point defines a callback object implementing a
+particular arithmetic function. The function is made accessible
+to the user through the user interface of the UI plugin defined in
+this package.
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;NEXT PACKAGE</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-tree.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-tree.html
new file mode 100644
index 0000000..fb1a1d5
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-tree.html
@@ -0,0 +1,115 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: com.bolour.sample.eclipse.service.ui Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package com.bolour.sample.eclipse.service.ui
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.ui.<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html"><B>FunctionsGrid</B></A><LI TYPE="circle">class com.bolour.sample.eclipse.service.ui.<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html"><B>ProcessServiceMembers</B></A><LI TYPE="circle">class org.eclipse.ui.part.WorkbenchPart (implements org.eclipse.core.runtime.IExecutableExtension, org.eclipse.ui.IWorkbenchPart)
+<UL>
+<LI TYPE="circle">class org.eclipse.ui.part.ViewPart (implements org.eclipse.ui.IViewPart)
+<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.ui.<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html"><B>FunctionsViewPart</B></A></UL>
+</UL>
+</UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">interface com.bolour.sample.eclipse.service.ui.<A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/IFunction.html"><B>IFunction</B></A></UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-use.html b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-use.html
new file mode 100644
index 0000000..e4600dc
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com/bolour/sample/eclipse/service/ui/package-use.html
@@ -0,0 +1,188 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Uses of Package com.bolour.sample.eclipse.service.ui
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>com.bolour.sample.eclipse.service.ui</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Packages that use <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.service.echo"><B>com.bolour.sample.eclipse.service.echo</B></A></TD>
+<TD>
+An echo plug-in.&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.service.exponentiation"><B>com.bolour.sample.eclipse.service.exponentiation</B></A></TD>
+<TD>
+An exponentiation plug-in.&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.service.multiplication"><B>com.bolour.sample.eclipse.service.multiplication</B></A></TD>
+<TD>
+A multiplication plug-in.&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#com.bolour.sample.eclipse.service.ui"><B>com.bolour.sample.eclipse.service.ui</B></A></TD>
+<TD>
+A UI plugin for invoking integer arithmetic operations.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.service.echo"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Classes in <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A> used by <A HREF="../../../../../../com/bolour/sample/eclipse/service/echo/package-summary.html">com.bolour.sample.eclipse.service.echo</A><TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/class-use/IFunction.html#com.bolour.sample.eclipse.service.echo"><B>IFunction</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback interface for extension functions.</TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.service.exponentiation"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Classes in <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A> used by <A HREF="../../../../../../com/bolour/sample/eclipse/service/exponentiation/package-summary.html">com.bolour.sample.eclipse.service.exponentiation</A><TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/class-use/IFunction.html#com.bolour.sample.eclipse.service.exponentiation"><B>IFunction</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback interface for extension functions.</TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.service.multiplication"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Classes in <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A> used by <A HREF="../../../../../../com/bolour/sample/eclipse/service/multiplication/package-summary.html">com.bolour.sample.eclipse.service.multiplication</A><TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/class-use/IFunction.html#com.bolour.sample.eclipse.service.multiplication"><B>IFunction</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback interface for extension functions.</TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="com.bolour.sample.eclipse.service.ui"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+Classes in <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A> used by <A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A><TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/class-use/FunctionsGrid.html#com.bolour.sample.eclipse.service.ui"><B>FunctionsGrid</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User interface grid for arithmetic functions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../../../../com/bolour/sample/eclipse/service/ui/class-use/IFunction.html#com.bolour.sample.eclipse.service.ui"><B>IFunction</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback interface for extension functions.</TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../../../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-use.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com_bolour_sample_eclipse_listener_subject_listeners.html b/Article-Plug-in-architecture/doc/com_bolour_sample_eclipse_listener_subject_listeners.html
new file mode 100644
index 0000000..ee7fa36
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com_bolour_sample_eclipse_listener_subject_listeners.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HEAD><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<STYLE type="text/css">
+div.dtd-fragment {
+ width: 100%;
+ border: none;
+ background-color: #eee;
+}
+</STYLE>
+</HEAD>
+<HTML>
+<BODY>
+<H1><CENTER>Listeners</CENTER></H1>
+<b><i>Identifier: </i></b>com.bolour.sample.eclipse.listener.subject.listeners<p>
+<b><i>Since: </i></b>2.1.0<p>
+<b><i>Description: </i></b>This extension-point is used to include one or more notification
+ listeners in the host plugin's list of listeners to be notified
+ of host menu events.<p><b><i>Configuration Markup:</i></b><p>
+<p><samp><font color="#800000">&nbsp;&nbsp; &lt;!ELEMENT <a name="e.extension">extension</a> (<a href="#e.listener">listener</a>*)&gt;</font></samp>
+<br><br><samp><font color="#800000">&nbsp;&nbsp; &lt;!ATTLIST extension</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point&nbsp;CDATA #REQUIRED</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;&nbsp;CDATA #IMPLIED</samp>
+<br><samp>&nbsp;&nbsp; &gt;</font></samp>
+<ul>
+<li><b>point</b> - The fully-qualified name of the extension point.
+ That is com.bolour.sample.eclipse.listener.subject.listeners.</li>
+<li><b>id</b> - An optional id.</li>
+<li><b>name</b> - An optional name.</li>
+</ul>
+<p><samp><font color="#800000">&nbsp;&nbsp; &lt;!ELEMENT <a name="e.listener">listener</a> EMPTY&gt;</font></samp>
+<br><br><samp><font color="#800000">&nbsp;&nbsp; &lt;!ATTLIST listener</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;CDATA #REQUIRED</samp>
+<br><samp>&nbsp;&nbsp; &gt;</font></samp>
+<ul>
+<li><b>class</b> - The fully-qualified name of this listener's callback class.
+ The class is instantiated by the host plugin, and the instance
+ is added to the host plugin's notification list.</li>
+</ul>
+<b><i>Examples: </i></b><p>
+<pre>
+ <font color="#000080">&lt;!-- Extend the listeners of the subject ... --&gt;</font>
+ <font color="#000080">&lt;extension
+ id=<font color="#008000">&quot;listener.firstlistener&quot;</font>
+ name=<font color="#008000">&quot;FirstListener&quot;</font>
+ point=<font color="#008000">&quot;com.bolour.sample.eclipse.listener.subject.listeners&quot;</font>&gt;</font>
+ <font color="#000080">&lt;!-- ... by a listener of type X ... --&gt;</font>
+ <font color="#000080">&lt;listener
+ class=<font color="#008000">&quot;com.bolour.sample.eclipse.listener.firstlistener.ListenerX&quot;</font>/&gt;</font>
+ <font color="#000080">&lt;!-- and by a listener of type Y. --&gt;</font>
+ <font color="#000080">&lt;listener
+ class=<font color="#008000">&quot;com.bolour.sample.eclipse.listener.firstlistener.ListenerY&quot;</font>/&gt;</font>
+ <font color="#000080">&lt;/extension&gt;</font>
+</pre>
+<p><p>
+<b><i>API Information: </i></b>Each listener callback must implement the interface
+ com.bolour.sample.eclipse.listener.subject.IListener.<p>
+<b><i>Supplied Implementation: </i></b>An update of the subject plug-in causes a notification to
+ be broadcast to all listeners.<p>
+<font size="-1" color="#336699">
+</font>
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/com_bolour_sample_eclipse_service_ui_functions.html b/Article-Plug-in-architecture/doc/com_bolour_sample_eclipse_service_ui_functions.html
new file mode 100644
index 0000000..1ca58be
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/com_bolour_sample_eclipse_service_ui_functions.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HEAD><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<STYLE type="text/css">
+div.dtd-fragment {
+ width: 100%;
+ border: none;
+ background-color: #eee;
+}
+</STYLE>
+</HEAD>
+<HTML>
+<BODY>
+<H1><CENTER>Functions</CENTER></H1>
+<b><i>Identifier: </i></b>com.bolour.sample.eclipse.services.ui.functions<p>
+<b><i>Since: </i></b>2.1.0.<p>
+<b><i>Description: </i></b>Each extension provides one or more service callbacks functions.
+ For each function, the service UI plug-in will add
+ a button for invoking the function, and a label that identifies
+ the function, to its user interface. The UI plug-in also provides an input
+ field and a result field that are shared between all function.
+ The function takes a <i>long</i> as its input, and returns
+ a <i>long</i> as its output.<p><b><i>Configuration Markup:</i></b><p>
+<p><samp><font color="#800000">&nbsp;&nbsp; &lt;!ELEMENT <a name="e.extension">extension</a> (<a href="#e.function">function</a>+)&gt;</font></samp>
+<br><br><samp><font color="#800000">&nbsp;&nbsp; &lt;!ATTLIST extension</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point&nbsp;CDATA #REQUIRED</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;&nbsp;CDATA #IMPLIED</samp>
+<br><samp>&nbsp;&nbsp; &gt;</font></samp>
+<ul>
+<li><b>point</b> - The extension-point of this extension.</li>
+<li><b>id</b> - Extension identifier.</li>
+<li><b>name</b> - Name of this extension.</li>
+</ul>
+<p><samp><font color="#800000">&nbsp;&nbsp; &lt;!ELEMENT <a name="e.function">function</a> EMPTY&gt;</font></samp>
+<br><br><samp><font color="#800000">&nbsp;&nbsp; &lt;!ATTLIST function</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED</samp>
+<br><samp>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constant&nbsp;CDATA #IMPLIED</samp>
+<br><samp>&nbsp;&nbsp; &gt;</font></samp>
+<ul>
+<li><b>name</b> - The name of the function.</li>
+<li><b>class</b> - The specific class implementing the function.</li>
+<li><b>constant</b> - A constant parameter used in the computation of the function.
+ This constant may be interpreted differently by different extension members.
+ For example, in a member that provides an exponentiation function,
+ the constant is interpreted as the exponent.</li>
+</ul>
+<b><i>Examples: </i></b><p>
+<pre>
+ <font color="#000080">&lt;!-- Extend the functions of the host ... --&gt;</font>
+ <font color="#000080">&lt;extension
+ id=<font color="#008000">&quot;service.exponentiation&quot;</font>
+ name=<font color="#008000">&quot;ExponentiationFunctions&quot;</font>
+ point=<font color="#008000">&quot;com.bolour.sample.eclipse.service.ui.functions&quot;</font>&gt;</font>
+ <font color="#000080">&lt;service
+ constant=<font color="#008000">&quot;3&quot;</font>
+ name=<font color="#008000">&quot;CUBE&quot;</font>
+ class=<font color="#008000">&quot;com.bolour.sample.eclipse.exponentiation.Exponentiation&quot;</font>/&gt;</font>
+ <font color="#000080">&lt;service
+ constant=<font color="#008000">&quot;4&quot;</font>
+ name=<font color="#008000">&quot;FOURTH POWER&quot;</font>
+ class=<font color="#008000">&quot;com.bolour.sample.eclipse.exponentiation.Exponentiation&quot;</font>/&gt;</font>
+ <font color="#000080">&lt;/extension&gt;</font>
+</pre>
+<p><p>
+<b><i>API Information: </i></b>Extension callback objects implement the
+ com.bolour.sample.eclipse.service.ui.IFunction
+ interface.<p>
+<b><i>Supplied Implementation: </i></b>An example implementation is provided in plug-in
+ com.bolour.sample.eclipse.service.exponentiation.<p>
+<font size="-1" color="#336699">
+</font>
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/deprecated-list.html b/Article-Plug-in-architecture/doc/deprecated-list.html
new file mode 100644
index 0000000..f757bd5
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/deprecated-list.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Deprecated List
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="deprecated-list.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Deprecated API</B></H2>
+</CENTER>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="deprecated-list.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/help-doc.html b/Article-Plug-in-architecture/doc/help-doc.html
new file mode 100644
index 0000000..8a6b68b
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/help-doc.html
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: API Help
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="help-doc.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H1>
+How This API Document Is Organized</H1>
+</CENTER>
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.<H3>
+Overview</H3>
+<BLOCKQUOTE>
+
+<P>
+The <A HREF="overview-summary.html">Overview</A> page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.</BLOCKQUOTE>
+<H3>
+Package</H3>
+<BLOCKQUOTE>
+
+<P>
+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:<UL>
+<LI>Interfaces (italic)<LI>Classes<LI>Exceptions<LI>Errors</UL>
+</BLOCKQUOTE>
+<H3>
+Class/Interface</H3>
+<BLOCKQUOTE>
+
+<P>
+Each class, interface, inner class and inner interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:<UL>
+<LI>Class inheritance diagram<LI>Direct Subclasses<LI>All Known Subinterfaces<LI>All Known Implementing Classes<LI>Class/interface declaration<LI>Class/interface description
+<P>
+<LI>Inner Class Summary<LI>Field Summary<LI>Constructor Summary<LI>Method Summary
+<P>
+<LI>Field Detail<LI>Constructor Detail<LI>Method Detail</UL>
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</BLOCKQUOTE>
+<H3>
+Use</H3>
+<BLOCKQUOTE>
+Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.</BLOCKQUOTE>
+<H3>
+Tree (Class Hierarchy)</H3>
+<BLOCKQUOTE>
+There is a <A HREF="overview-tree.html">Class Hierarchy</A> page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.<UL>
+<LI>When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.<LI>When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.</UL>
+</BLOCKQUOTE>
+<H3>
+Deprecated API</H3>
+<BLOCKQUOTE>
+The <A HREF="deprecated-list.html">Deprecated API</A> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</BLOCKQUOTE>
+<H3>
+Index</H3>
+<BLOCKQUOTE>
+The <A HREF="index-files/index-1.html">Index</A> contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.</BLOCKQUOTE>
+<H3>
+Prev/Next</H3>
+These links take you to the next or previous class, interface, package, or related page.<H3>
+Frames/No Frames</H3>
+These links show and hide the HTML frames. All pages are available with or without frames.
+<P>
+<H3>
+Serialized Form</H3>
+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+<P>
+<FONT SIZE="-1">
+<EM>
+This help file applies to API documentation generated using the standard doclet. </EM>
+</FONT>
+<BR>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="help-doc.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-1.html b/Article-Plug-in-architecture/doc/index-files/index-1.html
new file mode 100644
index 0000000..56841fc
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-1.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: A-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV LETTER&nbsp;
+&nbsp;<A HREF="index-2.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-1.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_A_"><!-- --></A><H2>
+<B>A</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html#addFunction(com.bolour.sample.eclipse.service.ui.IFunction, java.lang.String, java.lang.String, java.lang.Integer)"><B>addFunction(IFunction, String, String, Integer)</B></A> -
+Method in class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html">FunctionsGrid</A>
+<DD>Add a new row to the functions grid for a member function.
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV LETTER&nbsp;
+&nbsp;<A HREF="index-2.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-1.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-10.html b/Article-Plug-in-architecture/doc/index-files/index-10.html
new file mode 100644
index 0000000..4d062f5
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-10.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: R-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-9.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-11.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-10.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_R_"><!-- --></A><H2>
+<B>R</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#run(org.eclipse.jface.action.IAction)"><B>run(IAction)</B></A> -
+Method in class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html">PrintMemberMenuAction</A>
+<DD>The extension processing demo menu handler.
+<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#run(org.eclipse.jface.action.IAction)"><B>run(IAction)</B></A> -
+Method in class com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html">UpdateMenuAction</A>
+<DD>Event handler for the update menu action.
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-9.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-11.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-10.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-11.html b/Article-Plug-in-architecture/doc/index-files/index-11.html
new file mode 100644
index 0000000..7a936f0
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-11.html
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: S-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-10.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-12.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-11.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_S_"><!-- --></A><H2>
+<B>S</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)"><B>selectionChanged(IAction, ISelection)</B></A> -
+Method in class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html">PrintMemberMenuAction</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)"><B>selectionChanged(IAction, ISelection)</B></A> -
+Method in class com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html">UpdateMenuAction</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html#setFocus()"><B>setFocus()</B></A> -
+Method in class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html">FunctionsViewPart</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)"><B>setInitializationData(IConfigurationElement, String, Object)</B></A> -
+Method in class com.bolour.sample.eclipse.service.exponentiation.<A HREF="../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html">Exponentiation</A>
+<DD>Initialization method for instances of Exponentiation.
+<DT><A HREF="../com/bolour/sample/eclipse/service/multiplication/Multiplication.html#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)"><B>setInitializationData(IConfigurationElement, String, Object)</B></A> -
+Method in class com.bolour.sample.eclipse.service.multiplication.<A HREF="../com/bolour/sample/eclipse/service/multiplication/Multiplication.html">Multiplication</A>
+<DD>Initialization method for instances of MultiplicationService.
+<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/Subject.html"><B>Subject</B></A> - class com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/Subject.html">Subject</A>.<DD>Sample <i>subject</i> plug-in for the <i>listener</i> extension pattern.<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/Subject.html#Subject(org.eclipse.core.runtime.IPluginDescriptor)"><B>Subject(IPluginDescriptor)</B></A> -
+Constructor for class com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/Subject.html">Subject</A>
+<DD>&nbsp;
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-10.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-12.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-11.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-12.html b/Article-Plug-in-architecture/doc/index-files/index-12.html
new file mode 100644
index 0000000..75183b4
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-12.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: T-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-11.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-13.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-12.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_T_"><!-- --></A><H2>
+<B>T</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html#test(java.lang.String, java.lang.String)"><B>test(String, String)</B></A> -
+Static method in class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html">PrintMemberIdentity</A>
+<DD>Print identification information for each member of each extension
+ of an extension-point.
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-11.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-13.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-12.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-13.html b/Article-Plug-in-architecture/doc/index-files/index-13.html
new file mode 100644
index 0000000..3f99076
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-13.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: U-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-12.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;NEXT LETTER</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-13.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_U_"><!-- --></A><H2>
+<B>U</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/Subject.html#update()"><B>update()</B></A> -
+Method in class com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/Subject.html">Subject</A>
+<DD>Update the state of the subject.
+<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html"><B>UpdateMenuAction</B></A> - class com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html">UpdateMenuAction</A>.<DD>Menu event handler for testing <code>listeners</code> notification.<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#UpdateMenuAction()"><B>UpdateMenuAction()</B></A> -
+Constructor for class com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html">UpdateMenuAction</A>
+<DD>&nbsp;
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-12.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;NEXT LETTER</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-13.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-2.html b/Article-Plug-in-architecture/doc/index-files/index-2.html
new file mode 100644
index 0000000..4120238
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-2.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: C-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-1.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-3.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-2.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_C_"><!-- --></A><H2>
+<B>C</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/demo/package-summary.html"><B>com.bolour.sample.eclipse.demo</B></A> - package com.bolour.sample.eclipse.demo<DD>
+Generic extension processing demo.<DT><A HREF="../com/bolour/sample/eclipse/listener/firstlistener/package-summary.html"><B>com.bolour.sample.eclipse.listener.firstlistener</B></A> - package com.bolour.sample.eclipse.listener.firstlistener<DD>
+A sample listener plug-in package.<DT><A HREF="../com/bolour/sample/eclipse/listener/secondlistener/package-summary.html"><B>com.bolour.sample.eclipse.listener.secondlistener</B></A> - package com.bolour.sample.eclipse.listener.secondlistener<DD>
+A sample listener plug-in package.<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/package-summary.html"><B>com.bolour.sample.eclipse.listener.subject</B></A> - package com.bolour.sample.eclipse.listener.subject<DD>
+A plug-in acting as the subject of observations.<DT><A HREF="../com/bolour/sample/eclipse/service/echo/package-summary.html"><B>com.bolour.sample.eclipse.service.echo</B></A> - package com.bolour.sample.eclipse.service.echo<DD>
+An echo plug-in.<DT><A HREF="../com/bolour/sample/eclipse/service/errortest/package-summary.html"><B>com.bolour.sample.eclipse.service.errortest</B></A> - package com.bolour.sample.eclipse.service.errortest<DD>
+Test plugin for <code>functions</code> extension errors.<DT><A HREF="../com/bolour/sample/eclipse/service/exponentiation/package-summary.html"><B>com.bolour.sample.eclipse.service.exponentiation</B></A> - package com.bolour.sample.eclipse.service.exponentiation<DD>
+An exponentiation plug-in.<DT><A HREF="../com/bolour/sample/eclipse/service/multiplication/package-summary.html"><B>com.bolour.sample.eclipse.service.multiplication</B></A> - package com.bolour.sample.eclipse.service.multiplication<DD>
+A multiplication plug-in.<DT><A HREF="../com/bolour/sample/eclipse/service/ui/package-summary.html"><B>com.bolour.sample.eclipse.service.ui</B></A> - package com.bolour.sample.eclipse.service.ui<DD>
+A UI plugin for invoking integer arithmetic operations.<DT><A HREF="../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html#compute(long)"><B>compute(long)</B></A> -
+Method in class com.bolour.sample.eclipse.service.exponentiation.<A HREF="../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html">Exponentiation</A>
+<DD>Implementation of the exponentiation operation.
+<DT><A HREF="../com/bolour/sample/eclipse/service/multiplication/Multiplication.html#compute(long)"><B>compute(long)</B></A> -
+Method in class com.bolour.sample.eclipse.service.multiplication.<A HREF="../com/bolour/sample/eclipse/service/multiplication/Multiplication.html">Multiplication</A>
+<DD>Implementation of the multiplication function.
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/IFunction.html#compute(long)"><B>compute(long)</B></A> -
+Method in interface com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>
+<DD>Callback method for arithmetic computation.
+<DT><A HREF="../com/bolour/sample/eclipse/service/echo/Echo.html#compute(long)"><B>compute(long)</B></A> -
+Method in class com.bolour.sample.eclipse.service.echo.<A HREF="../com/bolour/sample/eclipse/service/echo/Echo.html">Echo</A>
+<DD>Implementation of the echo function.
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html#createPartControl(org.eclipse.swt.widgets.Composite)"><B>createPartControl(Composite)</B></A> -
+Method in class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html">FunctionsViewPart</A>
+<DD>&nbsp;
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-1.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-3.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-2.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-3.html b/Article-Plug-in-architecture/doc/index-files/index-3.html
new file mode 100644
index 0000000..6039bb9
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-3.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: D-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-2.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-4.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-3.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_D_"><!-- --></A><H2>
+<B>D</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#dispose()"><B>dispose()</B></A> -
+Method in class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html">PrintMemberMenuAction</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html#dispose()"><B>dispose()</B></A> -
+Method in class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html">FunctionsViewPart</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#dispose()"><B>dispose()</B></A> -
+Method in class com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html">UpdateMenuAction</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/service/errortest/Dummy.html"><B>Dummy</B></A> - class com.bolour.sample.eclipse.service.errortest.<A HREF="../com/bolour/sample/eclipse/service/errortest/Dummy.html">Dummy</A>.<DD>Example class that does not implement the <code>IFunction</code> interface.<DT><A HREF="../com/bolour/sample/eclipse/service/errortest/Dummy.html#Dummy()"><B>Dummy()</B></A> -
+Constructor for class com.bolour.sample.eclipse.service.errortest.<A HREF="../com/bolour/sample/eclipse/service/errortest/Dummy.html">Dummy</A>
+<DD>&nbsp;
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-2.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-4.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-3.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-4.html b/Article-Plug-in-architecture/doc/index-files/index-4.html
new file mode 100644
index 0000000..13f9b80
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-4.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: E-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-3.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-5.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-4.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_E_"><!-- --></A><H2>
+<B>E</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/service/echo/Echo.html"><B>Echo</B></A> - class com.bolour.sample.eclipse.service.echo.<A HREF="../com/bolour/sample/eclipse/service/echo/Echo.html">Echo</A>.<DD>Service implementing the echo function.<DT><A HREF="../com/bolour/sample/eclipse/service/echo/Echo.html#Echo()"><B>Echo()</B></A> -
+Constructor for class com.bolour.sample.eclipse.service.echo.<A HREF="../com/bolour/sample/eclipse/service/echo/Echo.html">Echo</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html"><B>Exponentiation</B></A> - class com.bolour.sample.eclipse.service.exponentiation.<A HREF="../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html">Exponentiation</A>.<DD>Callback class for exponentiation functions.<DT><A HREF="../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html#Exponentiation()"><B>Exponentiation()</B></A> -
+Constructor for class com.bolour.sample.eclipse.service.exponentiation.<A HREF="../com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html">Exponentiation</A>
+<DD>&nbsp;
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-3.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-5.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-4.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-5.html b/Article-Plug-in-architecture/doc/index-files/index-5.html
new file mode 100644
index 0000000..3b91285
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-5.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: F-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-4.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-6.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-5.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_F_"><!-- --></A><H2>
+<B>F</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html"><B>FunctionsGrid</B></A> - class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html">FunctionsGrid</A>.<DD>User interface grid for arithmetic functions.<DT><A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html#FunctionsGrid(org.eclipse.swt.widgets.Composite)"><B>FunctionsGrid(Composite)</B></A> -
+Constructor for class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsGrid.html">FunctionsGrid</A>
+<DD>Create the skeletal layout of the function invocation view.
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html"><B>FunctionsViewPart</B></A> - class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html">FunctionsViewPart</A>.<DD>Eclipse user interface view for invoking service functions.<DT><A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html#FunctionsViewPart()"><B>FunctionsViewPart()</B></A> -
+Constructor for class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html">FunctionsViewPart</A>
+<DD>&nbsp;
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-4.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-6.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-5.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-6.html b/Article-Plug-in-architecture/doc/index-files/index-6.html
new file mode 100644
index 0000000..fab97cf
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-6.html
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: I-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-5.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-7.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-6.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_I_"><!-- --></A><H2>
+<B>I</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/IFunction.html"><B>IFunction</B></A> - interface com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>.<DD>Callback interface for extension functions.<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/IListener.html"><B>IListener</B></A> - interface com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>.<DD>Callback interface for listeners.<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#init(org.eclipse.ui.IWorkbenchWindow)"><B>init(IWorkbenchWindow)</B></A> -
+Method in class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html">PrintMemberMenuAction</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html#init(org.eclipse.ui.IWorkbenchWindow)"><B>init(IWorkbenchWindow)</B></A> -
+Method in class com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html">UpdateMenuAction</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/demo/IProcessMember.html"><B>IProcessMember</B></A> - interface com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A>.<DD>Callback interface for processing each extension-point member
+ in generic extension processing.</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-5.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-7.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-6.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-7.html b/Article-Plug-in-architecture/doc/index-files/index-7.html
new file mode 100644
index 0000000..151e995
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-7.html
@@ -0,0 +1,120 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: L-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-6.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-8.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-7.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_L_"><!-- --></A><H2>
+<B>L</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html#listen()"><B>listen()</B></A> -
+Method in class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html">ListenerY</A>
+<DD>Trivial listener class: print out an information message to standard output.
+<DT><A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html#listen()"><B>listen()</B></A> -
+Method in class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html">ListenerX</A>
+<DD>Trivial listener class: print out an information message to standard output.
+<DT><A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html#listen()"><B>listen()</B></A> -
+Method in class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html">ListenerY</A>
+<DD>Trivial listener class: print out an information message to standard output.
+<DT><A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html#listen()"><B>listen()</B></A> -
+Method in class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html">ListenerX</A>
+<DD>Trivial listener class: print out an information message to standard output.
+<DT><A HREF="../com/bolour/sample/eclipse/listener/subject/IListener.html#listen()"><B>listen()</B></A> -
+Method in interface com.bolour.sample.eclipse.listener.subject.<A HREF="../com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>
+<DD>Notification callback method.
+<DT><A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html"><B>ListenerX</B></A> - class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html">ListenerX</A>.<DD>Callback object of type X.<DT><A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html"><B>ListenerX</B></A> - class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html">ListenerX</A>.<DD>Callback object of type X.<DT><A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html#ListenerX()"><B>ListenerX()</B></A> -
+Constructor for class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html">ListenerX</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html#ListenerX()"><B>ListenerX()</B></A> -
+Constructor for class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html">ListenerX</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html"><B>ListenerY</B></A> - class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html">ListenerY</A>.<DD>Callback object of type Y.<DT><A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html"><B>ListenerY</B></A> - class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html">ListenerY</A>.<DD>Callback object of type Y.<DT><A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html#ListenerY()"><B>ListenerY()</B></A> -
+Constructor for class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="../com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html">ListenerY</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html#ListenerY()"><B>ListenerY()</B></A> -
+Constructor for class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="../com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html">ListenerY</A>
+<DD>&nbsp;
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-6.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-8.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-7.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-8.html b/Article-Plug-in-architecture/doc/index-files/index-8.html
new file mode 100644
index 0000000..4b795a1
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-8.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: M-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-7.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-9.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-8.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_M_"><!-- --></A><H2>
+<B>M</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/service/multiplication/Multiplication.html"><B>Multiplication</B></A> - class com.bolour.sample.eclipse.service.multiplication.<A HREF="../com/bolour/sample/eclipse/service/multiplication/Multiplication.html">Multiplication</A>.<DD>Callback class for the multiplication function.<DT><A HREF="../com/bolour/sample/eclipse/service/multiplication/Multiplication.html#Multiplication()"><B>Multiplication()</B></A> -
+Constructor for class com.bolour.sample.eclipse.service.multiplication.<A HREF="../com/bolour/sample/eclipse/service/multiplication/Multiplication.html">Multiplication</A>
+<DD>&nbsp;
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-7.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-9.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-8.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index-files/index-9.html b/Article-Plug-in-architecture/doc/index-files/index-9.html
new file mode 100644
index 0000000..b7401e5
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index-files/index-9.html
@@ -0,0 +1,120 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: P-Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-8.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-10.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-9.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+<A NAME="_P_"><!-- --></A><H2>
+<B>P</B></H2>
+<DL>
+<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html"><B>PrintMemberIdentity</B></A> - class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html">PrintMemberIdentity</A>.<DD>Extension-point member-processing implementation class to print
+ identifying information about a member.<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html#PrintMemberIdentity(java.lang.String)"><B>PrintMemberIdentity(String)</B></A> -
+Constructor for class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html">PrintMemberIdentity</A>
+<DD>Constructor.
+<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html"><B>PrintMemberMenuAction</B></A> - class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html">PrintMemberMenuAction</A>.<DD>Event handler for menu to print extension members.<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html#PrintMemberMenuAction()"><B>PrintMemberMenuAction()</B></A> -
+Constructor for class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html">PrintMemberMenuAction</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html#process(com.bolour.sample.eclipse.service.ui.FunctionsGrid)"><B>process(FunctionsGrid)</B></A> -
+Static method in class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html">ProcessServiceMembers</A>
+<DD>Perform initial extension processing for the members of the
+ <code>functions</code> extension-point.
+<DT><A HREF="../com/bolour/sample/eclipse/demo/IProcessMember.html#process(org.eclipse.core.runtime.IExtension, org.eclipse.core.runtime.IConfigurationElement)"><B>process(IExtension, IConfigurationElement)</B></A> -
+Method in interface com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A>
+<DD>Process a particular member (top-level element) of an extension.
+<DT><A HREF="../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html#process(org.eclipse.core.runtime.IExtension, org.eclipse.core.runtime.IConfigurationElement)"><B>process(IExtension, IConfigurationElement)</B></A> -
+Method in class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/PrintMemberIdentity.html">PrintMemberIdentity</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/demo/ProcessExtensions.html#process(java.lang.String, com.bolour.sample.eclipse.demo.IProcessMember)"><B>process(String, IProcessMember)</B></A> -
+Static method in class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/ProcessExtensions.html">ProcessExtensions</A>
+<DD>Loop over all members of all extensions of an extension-point.
+<DT><A HREF="../com/bolour/sample/eclipse/demo/ProcessExtensions.html"><B>ProcessExtensions</B></A> - class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/ProcessExtensions.html">ProcessExtensions</A>.<DD>Generic extension-processing class: for looping over all members
+ of all extensions of an extension-point, and calling a processing function on each.<DT><A HREF="../com/bolour/sample/eclipse/demo/ProcessExtensions.html#ProcessExtensions()"><B>ProcessExtensions()</B></A> -
+Constructor for class com.bolour.sample.eclipse.demo.<A HREF="../com/bolour/sample/eclipse/demo/ProcessExtensions.html">ProcessExtensions</A>
+<DD>&nbsp;
+<DT><A HREF="../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html"><B>ProcessServiceMembers</B></A> - class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html">ProcessServiceMembers</A>.<DD>Extension processing logic for the <code>functions</code> extension-point.<DT><A HREF="../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html#ProcessServiceMembers()"><B>ProcessServiceMembers()</B></A> -
+Constructor for class com.bolour.sample.eclipse.service.ui.<A HREF="../com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html">ProcessServiceMembers</A>
+<DD>&nbsp;
+</DL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="index-8.html"><B>PREV LETTER</B></A>&nbsp;
+&nbsp;<A HREF="index-10.html"><B>NEXT LETTER</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-9.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="index-1.html">A</A> <A HREF="index-2.html">C</A> <A HREF="index-3.html">D</A> <A HREF="index-4.html">E</A> <A HREF="index-5.html">F</A> <A HREF="index-6.html">I</A> <A HREF="index-7.html">L</A> <A HREF="index-8.html">M</A> <A HREF="index-9.html">P</A> <A HREF="index-10.html">R</A> <A HREF="index-11.html">S</A> <A HREF="index-12.html">T</A> <A HREF="index-13.html">U</A> <HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/index.html b/Article-Plug-in-architecture/doc/index.html
new file mode 100644
index 0000000..68702c3
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/index.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd>
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003-->
+<TITLE>
+Generated Documentation (Untitled)
+</TITLE>
+</HEAD>
+<FRAMESET cols="20%,80%">
+<FRAMESET rows="30%,70%">
+<FRAME src="overview-frame.html" name="packageListFrame">
+<FRAME src="allclasses-frame.html" name="packageFrame">
+</FRAMESET>
+<FRAME src="overview-summary.html" name="classFrame">
+</FRAMESET>
+<NOFRAMES>
+<H2>
+Frame Alert</H2>
+
+<P>
+This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+<BR>
+Link to <A HREF="overview-summary.html">Non-frame version.</A></NOFRAMES>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/overview-frame.html b/Article-Plug-in-architecture/doc/overview-frame.html
new file mode 100644
index 0000000..fa5feae
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/overview-frame.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Overview
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameTitleFont">
+<B></B></FONT></TD>
+</TR>
+</TABLE>
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="allclasses-frame.html" TARGET="packageFrame">All Classes</A></FONT>
+<P>
+<FONT size="+1" CLASS="FrameHeadingFont">
+Packages</FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/demo/package-frame.html" TARGET="packageFrame">com.bolour.sample.eclipse.demo</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/listener/firstlistener/package-frame.html" TARGET="packageFrame">com.bolour.sample.eclipse.listener.firstlistener</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/listener/secondlistener/package-frame.html" TARGET="packageFrame">com.bolour.sample.eclipse.listener.secondlistener</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/listener/subject/package-frame.html" TARGET="packageFrame">com.bolour.sample.eclipse.listener.subject</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/service/echo/package-frame.html" TARGET="packageFrame">com.bolour.sample.eclipse.service.echo</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/service/errortest/package-frame.html" TARGET="packageFrame">com.bolour.sample.eclipse.service.errortest</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/service/exponentiation/package-frame.html" TARGET="packageFrame">com.bolour.sample.eclipse.service.exponentiation</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/service/multiplication/package-frame.html" TARGET="packageFrame">com.bolour.sample.eclipse.service.multiplication</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="com/bolour/sample/eclipse/service/ui/package-frame.html" TARGET="packageFrame">com.bolour.sample.eclipse.service.ui</A></FONT>
+<BR>
+</TD>
+</TR>
+</TABLE>
+
+<P>
+&nbsp;
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/overview-summary.html b/Article-Plug-in-architecture/doc/overview-summary.html
new file mode 100644
index 0000000..c10cc42
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/overview-summary.html
@@ -0,0 +1,147 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+: Overview
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="overview-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Samples for Notes on the Eclipse Plug-in Architecture</H2>
+</CENTER>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Packages</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="com/bolour/sample/eclipse/demo/package-summary.html">com.bolour.sample.eclipse.demo</A></B></TD>
+<TD>
+Generic extension processing demo.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="com/bolour/sample/eclipse/listener/firstlistener/package-summary.html">com.bolour.sample.eclipse.listener.firstlistener</A></B></TD>
+<TD>
+A sample listener plug-in package.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="com/bolour/sample/eclipse/listener/secondlistener/package-summary.html">com.bolour.sample.eclipse.listener.secondlistener</A></B></TD>
+<TD>
+A sample listener plug-in package.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="com/bolour/sample/eclipse/listener/subject/package-summary.html">com.bolour.sample.eclipse.listener.subject</A></B></TD>
+<TD>
+A plug-in acting as the subject of observations.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="com/bolour/sample/eclipse/service/echo/package-summary.html">com.bolour.sample.eclipse.service.echo</A></B></TD>
+<TD>
+An echo plug-in.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="com/bolour/sample/eclipse/service/errortest/package-summary.html">com.bolour.sample.eclipse.service.errortest</A></B></TD>
+<TD>
+Test plugin for <code>functions</code> extension errors.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="com/bolour/sample/eclipse/service/exponentiation/package-summary.html">com.bolour.sample.eclipse.service.exponentiation</A></B></TD>
+<TD>
+An exponentiation plug-in.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="com/bolour/sample/eclipse/service/multiplication/package-summary.html">com.bolour.sample.eclipse.service.multiplication</A></B></TD>
+<TD>
+A multiplication plug-in.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="com/bolour/sample/eclipse/service/ui/package-summary.html">com.bolour.sample.eclipse.service.ui</A></B></TD>
+<TD>
+A UI plugin for invoking integer arithmetic operations.</TD>
+</TR>
+</TABLE>
+
+<P>
+&nbsp;<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="overview-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/overview-tree.html b/Article-Plug-in-architecture/doc/overview-tree.html
new file mode 100644
index 0000000..45c9e46
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/overview-tree.html
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:49 PDT 2003 -->
+<TITLE>
+: Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="overview-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For All Packages</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="com/bolour/sample/eclipse/demo/package-tree.html">com.bolour.sample.eclipse.demo</A>, <A HREF="com/bolour/sample/eclipse/listener/firstlistener/package-tree.html">com.bolour.sample.eclipse.listener.firstlistener</A>, <A HREF="com/bolour/sample/eclipse/listener/secondlistener/package-tree.html">com.bolour.sample.eclipse.listener.secondlistener</A>, <A HREF="com/bolour/sample/eclipse/listener/subject/package-tree.html">com.bolour.sample.eclipse.listener.subject</A>, <A HREF="com/bolour/sample/eclipse/service/echo/package-tree.html">com.bolour.sample.eclipse.service.echo</A>, <A HREF="com/bolour/sample/eclipse/service/errortest/package-tree.html">com.bolour.sample.eclipse.service.errortest</A>, <A HREF="com/bolour/sample/eclipse/service/exponentiation/package-tree.html">com.bolour.sample.eclipse.service.exponentiation</A>, <A HREF="com/bolour/sample/eclipse/service/multiplication/package-tree.html">com.bolour.sample.eclipse.service.multiplication</A>, <A HREF="com/bolour/sample/eclipse/service/ui/package-tree.html">com.bolour.sample.eclipse.service.ui</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.errortest.<A HREF="com/bolour/sample/eclipse/service/errortest/Dummy.html"><B>Dummy</B></A><LI TYPE="circle">class com.bolour.sample.eclipse.service.echo.<A HREF="com/bolour/sample/eclipse/service/echo/Echo.html"><B>Echo</B></A> (implements com.bolour.sample.eclipse.service.ui.<A HREF="com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.exponentiation.<A HREF="com/bolour/sample/eclipse/service/exponentiation/Exponentiation.html"><B>Exponentiation</B></A> (implements org.eclipse.core.runtime.IExecutableExtension, com.bolour.sample.eclipse.service.ui.<A HREF="com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.ui.<A HREF="com/bolour/sample/eclipse/service/ui/FunctionsGrid.html"><B>FunctionsGrid</B></A><LI TYPE="circle">class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="com/bolour/sample/eclipse/listener/firstlistener/ListenerX.html"><B>ListenerX</B></A> (implements com.bolour.sample.eclipse.listener.subject.<A HREF="com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="com/bolour/sample/eclipse/listener/secondlistener/ListenerX.html"><B>ListenerX</B></A> (implements com.bolour.sample.eclipse.listener.subject.<A HREF="com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.firstlistener.<A HREF="com/bolour/sample/eclipse/listener/firstlistener/ListenerY.html"><B>ListenerY</B></A> (implements com.bolour.sample.eclipse.listener.subject.<A HREF="com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.secondlistener.<A HREF="com/bolour/sample/eclipse/listener/secondlistener/ListenerY.html"><B>ListenerY</B></A> (implements com.bolour.sample.eclipse.listener.subject.<A HREF="com/bolour/sample/eclipse/listener/subject/IListener.html">IListener</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.multiplication.<A HREF="com/bolour/sample/eclipse/service/multiplication/Multiplication.html"><B>Multiplication</B></A> (implements org.eclipse.core.runtime.IExecutableExtension, com.bolour.sample.eclipse.service.ui.<A HREF="com/bolour/sample/eclipse/service/ui/IFunction.html">IFunction</A>)
+<LI TYPE="circle">class org.eclipse.core.runtime.Plugin<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.listener.subject.<A HREF="com/bolour/sample/eclipse/listener/subject/Subject.html"><B>Subject</B></A></UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.demo.<A HREF="com/bolour/sample/eclipse/demo/PrintMemberIdentity.html"><B>PrintMemberIdentity</B></A> (implements com.bolour.sample.eclipse.demo.<A HREF="com/bolour/sample/eclipse/demo/IProcessMember.html">IProcessMember</A>)
+<LI TYPE="circle">class com.bolour.sample.eclipse.demo.<A HREF="com/bolour/sample/eclipse/demo/PrintMemberMenuAction.html"><B>PrintMemberMenuAction</B></A> (implements org.eclipse.ui.IWorkbenchWindowActionDelegate)
+<LI TYPE="circle">class com.bolour.sample.eclipse.demo.<A HREF="com/bolour/sample/eclipse/demo/ProcessExtensions.html"><B>ProcessExtensions</B></A><LI TYPE="circle">class com.bolour.sample.eclipse.service.ui.<A HREF="com/bolour/sample/eclipse/service/ui/ProcessServiceMembers.html"><B>ProcessServiceMembers</B></A><LI TYPE="circle">class com.bolour.sample.eclipse.listener.subject.<A HREF="com/bolour/sample/eclipse/listener/subject/UpdateMenuAction.html"><B>UpdateMenuAction</B></A> (implements org.eclipse.ui.IWorkbenchWindowActionDelegate)
+<LI TYPE="circle">class org.eclipse.ui.part.WorkbenchPart (implements org.eclipse.core.runtime.IExecutableExtension, org.eclipse.ui.IWorkbenchPart)
+<UL>
+<LI TYPE="circle">class org.eclipse.ui.part.ViewPart (implements org.eclipse.ui.IViewPart)
+<UL>
+<LI TYPE="circle">class com.bolour.sample.eclipse.service.ui.<A HREF="com/bolour/sample/eclipse/service/ui/FunctionsViewPart.html"><B>FunctionsViewPart</B></A></UL>
+</UL>
+</UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">interface com.bolour.sample.eclipse.service.ui.<A HREF="com/bolour/sample/eclipse/service/ui/IFunction.html"><B>IFunction</B></A><LI TYPE="circle">interface com.bolour.sample.eclipse.listener.subject.<A HREF="com/bolour/sample/eclipse/listener/subject/IListener.html"><B>IListener</B></A><LI TYPE="circle">interface com.bolour.sample.eclipse.demo.<A HREF="com/bolour/sample/eclipse/demo/IProcessMember.html"><B>IProcessMember</B></A></UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="overview-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/package-list b/Article-Plug-in-architecture/doc/package-list
new file mode 100644
index 0000000..20a9b7d
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/package-list
@@ -0,0 +1,9 @@
+com.bolour.sample.eclipse.demo
+com.bolour.sample.eclipse.listener.firstlistener
+com.bolour.sample.eclipse.listener.secondlistener
+com.bolour.sample.eclipse.listener.subject
+com.bolour.sample.eclipse.service.echo
+com.bolour.sample.eclipse.service.errortest
+com.bolour.sample.eclipse.service.exponentiation
+com.bolour.sample.eclipse.service.multiplication
+com.bolour.sample.eclipse.service.ui
diff --git a/Article-Plug-in-architecture/doc/packages.html b/Article-Plug-in-architecture/doc/packages.html
new file mode 100644
index 0000000..1c42c0f
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/packages.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<BR>
+
+<BR>
+
+<BR>
+<CENTER>
+The front page has been relocated.Please see:
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="index.html">Frame version</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="overview-summary.html">Non-frame version.</A></CENTER>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/serialized-form.html b/Article-Plug-in-architecture/doc/serialized-form.html
new file mode 100644
index 0000000..243d4d6
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/serialized-form.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Tue Jul 01 16:29:50 PDT 2003 -->
+<TITLE>
+Serialized Form
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="serialized-form.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H1>
+Serialized Form</H1>
+</CENTER>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="serialized-form.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/Article-Plug-in-architecture/doc/stylesheet.css b/Article-Plug-in-architecture/doc/stylesheet.css
new file mode 100644
index 0000000..95f5764
--- /dev/null
+++ b/Article-Plug-in-architecture/doc/stylesheet.css
@@ -0,0 +1,29 @@
+/* Javadoc style sheet */
+
+/* Define colors, fonts and other style attributes here to override the defaults */
+
+/* Page background color */
+body { background-color: #FFFFFF }
+
+/* Table colors */
+.TableHeadingColor { background: #CCCCFF } /* Dark mauve */
+.TableSubHeadingColor { background: #EEEEFF } /* Light mauve */
+.TableRowColor { background: #FFFFFF } /* White */
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont { font-size: normal; font-family: normal }
+.FrameHeadingFont { font-size: normal; font-family: normal }
+.FrameItemFont { font-size: normal; font-family: normal }
+
+/* Example of smaller, sans-serif font in frames */
+/* .FrameItemFont { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */
+
+/* Navigation bar fonts and colors */
+.NavBarCell1 { background-color:#EEEEFF;}/* Light mauve */
+.NavBarCell1Rev { background-color:#00008B;}/* Dark Blue */
+.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
+
+.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+
diff --git a/Article-Plug-in-architecture/images/Idea.jpg b/Article-Plug-in-architecture/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Plug-in-architecture/images/Idea.jpg
Binary files differ
diff --git a/Article-Plug-in-architecture/images/eclipse_extensions.jpg b/Article-Plug-in-architecture/images/eclipse_extensions.jpg
new file mode 100644
index 0000000..59bd63c
--- /dev/null
+++ b/Article-Plug-in-architecture/images/eclipse_extensions.jpg
Binary files differ
diff --git a/Article-Plug-in-architecture/images/functions_grid_view.jpg b/Article-Plug-in-architecture/images/functions_grid_view.jpg
new file mode 100644
index 0000000..50df960
--- /dev/null
+++ b/Article-Plug-in-architecture/images/functions_grid_view.jpg
Binary files differ
diff --git a/Article-Plug-in-architecture/images/linux_only.gif b/Article-Plug-in-architecture/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Plug-in-architecture/images/linux_only.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/listeners_extensions.jpg b/Article-Plug-in-architecture/images/listeners_extensions.jpg
new file mode 100644
index 0000000..a7be10f
--- /dev/null
+++ b/Article-Plug-in-architecture/images/listeners_extensions.jpg
Binary files differ
diff --git a/Article-Plug-in-architecture/images/services_extensions.jpg b/Article-Plug-in-architecture/images/services_extensions.jpg
new file mode 100644
index 0000000..c6b47dc
--- /dev/null
+++ b/Article-Plug-in-architecture/images/services_extensions.jpg
Binary files differ
diff --git a/Article-Plug-in-architecture/images/tag_1.gif b/Article-Plug-in-architecture/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Plug-in-architecture/images/tag_1.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/tag_2.gif b/Article-Plug-in-architecture/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Plug-in-architecture/images/tag_2.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/tag_3.gif b/Article-Plug-in-architecture/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Plug-in-architecture/images/tag_3.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/tag_4.gif b/Article-Plug-in-architecture/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Plug-in-architecture/images/tag_4.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/tag_5.gif b/Article-Plug-in-architecture/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Plug-in-architecture/images/tag_5.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/tag_6.gif b/Article-Plug-in-architecture/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Plug-in-architecture/images/tag_6.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/tag_7.gif b/Article-Plug-in-architecture/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Plug-in-architecture/images/tag_7.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/tip.gif b/Article-Plug-in-architecture/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Plug-in-architecture/images/tip.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/tryit.gif b/Article-Plug-in-architecture/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Plug-in-architecture/images/tryit.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/images/win_only.gif b/Article-Plug-in-architecture/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Plug-in-architecture/images/win_only.gif
Binary files differ
diff --git a/Article-Plug-in-architecture/plugin_architecture.html b/Article-Plug-in-architecture/plugin_architecture.html
new file mode 100644
index 0000000..671cf90
--- /dev/null
+++ b/Article-Plug-in-architecture/plugin_architecture.html
@@ -0,0 +1,2574 @@
+
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<title>Notes on the Eclipse Plug-in Architecture</title>
+<link rel="stylesheet" href="../default_style.css">
+<link rel="stylesheet" href="specific_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2003 Bolour Computing</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">Notes on the Eclipse Plug-in Architecture</h1>
+
+<blockquote>
+<b>Summary</b>
+
+<br>
+Eclipse plug-ins embody an architectural pattern for building an
+application from constituent parts. This article presents an in-depth view
+of the participant roles and collaborations of this architectural pattern,
+as they exist in an instance of the Eclipse workbench. The goal is to
+provide an understanding of plug-ins, and of how plug-in extensions are
+defined and processed, independently of the mechanics of using the Eclipse
+workbench to produce plug-ins.
+
+ <p><b> Azad Bolour, Bolour Computing</b> <br>
+ <font size="-1">July 3, 2003</font> </p>
+
+<p><b>Table of Contents</b> <br>
+
+<a href="#1.">1. Introduction</a>
+<br>
+<a href="#2.">2. The Eclipse Plug-in Model</a>
+<br>
+<a href="#3.">3. Extension Processing</a>
+<br>
+<a href="#4.">4. Example: An Extensible Arithmetic Function Service</a>
+<br>
+<a href="#5.">5. Listener Extensions and the Observer Pattern</a>
+<br>
+<a href="#6.">6. Summary and Conclusions</a>
+
+</blockquote>
+
+<hr width="100%">
+
+
+<a name="1."> </a>
+<h2>
+1. Introduction
+</h2>
+
+<p> <a href="http://www.eclipse.org">Eclipse</a> is an extensible platform
+for building IDEs. It provides a core of services for controlling a set of
+tools working together to support programming tasks. Tool builders
+contribute to the Eclipse platform by wrapping their tools in pluggable
+components, called <i>Eclipse plug-ins</i>, which conform to Eclipse's
+plug-in contract. The basic mechanism of extensibility in Eclipse is that
+new plug-ins can add new processing elements to existing plug-ins. And
+Eclipse provides a set of core plug-ins to bootstrap this process.
+For a general introduction to Eclipse as an extensible IDE platform,
+see the literature available at <a href="http://www.eclipse.org">
+this site</a>.
+
+<p> Even though the Eclipse platform is specialized for building IDEs, the
+core of its concepts and facilities supports a general model for composing
+an application from constituent parts developed by multiple vendors. This
+general model of system composition in Eclipse will be described and placed
+in the context of other software patterns in this article. The article is
+intended for new plug-in developers who need to understand the overall
+model of how plug-ins work, either before, or in conjunction with, working
+through the mechanics of building plug-ins.
+
+<p> The article is structured as follows. Section 2 outlines the Eclipse
+plug-in model and the declarative specification of plug-ins and their
+relationships within this model. Section 3 explains what plug-in
+developers must do programmatically to allow their plug-ins to be extended.
+Section 4 provides a complete example of an extensible plug-in and its
+extensions by other plug-ins. Section 5 contrasts the Eclipse plug-in
+model with the much simpler <i>observer pattern</i> of [1]. Section 6
+concludes the article by summarizing the main architectural concepts used
+in Eclipse plug-ins.
+
+<p> This article specifically avoids the mechanics of the required user
+interactions with the Eclipse plug-in development environment (PDE) to
+build and test plug-ins. See Beck and Gamma [2], Shavor, et. al. [3], the
+online help documentation, and other articles at <a
+href="http://www.eclipse.org">this site</a> for the required procedures to
+build and test plug-ins in the PDE.
+
+<p>
+The <a href="samples.zip">companion plug-ins zip file</a> includes
+the plug-in samples appearing in this article.
+<a href="#instructions">Installation instructions </a>
+for the samples appear at the end of this article.
+Also accompanying this article is the
+<a href="doc/index.html">samples API reference</a>.
+
+<a name="2."> </a>
+<h2>
+2. The Eclipse Plug-in Model
+</h2>
+
+<p> A plug-in in Eclipse is a component that provides a certain type of
+service within the context of the Eclipse workbench. By a component here I
+mean an object that may be configured into a system at system deployment
+time. The Eclipse runtime provides an infrastructure to support the
+activation and operation of a set of plug-ins working together to provide a
+seamless environment for development activities. Within a running Eclipse
+instance, a plug-in is embodied in an instance of some <var>plug-in
+runtime class</var>, or <var>plug-in class</var>, for short. The plug-in
+class provides configuration and management support for the plug-in
+instance. A plug-in class in Eclipse must extend
+<var>org.eclipse.core.runtime.Plugin</var>, which is an abstract class that
+provides generic facilities for managing plug-ins.
+
+<p> An Eclipse installation includes a <code>plugins</code> folder where
+individual plug-ins are deployed. Each plug-in is installed in its own
+folder under the <code>plugins</code> folder. A plug-in is described in an
+XML manifest file, called <code>plugin.xml</code>, residing in the
+plug-in's folder. The manifest file tells the Eclipse runtime what it needs
+to know to activate the plug-in.
+
+<p> The parsed contents of plug-in manifest files are made available
+programmatically through a <i>plug-in registry API</i>. And parsed plug-in
+specifications are cached in an in-memory repository called the <i>plug-in
+registry</i>. The Eclipse runtime instantiates an instance of each plug-in
+by using the plug-in registry API. The plug-in registry API is also used
+by provider-supplied plug-in code to obtain information about
+plug-ins.
+
+<p>
+Here is what a minimal plug-in manifest file looks like:
+
+<p>
+<table width=350 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;plugin
+ name="JUnit Testing Framework"
+ id="org.junit"
+ version="3.7"
+ provider-name="Eclipse.org"&gt;
+ &lt;runtime&gt;
+ &lt;library name="junit.jar"&gt;
+ &lt;export name="*"/&gt;
+ &lt;/library&gt;
+ &lt;/runtime&gt;
+&lt;/plugin&gt;
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 2.1. A Minimal Plug-in Manifest File.
+</td></tr> </table>
+
+<p> This manifest file describes a plug-in that provides the services of
+the <i>JUnit</i> testing infrastructure to the Eclipse workbench. (Note.
+To improve readability, the contents of Eclipse manifest files, such as
+this one, are reproduced in this article in their English localization.)
+
+<p>
+<a href="http://www.eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/reference/misc/rplugman.html">
+The Eclipse Platform Plug-in Manifest Specification</a> documents
+the XML elements and attributes used in defining plug-ins.
+(This specification is also available in the Eclipse platform
+help documentation under <i>Platform Plug-In Developer Guide/Other
+reference information/Plug-in manifest</i>).
+
+<p> I am not going to focus on the contents of the plug-in manifest file
+at this time, except to note that each plug-in has a unique identifier (XML
+attribute <code>id</code>). The unique identifier is used to refer to a plug-in
+within the manifest files of other, related, plug-ins. The unique
+identifier may also be used within provider-supplied plug-in code to access
+the plug-in's running instance, as follows:
+
+<code>
+<pre>
+ Plugin p = Platform.getPlugin(pluginID);
+</pre>
+</code>
+
+<p>
+Plug-in instances are managed by the Eclipse runtime, and
+are accessed by using the Eclipse platform as shown above. Plug-in
+instances are not constructed by application programs.
+
+<h3>
+2.1. Plug-in Deployment and Activation
+</h3>
+
+<p>
+Deploying a plug-in in an Eclipse installation involves
+copying the resources that constitute the plug-in (the manifest file,
+jar files, and other resources) into an individual folder
+for the plug-in, under the installation's <code>plugins</code> directory.
+Such a plug-in can then be <i>activated</i> by the Eclipse runtime
+when it is required to perform some function. Activating a plug-in means
+loading its runtime class and instantiating and initializing its
+instance.
+
+<p>
+The main function of a plug-in class is to do special processing during
+plug-in activation and deactivation, e.g., to allocate and release
+resources. For simple plug-ins, like the <code>JUnit</code> plug-in above, no
+specific activation or deactivation processing is required, and therefore
+no specific plug-in class need be provided by the plug-in designer. In that
+case, the Eclipse runtime automatically provides a default plug-in class
+for the plug-in instance.
+
+<p> When the plug-in needs to do something specific to activate or
+deactivate itself, the plug-in designer subclasses
+<code>org.eclipse.core.runtime.Plugin</code>, provides overrides for the
+activation and deactivation methods of the class, respectively called
+<var>startup</var> and <var>shutdown</var>, and includes the
+fully-qualified name of this specific plug-in subclass as the value of the
+attribute <code>class</code> in the corresponding plug-in manifest file.
+
+<p> Eclipse includes a plug-in management kernel, known as the Eclipse
+<i>platform</i>, or the Eclipse <i>runtime</i>, and certain core plug-ins
+that are present in every Eclipse deployment. The identities of these core
+plug-ins are hard-coded into the Eclipse platform, and the platform knows to
+activate these plug-ins in each running instance of Eclipse. Non-core
+plug-ins, on the other hand, are activated when required by other plug-ins,
+as described below.
+
+<p> In the Eclipse model, a plug-in may be related to another plug-in by one
+of two relationships:
+
+<p>
+<ul>
+<li>
+<i>Dependency</i>. The roles in this relationship are <i>dependent
+plug-in</i> and <i>prerequisite plug-in</i>. A prerequisite plug-in supports the
+functions of a dependent plug-in.
+
+<li>
+<i>Extension</i>. The roles in this relationship are <i>host plug-in</i> and
+<i>extender plug-in</i>. An extender plug-in extends the functions of a
+host plug-in.
+
+</ul>
+
+<p> These relationships are specified declaratively in plug-in manifest
+files through the XML elements <code>requires</code> and
+<code>extension</code> (the details of which appear in later subsections).
+
+<p> A non-core plug-in that has been deployed in an Eclipse installation
+may be activated in a running instance of Eclipse if it is transitively
+related to a core Eclipse plug-in by the union of the dependency and the
+extension relations. Such a plug-in will be activated when its functions
+are required to support or to extend the functions of another plug-in. A
+plug-in that is deployed but unreachable from any core plug-in via the
+dependency and extension relations might as well not be deployed from the
+point of view of plug-in activation. Of course, even a reachable plug-in
+may remain unactivated in a running instance for some time (or for the
+lifetime of the instance), if no user action or other triggering event
+elicits its use.
+
+<h3>
+2.2. Dependency
+</h3>
+
+<p> When a plug-in is dependent on other plug-ins for its functions, the
+dependency is specified via a <code>requires</code> element in the plug-in manifest
+file. Here is an example:
+
+<p>
+<table width=350 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;plugin
+ id="com.bolour.sample.eclipse.demo"
+ name="Extension Processing Demo"
+ version="1.0.0"&gt;
+ &lt;runtime&gt;
+ &lt;library name="demo.jar"/&gt;
+ &lt;/runtime&gt;
+ &lt;requires&gt;
+ &lt;import plugin="org.eclipse.ui"/&gt;
+ &lt;/requires&gt;
+&lt;/plugin&gt;
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 2.2. Specifying Plug-in Dependencies.
+</td></tr> </table>
+
+
+<p>
+In this example, the sample plug-in <code>com.bolour.sample.eclipse.demo</code>
+is declared to be dependent on (i.e., to make use of) the base Eclipse
+UI plug-in <code>org.eclipse.ui</code>.
+
+<p> Dependency as defined in the plug-in manifest file is both a runtime
+and a compile-time directive. At runtime, Eclipse has to make sure that a
+prerequisite plug-in can be made available to a dependent plug-in when the
+dependent plug-in is activated. At compile time, Eclipse can be directed to
+augment the classpath for compiling a dependent plug-in by the jar files of
+all of its prerequisite plug-ins.
+
+<h3>
+2.3. Extension
+</h3>
+
+<p> When the facilities of a plug-in are to be made directly available to
+the user, one or more user interface elements have to be added to the base
+Eclipse workbench. For example, to make the workbench's <i>help</i> plug-in
+available to the user, <i>help</i> menu items must be added to the
+workbench user interface.
+
+<p> The process of adding some processing element or elements to a plug-in
+is known as an <i>extension</i>. This process is not restricted to UI
+elements, however. Any plug-in may allow other plug-ins to extend it by
+adding processing elements. An extension is defined by an <i>extender
+plug-in</i> and causes a <i>host plug-in</i> to modify its behavior.
+Typically, this modification of behavior includes the addition of
+processing elements to the host plug-in (e.g., the addition of new menu
+items to the Eclipse workbench), and the customization of the behavior of
+these additional elements by services provided by the extender plug-in
+(e.g., the customization of new menu items by specific menu event
+handlers).
+
+<p> In simple cases, a single act of extension adds a single <i>callback
+object</i> to the environment, through which the host and extender plug-ins
+communicate. The callback object is different from the host and extender
+plug-in objects. And unlike these objects, which are components that are
+automatically instantiated and managed by the Eclipse platform, a callback
+object is a <i>plain old Java objects</i> that is instantiated and managed
+specifically by provider-supplied code. A single act of extension can also
+add more than one callback object to the environment. For example, Eclipse
+allows a set of menus to be added to its user interface via a single
+extension.
+
+<p> Note, however, that the extension model, per se, is quite general, and
+does not necessarily require that an extender plug-in provide custom
+callback objects. It is possible, for example, that the kind of behavior
+modification required of a host plug-in can be provided entirely by objects
+whose classes are known to the host plug-in at compile-time, so that an
+extension declaration serves merely to parameterize instances of such
+built-in classes.
+
+<p> Similarly, the extension model, per se, does not require that
+the host plug-in directly expose aspects of each of its extensions
+in its interface. For example, an extension may merely ask that
+an extender plug-in be notified of certain events known to occur
+in the host plug-in independently of the extender plug-in, without
+any changes visible in the host plug-in's interface.
+
+<p> A plug-in may allow itself to be augmented by different kinds of
+extensions. For example, the workbench UI allows both its menus and its
+editors to be extended. In each case, the extension must conform to a
+unique set of configuration and behavioral requirements. Therefore, an
+extensible plug-in provides different types of slots that extensions can
+plug into. These slot types are called <i>extension points</i>. In the
+remainder of this article I will use the compound form
+<i>extension-point</i> to refer to these slots. An extension-point allows
+any number of extensions to be plugged into it.
+
+<p> <i>Extension</i> and <i>extension-point</i> are standard Eclipse
+plug-in terminology. <i>Host plug-in</i>, <i>extender plug-in</i>, and
+<i>callback object</i> are terms used in this article to describe
+the different roles of objects in an extension.
+
+<p> Figure 1 illustrates the relationships between the participants of an
+extension, in this case, the extension of the Eclipse workbench by the menu
+items of the Eclipse help system. In this extension, the host plug-in is
+the Eclipse workbench user interface, <code>org.eclipse.ui</code>, whose
+menus can be extended via an extension-point known as
+<code>actionSets</code>. The extender plug-in is the Eclipse help system's
+user interface, <code>org.eclipse.help.ui</code>. In order to make help
+functions available to the user, the help UI plug-in uses the
+<code>actionSets</code> extension-point to extend the workbench UI plug-in
+by specific help-related menu items, among them, <i>Help-&gt;Help
+Contents</i> and <i>Search-&gt;Help</i>. The extension is defined by the
+extender plug-in. And in this case, the single extension augments the
+workbench UI by multiple menu items.
+
+
+<P>
+<spacer type=vertical size=10>
+
+<CENTER>
+<IMG SRC="images/eclipse_extensions.jpg" ALT="Figure-1" BORDER="0">
+</CENTER>
+
+<BR>
+<table align=center width=600>
+<tr><td>
+Figure 1. Participants of a plug-in extension. The workbench UI plug-in
+is extended by the workbench help plug-in via an
+<i>actionSets</i> extension that defines specific help-related menu items.
+</td></tr>
+</table>
+
+<P>
+<spacer type=vertical size=10>
+
+<p>
+(The extension-point <i>power-strip</i> notation used in this article
+was devised by Don Estberg [5].)
+
+<p> Also shown in the figure are the classes of the extension's callback
+objects: that is, the classes of the help system's menu handlers. As we
+will see shortly, callback classes are typically identified by name in the
+declarative specification of each extension. Thus, this extension's
+<i>Help-&gt;Help Contents</i> menu specification declares its custom
+callback class (menu handler) to be <code>HelpContentsAction</code>. And
+the extension's <i>Search-&gt;Help</i> menu specification declares its
+custom callback class (menu handler) to be
+<code>OpenHelpSearchPageAction</code> (see blow for details).
+
+<p> Note that to reduce clutter, package prefixes are not shown in this and
+later figures. Here the workbench plug-in class belongs to the
+<code>org.eclipse.ui.internal</code> package; and the help plug-in and
+related classes belong to the <code>org.eclipse.help.ui.internal</code>
+package.
+
+<p>
+The remainder of this section provides a detailed account of how
+extension-points and extensions are defined.
+
+<h4>
+2.3.1 Participants of an Extension
+</h4>
+
+<p>
+Let us now look more closely at the various roles played by the objects
+participating in an extension. There are two plug-in roles, <i>host</i>
+and <i>extender</i>, a generic role of a <i>callback</i> object,
+and <i>specific callback</i> roles defined by each extension-point.
+
+<h5>
+2.3.1.1. The Host Plug-in Role
+</h5>
+
+<p> In the context of a particular extension, a plug-in that stands in the
+<i>host</i> role provides the extension-point and is extended. In addition
+to providing services in its own right, such a plug-in also acts as the
+coordinator and controller of a number of extensions.
+
+<p> Within the host plug-in's manifest file, an extension-point is declared
+in an <i>extension-point XML element</i>. Here is an example of
+such an element, culled from the base Eclipse workbench UI plug-in,
+<code>org.eclipse.ui</code>:
+
+<p>
+<table bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;plugin
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> id="org.eclipse.ui"
+ name="Eclipse UI"
+ version="2.1.0"
+ provider-name="Eclipse.org"
+ class="org.eclipse.ui.internal.UIPlugin"&gt;
+
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> &lt;extension-point id="actionSets" name="Action Sets"
+ schema="schema/actionSets.exsd"/&gt;
+ &lt;!-- Other specifications omitted. --&gt;
+&lt;/plugin&gt;
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 2.3. Declaring an Extension-Point.
+</td></tr> </table>
+
+<p>
+The documentation for this extension-point is provided in a
+<a
+href="http://www.eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/reference/extension-points/org_eclipse_ui_actionSets.html">
+reference page</a>
+(and is also available in the Eclipse platform on-line help at
+<i>Platform Plugin Developer Guide/Reference/Extension Points
+Reference/Workbench/org.eclipse.ui.actionSets</i>). The documentation
+indicates, among other things, that this extension-point provides a plug-in
+slot for sets of menus, menu items, and buttons to be added to the
+base Eclipse workbench.
+
+<p>
+The extension-point specification
+
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER>
+
+defines a unique identifier for the extension-point within this host
+plug-in. To identify an extension-point uniquely in global context, the
+extension-point identifier is prepended with the unique identifier of the
+host plug-in
+
+(as in <img src="images/tag_1.gif" height=13 width=24 align=CENTER>)
+
+to form a <i>fully-qualified</i> identifier for the extension-point.
+Thus, the fully-qualified identifier of the <code>actionSets</code>
+extension-point of the Eclipse UI plug-in is
+<code>org.eclipse.ui.actionSets</code>. Plug-ins that extend an extension-point
+refer to it by its fully-qualified identifier.
+
+<p>
+The extension-point specification
+
+(<img src="images/tag_2.gif" height=13 width=24 align=CENTER>)
+
+also declares an XML schema for the extensions of this extension-point,
+which provides the syntax for declaring menus, menu items, and buttons to
+be added to the workbench UI. We'll have more to say about the structure
+and contents of such a schema in section 2.3.3.
+
+<h5>
+2.3.1.2. The Extender Plug-in Role
+</h5>
+
+<p> In the context of a particular extension, a plug-in that stands in the
+<i>extender</i> role defines the extension, typically making certain
+aspects of itself available to a host plug-in through the extension, and,
+in addition, causing the host plug-in to add certain processing elements to
+its environment. An extension is declared by using an
+<code>extension</code> XML element in the extender plug-in's manifest file.
+Here is an example of an extender plug-in, culled from the
+<code>org.eclipse.help.ui</code> plug-in manifest file, that extends the
+<code>actionSets</code> extension-point of Listing 2.3, by adding two menu
+items:
+
+<a name="listing2.5"> </a>
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+&lt;plugin
+ id="org.eclipse.help.ui"
+ name="Help System UI"
+ version="2.1.0"
+ provider-name="Eclipse.org"
+ class="org.eclipse.help.ui.internal.WorkbenchHelpPlugin"&gt;
+ &lt;!-- ... --&gt;
+ &lt;!-- Action Sets --&gt;
+ &lt;extension
+ <img src="images/tag_1.gif" height=13 width=24 align=CENTER> point="org.eclipse.ui.actionSets"&gt;
+ &lt;actionSet
+ label="Help"
+ visible="true"
+ id="org.eclipse.help.internal.ui.HelpActionSet"&gt;
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> &lt;action
+ label="&amp;Help Contents"
+ icon="icons/view.gif"
+ helpContextId="org.eclipse.help.ui.helpContentsMenu"
+ tooltip="Open Help Contents"
+ class="org.eclipse.help.ui.internal.HelpContentsAction"
+ menubarPath="help/helpEnd"
+ id="org.eclipse.help.internal.ui.HelpAction"&gt;
+ &lt;/action&gt;
+ &lt;!-- ... other actionSet elements --&gt;
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> &lt;action
+ label="&amp;Help..."
+ icon="icons/search_menu.gif"
+ helpContextId="org.eclipse.help.ui.helpSearchMenu"
+ <img src="images/tag_4.gif" height=13 width=24 align=CENTER> class="org.eclipse.help.ui.internal.OpenHelpSearchPageAction"
+ menubarPath="org.eclipse.search.menu/dialogGroup"
+ id="org.eclipse.help.ui.OpenHelpSearchPage"&gt;
+ &lt;/action&gt;
+ &lt;/actionSet&gt;
+ &lt;/extension&gt;
+&lt;!-- ... --&gt;
+&lt;/plugin&gt;
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 2.4. Declaring an Extension.
+</td></tr> </table>
+
+<p>
+Note that in this extender plug-in, the <code>actionSets</code> extension-point
+is referred to by its fully-qualified identifier
+
+(<img src="images/tag_1.gif" height=13 width=24 align=CENTER>).
+
+<p> The portion of the <code>actionSets</code> extension shown in Listing 2.4
+defines two actions
+
+(<img src="images/tag_2.gif" height=13 width=24 align=CENTER>,
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER>).
+
+The actions shown are made available through the workbench menu items
+<i>Help-&gt;Help Contents</i> and <i>Search-&gt;Help</i>, respectively.
+
+<h5>
+2.3.1.3. The Extension Callback Role
+</h5>
+
+<p> In the context of a particular extension, an object that stands in a
+<i>callback</i> role is a plain old Java object (not a plug-in) that is
+called by the host plug-in when certain events specified in the
+corresponding extension-point contract are recognized by the host plug-in.
+The interface for callback objects is provided by the host plug-in, and is
+documented in the documentation of the extension-point being extended. The
+implementation of callback objects is typically a custom class specific to
+the particular extension, and is furnished by the provider of the extender
+plug-in. Because the implementation of the callback object in the extender
+references the callback interface, which is typically packaged with the
+host, an extender plug-in typically also <i>depends on</i> the host
+plug-in.
+
+<a name="2.3.1.3.1."> </a>
+<h6>
+2.3.1.3.1. Specific Callback Roles
+</h6>
+
+<p> Each callback object fills a certain specific role within an extension.
+I will refer to these specific roles simply as <i>callback roles</i>. In
+the XML definition of an extension, callback roles are defined by child or
+descendent XML elements. The <code>actionSets</code> extension-point, for
+example, defines a descendent callback role known as <code>action</code>.
+Multiple callback objects may stand in this role within an
+<code>actionSets</code> extension, each servicing a particular workbench
+menu item or button.
+
+<p> When a custom implementation of a callback object is required, the XML
+schema of the corresponding extension-point typically includes an attribute
+for specifying the fully-qualified name of the custom callback implementation
+class. For the <code>help</code> UI plug-in, the name of the XML attribute
+designating an <code>action</code> class is "<code>class</code>",
+as exemplified in Listing 2.4
+
+(<img src="images/tag_4.gif" height=13 width=24 align=CENTER>).
+
+<p> But while the extender plug-in defines the required specific callback
+objects, and declares their custom implementation classes, the callback
+objects only come into existence as a result of specific action by the host
+plug-in (and usually only when they are required for the first time to
+perform some action on behalf of the extension).
+
+For example, in Listing 2.4
+
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER>,
+
+the <code>action</code> callback
+class for the workbench <i>Search-&gt;Help</i> menu is specified
+by the extender plug-in <code>org.eclipse.help.ui</code> to be <code>OpenHelpSearchPageAction</code>
+(package <code>org.eclipse.help.ui.internal</code>).
+But the associated callback instance is created by the host plug-in
+<code>org.eclipse.ui</code>. In this case, the callback instance is created the
+first time the <i>Search-&gt;Help</i> menu item is invoked.
+
+<p> As extension designers for an extender plug-in, we need to know about
+the callback roles of an extension, and supply concrete callback objects
+for these roles. The roles are defined as particular elements in the XML
+schema associated with the extension-point (see section 2.3.3), and are
+described in the documentation of the XML schema, which, among other
+things, must include the interfaces expected of callback objects filling
+each role.
+
+<p> For example, the <code>actionSets</code>
+<a href="http://www.eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/reference/extension-points/org_eclipse_ui_actionSets.html">
+reference page</a> introduced earlier
+specifies the callback interface for menu item actions to be <a
+href="http://www.eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/reference/api/org/eclipse/ui/IWorkbenchWindowActionDelegate.html">
+org.eclipse.ui.IWorkbenchWindowActionDelegate</a>. So the menu action handlers
+of the help system implement this interface. In this interface,
+the method whose implementation actually performs the menu action
+is declared as:
+
+<code>
+<pre>
+ public void run(org.eclipse.jface.action.IAction action);
+</pre>
+</code>
+
+<p> Therefore, when a new service is to be made accessible through the main
+workbench menu, the service's plug-in provides an implementation of
+<code>IWorkbenchWindowActionDelegate</code> in which the <code>run</code>
+method invokes the service. And the fully-qualified name of the
+implementation class is added to the service's plug-in manifest file as the
+callback class of the service's menu.
+
+<h5>
+2.3.1.4. Non-Specific Service Objects
+</h5>
+
+<p> Note that not all XML elements used in defining an extension correspond
+to custom callback roles. Some elements may be purely descriptive,
+supplying, for example, certain parameters to the host plug-in to shape
+corresponding UI elements, or to use in creating non-custom internal host
+objects representing parts of the extension. In our example, an
+<code>actionSet</code> element in and of itself (i.e., independently of its
+child elements) does not define a custom callback object. But such an
+element does cause an internal object to come into existence within the
+<code>org.eclipse.ui</code> plug-in to represent the action set.
+
+<p> Similarly, the <code>actionSets</code> extension-point allows the
+declaration of new top-level workbench menus through an
+<code>actionSet</code> <code>menu</code> element. But the action associated
+with a top-level menu is generic: "expose the list of lower-level menu
+items". Therefore, there is no need for an extender-specific callback
+object to be associated with a top-level workbench menu. And the workbench
+top-level menus are represented by internal workbench UI objects.
+
+<p> As users of extension-points, we need not be concerned with these
+non-specific internal objects supplied by the host plug-in. But as designers
+of host plug-ins, we see that we have the flexibility to design complex
+extension structures, parts of which may be exposed as callbacks to be provided
+by extensions, and other parts of which would be generic, built-in to
+the host plug-in code, and possibly parameterizable through corresponding XML
+attributes of extensions.
+
+<h4>
+2.3.2. Relationships between Plug-ins and Extension Objects
+</h4>
+
+<p> The act of extension is quite a general concept in Eclipse, and to
+understand its full generality, it is useful to summarize the types of
+relationships that may exist between plug-in objects, extension-points, and
+callback objects.
+
+<ol>
+
+<p>
+<li>
+Multiple extension-points may exist in a host plug-in.
+
+<p>
+<li>
+A plug-in may act both as a host plug-in, exposing
+some extension-points, and as an extender plug-in, extending some
+plug-ins.
+
+<p>
+<li>
+Multiple plug-ins may extend a given extension-point.
+
+<p>
+<li>
+A given plug-in may extend a given extension-point multiple
+times.
+
+<p>
+<li>
+An extender plug-in may include different extensions
+of different host plug-ins.
+
+<p>
+<li>
+A single act of extension of an extension-point by a
+particular extension of a particular plug-in may create
+multiple callback objects.
+
+<p>
+<li>
+A plug-in can define extensions of its own extension-points.
+
+</ol>
+
+<p> Note. The idea of a plug-in extending itself may seem odd at first.
+A prominent example of a self-extending plug-in is the workbench UI
+itself. This plug-in adds various facilities, e.g., editors,
+to its own UI by extending its own extension-points.
+
+<h4>
+2.3.3. Extension-Point Schemas
+</h4>
+
+<p> A particular extension is defined by an XML configuration element in an
+extender plug-in. The element provides the information required to
+instantiate and initialize the required callback objects for that
+extension, as well as the information required to customize the interface
+and behavior of the host plug-in. When a host plug-in designer creates an
+extension-point, in addition to declaring the extension-point in its
+manifest file, the designer is also responsible for defining the
+configuration syntax for extensions to that extension-point. This syntax
+is defined as an XML schema and stored in a file with a <code>.exsd</code>
+extension, e.g., <code>actionSets.exsd</code>. The schema definition then
+becomes part of the documentation of the host plug-in. (Eclipse includes
+an XML schema editor and a corresponding formatter for this purpose.)
+
+<p> The extension-point schema lets extender plug-in designers know how to
+parameterize their extensions. (Eclipse also provides an extension
+configuration editor that is driven by the XML schema of an
+extension-point being extended.)
+
+<p> To get an idea of the structure and contents of extension-point
+schemas, you can browse the extension-point schemas for the Eclipse
+platform plug-ins. These schemas are available in each Eclipse installation
+below the folder <code>plugins/org.eclipse.platform.source_&lt;ver&gt;/src</code>
+(where <code>&lt;ver&gt;</code> is the version of Eclipse). Under this folder,
+the extension-point schemas for a given platform plug-in may be found in the
+folder <code>&lt;plugin&gt;_&lt;plugin_ver&gt;/schema</code>, where
+<code>&lt;plugin&gt;</code> is the id of the plug-in, and
+<code>&lt;plugin_ver&gt;</code> is the version of the plug-in. For example,
+for Eclipse 2.1, the <code>actionSets</code> extension-point schema,
+<code>actionSets.exsd</code>, may be found in the folder
+<code>org.eclipse.ui_2.1.0/schema</code> below the
+<code>platform.source</code> folder.
+
+<p>
+Here is a considerably abbreviated version of <code>actionSets.exsd</code>:
+
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+&lt;schema targetNamespace="org.eclipse.ui"&gt;
+ &lt;element name="extension"&gt;
+ &lt;complexType&gt;
+ &lt;sequence&gt;
+ <img src="images/tag_1.gif" height=13 width=24 align=CENTER> &lt;element ref="actionSet" minOccurs="1" maxOccurs="unbounded"/&gt;
+ &lt;/sequence&gt;
+ &lt;attribute name="point" type="string" use="required"&gt; &lt;/attribute&gt;
+ &lt;attribute name="id" type="string"&gt; &lt;/attribute&gt;
+ &lt;attribute name="name" type="string"&gt; &lt;/attribute&gt;
+ &lt;/complexType&gt;
+ &lt;/element&gt;
+ &lt;element name="actionSet"&gt;
+ &lt;complexType&gt;
+ &lt;sequence&gt;
+ &lt;element ref="menu" minOccurs="0" maxOccurs="unbounded"/&gt;
+ &lt;element ref="action" minOccurs="0" maxOccurs="unbounded"/&gt;
+ &lt;/sequence&gt;
+ &lt;attribute name="id" type="string" use="required"&gt; &lt;/attribute&gt;
+ &lt;attribute name="label" type="string" use="required"&gt; &lt;/attribute&gt;
+ &lt;attribute name="visible" type="boolean"&gt; &lt;/attribute&gt;
+ &lt;attribute name="description" type="string"&gt; &lt;/attribute&gt;
+ &lt;/complexType&gt;
+ &lt;/element&gt;
+ &lt;element name="action"&gt;
+ &lt;complexType&gt;
+ &lt;choice&gt;
+ &lt;element ref="selection" minOccurs="0" maxOccurs="unbounded"/&gt;
+ &lt;element ref="enablement" minOccurs="0" maxOccurs="1"/&gt;
+ &lt;/choice&gt;
+ &lt;attribute name="id" type="string" use="required"&gt; &lt;/attribute&gt;
+ &lt;attribute name="label" type="string" use="required"&gt; &lt;/attribute&gt;
+ &lt;attribute name="toolbarPath" type="string"&gt;
+ &lt;attribute name="icon" type="string"&gt; &lt;/attribute&gt;
+ &lt;attribute name="tooltip" type="string"&gt; &lt;/attribute&gt;
+ &lt;attribute name="class" type="string"&gt; &lt;/attribute&gt;
+ &lt;/complexType&gt;
+ &lt;/element&gt;
+&lt;/schema&gt;
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 2.5. Extension-Point Schema Definition (<code>.exsd</code> File).
+</td></tr> </table>
+
+<p>
+The schema defines an <code>actionSets</code> extension as an element that
+includes some attributes and a sequence of <code>actionSet</code>'s,
+and an <code>actionSet</code> as an element that includes some
+attributes and a sequence of <code>menu</code>s and <code>action</code>s.
+
+<p> In the full version of this file, each attribute is annotated with a
+human-readable <i>documentation element</i>. The documentation elements of
+extension-point schemas are used to generate HTML reference pages for
+extension-points (e.g., <a
+href="http://www.eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/reference/extension-points/org_eclipse_ui_actionSets.html">
+the <code>actionSets</code> reference page</a> mentioned earlier in this
+article), similarly to the way in which Java API reference pages
+are generated via <code>javadoc</code>. Such a reference page is made
+available as part of the documentation of the host plug-in, and is
+integrated with the workbench's help system.
+
+<p>
+The reference page supports the two tasks that must be performed
+to plug new functionality into an extension-point, namely:
+
+<ul>
+
+<p>
+<li>
+Configuration of an extension in the extender plug-in's manifest file.
+
+<p>
+The reference page specifies the XML configuration syntax
+required for the extension.
+
+<p>
+<li>
+Provision of custom implementations for the extension-point's callback objects.
+
+<p> The reference page includes an API section for documenting the callback
+interfaces expected by the host plug-in for each callback role.
+
+</ul>
+
+<h5>
+2.3.3.1. Extension Members
+</h5>
+
+<p> What goes into an extension-point schema definition is up to the
+designer of the host plug-in. And the extension XML in the
+<a href="http://www.eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/reference/misc/rplugman.html">
+Eclipse Platform Plug-in Manifest Specification</a> is defined as an XML
+<code>ANY</code>, meaning that it is arbitrary. That designation is too general,
+however. In fact, an XML extension specification is always a (possibly
+degenerate) sequence of elements. I will refer to an item within this
+sequence of elements as an <i>extension member</i>. An
+<code>actionSets</code>
+extension, for example, is a sequence of <code>actionSet</code> members.
+Often the members of an extension have the same element type: that is,
+the sequence represents a homogeneous list of members.
+
+<p> In XML, the number of elements of each type within a sequence may be
+bounded by using the <code>minOccurs</code> and the <code>maxOccurs</code>
+element definition attributes. This usage is illustrated in the
+<code>actionSets</code> schema (Listing 2.5, <img src="images/tag_1.gif"
+height=13 width=24 align=CENTER>), where an <code>actionSets</code>
+extension is specified to contain at least one, but an otherwise
+unrestricted number of <code>actionSet</code> elements.
+
+<p> When an extension-point defines a homogeneous sequence of members and
+allows its extensions to have more than one member, the extension-point is
+assigned a plural name. Such extension-points and their extensions
+may be referred to as <i>plural-form</i>. The plural form is typically
+provided as a shorthand for representing multiple single-member extensions.
+
+<p> The notion of an extension <i>member</i>, that is, a top-level XML
+element of an extension's (top-level) sequence, may be contrasted with the
+Eclipse notion of a <i>configuration element</i>, an arbitrary element
+(either a top-level element or a lower-level descendent element) in the XML
+specification of an extension. Both terms will be used here for the XML element
+itself and for its parsed programmatic representation.
+
+<a name="3."> </a>
+<h2>
+3. Extension Processing
+</h2>
+
+<p> In section 2, the extension model of Eclipse was presented at a high
+level, and the declarative specifications of extensions and their callback
+objects was introduced. In this section, we will see how such declarations are
+processed programmatically to support the obligations of a host plug-in
+under an extension-point contract. In other words, we will see the kind of
+code host plug-in designers must write for each extension-point they
+define.
+
+<p> Consider again the plug-in <code>org.eclipse.ui</code> and its
+<code>actionsSets</code> extension-point. When this plug-in is activated,
+the extension declarations in all plug-ins that extend it must be
+processed, so that the UI knows how to configure its menus and buttons, and
+what callback objects to call when corresponding menu and button events
+occur. This section presents the API calls provided by the Eclipse platform
+to aid in this type of extension processing, and exemplifies the idioms
+used by plug-in developers to process extensions by using these API calls.
+
+<h3>
+3.1. Obtaining References to the Extensions of an Extension-Point
+</h3>
+
+<p>
+How are the extension declarations processed for a given extension-point?
+Well, in general, the configuration of an extension is
+quite arbitrary. And the part of the system that has the knowledge
+of this configuration is the host plug-in, whose design produced
+the extension-point schema definition.
+For example, the knowledge of how to process the <code>actionsSets</code>
+extension of the UI help plug-in, <code>org.eclipse.help.ui</code>,
+resides within the plug-in that defines the <code>actionsSets</code>
+extension-point, namely, the plug-in <code>org.eclipse.ui</code>.
+
+<p> In order for a host plug-in to process the extensions of one of its
+extension-points, it needs to be able to obtain a list of those extensions
+from the Eclipse runtime, and, for each extension, to get a parsed version
+of that extension's members.
+
+<p> Recall that the plug-in registry API provides programmatic access to
+the parsed representation of all available plug-in specifications.
+This API provides methods for
+traversing the information about plug-ins, their components, and their
+relationships. A configuration element in the registry API (interface
+<var>IConfigurationElement</var>) represents the parsed version of an
+extension element in an extender plug-in's manifest file.
+The following sample code shows how to use the plug-in registry
+API to iterate over all members of all extensions of an extension-point.
+
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+package com.bolour.sample.eclipse.demo;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+
+public interface IProcessMember {
+ public Object process(IExtension extension,
+ IConfigurationElement member);
+}
+
+package com.bolour.sample.eclipse.demo;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPluginRegistry;
+import org.eclipse.core.runtime.Platform;
+
+public class ProcessExtensions {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> public static void process(String xpid, IProcessMember processor) {
+ IPluginRegistry registry = Platform.getPluginRegistry();
+ IExtensionPoint extensionPoint =
+ registry.getExtensionPoint(xpid);
+ IExtension[] extensions = extensionPoint.getExtensions();
+ // For each extension ...
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> for (int i = 0; i &lt; extensions.length; i++) {
+ IExtension extension = extensions[i];
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> IConfigurationElement[] elements =
+ extension.getConfigurationElements();
+ // For each member of the extension ...
+ <img src="images/tag_4.gif" height=13 width=24 align=CENTER> for (int j = 0; j &lt; elements.length; j++) {
+ IConfigurationElement element = elements[j];
+ <img src="images/tag_5.gif" height=13 width=24 align=CENTER> processor.process(extension, element);
+ }
+ }
+ }
+}
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 3.1. Iterating over the Extensions and the Members of an Extension-Point.
+</td></tr> </table>
+
+<p> The class <code>ProcessExtensions</code> provides an extension processing
+method <code>process</code> (<img src="images/tag_1.gif" height=13 width=24
+align=CENTER>), which uses the nested loop idiom for extension processing:
+loop over all extensions of the given extension-point
+
+(<img src="images/tag_2.gif" height=13 width=24 align=CENTER>),
+
+and for each extension, loop over all members of that extension
+
+(<img src="images/tag_4.gif" height=13 width=24 align=CENTER>).
+
+The <code>process</code> method is made generic by providing it with a
+member processing visitor: an instance of interface
+<code>IProcessMember</code> that is called back on for each member being
+processed
+
+(<img src="images/tag_5.gif" height=13 width=24 align=CENTER>).
+
+<p> Suppose this extension processing method is called with the
+id of the <code>actionSets</code> extension-point, namely,
+<code>org.eclipse.ui.actionSets</code>, as the first argument. One of the
+extensions of the <code>actionSets</code> extension-point is the
+<code>help</code> extension of <a href="#listing2.5">Listing 2.4</a>, and
+that extension happens to have a single <code>actionSet</code> member. So
+when the <code>help</code> extension is reached in the outer loop, its
+<code>actionSet</code> member is supplied to the inner loop, and can be
+processed by the member processing visitor.
+
+<p> A similar processing loop occurs in the Eclipse workbench UI plug-in
+(the owner of the <code>actionSets</code> extension-point) when that
+plug-in is activated. And the UI plug-in can then pick apart the attributes
+and sub-elements of the <code>actionSet</code> member by using the methods of
+<var>IConfigurationElement</var> and related interfaces, and use them to
+configure the specified menu and button elements into the workbench user interface,
+and to instantiate the required callback objects, when required.
+
+<p> Within the member processing function called in the inner loop
+
+<img src="images/tag_5.gif" height=13 width=24 align=CENTER>,
+of course, the host plug-in is free to do
+whatever is necessary to process each member, as directed by that
+member's XML configuration element.
+
+<a name="shorthand"/>
+<h4>
+3.1.1. Extension-Point Member Traversal Shorthand
+</h4>
+
+<p>
+Listing 3.1 exemplifies the use of the method <code>IConfigurationElement[]
+getConfigurationElements()</code> to obtain the configurations of all members of
+an extension
+
+(Listing 3.1 <img src="images/tag_3.gif" height=13 width=24 align=CENTER>).
+
+A method with an identical signature also exists for an extension-point as a
+whole, that is, for the interface <code>IExtensionPoint</code>, and returns
+the configurations of all members of all extensions of an extension-point.
+By using this <i>shorthand</i> method, the extension/member nested loop
+(Listing 3.1, <img src="images/tag_2.gif" height=13 width=24 align=CENTER>,
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER>)
+is reduced to a single loop spanning all members of all extensions of an
+extension-point. Often this simpler idiom is sufficient for processing
+an extension-point.
+
+<h4>
+3.1.2. Extension Processing in Action
+</h4>
+
+<p> By supplying a concrete extension processing visitor to the
+<code>process</code> method of our generic extension processing class
+
+(Listing 3.1 <img src="images/tag_1.gif" height=13 width=24 align=CENTER>),
+
+we can get a taste of extension processing in action. For example, to output
+identifying information about all extension members for a given
+extension-point, the following implementation of the visitor interface
+<code>IProcessMember</code> may be used:
+
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+package com.bolour.sample.eclipse.demo;
+// imports ...
+public class PrintMemberIdentity implements IProcessMember {
+ private String memberLabelAttribute = null;
+ public PrintMemberIdentity(String memberLabelAttribute) {
+ this.memberLabelAttribute = memberLabelAttribute;
+ }
+ public Object process(IExtension extension,
+ IConfigurationElement member) {
+ String label =
+ extension.getDeclaringPluginDescriptor().getLabel() + "/"
+ + member.getAttribute(memberLabelAttribute);
+ System.out.println(label);
+ return label;
+ }
+ public static void test(String extensionPoint,
+ String memberLabelAttribute) {
+ // Validate input ...
+ System.out.println("Extension members of " + extensionPoint + ":");
+ IProcessMember processor =
+ new PrintMemberIdentity(memberLabelAttribute);
+ ProcessExtensions.process(extensionPoint, processor);
+ }
+}
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 3.2. Printing Identification Data for Extension-Point Members.
+</td></tr> </table>
+
+<p>
+For <code>actionSet</code> members, there is a labeling attribute whose name
+is <code>label</code>. So to get a printout of the identifying information
+for all <code>actionSet</code>s present in the current instance of the
+workbench, the following call may be used:
+
+<code>
+<pre>
+ PrintMemberIdentity.test("org.eclipse.ui.actionSets", "label")
+</pre>
+</code>
+
+<p>
+And the call produces output lines such as:
+
+<pre>
+Java Development Tools UI/Java Element Creation
+Java Development Tools UI/Java Navigation
+Help System UI/Help
+CVS Team Provider UI/CVS
+Extension Processing Demo/Demo Menu Actions
+Eclipse UI/Resource Navigation
+...
+</pre>
+
+<p> This extension processing demo is included with the
+companion plug-ins of this article. To try it out,
+see the plug-in <a href="#instructions">installation instructions </a> at
+the end of this article.
+
+<a name="3.2."> </a>
+<h3>
+3.2. Standardized Extension Processing
+</h3>
+
+<p> A principal function of extension processing is the instantiation of an
+extension's callback objects. As we shall see in section 3.3, for
+performance reasons, this function is normally performed in a lazy manner,
+as callback objects are required to do actual work. In this section,
+however, I will ignore this important performance optimization, and
+concentrate instead on the main functional aspects of callback
+instantiation.
+
+<p> Eclipse defines a standard for instantiating and initializing callback
+objects. As we have seen, a callback object is typically represented in a
+specific child-level or descendent XML element of an extension, and its
+fully-qualified class name is provided as the value of some attribute of
+this element. Also, the initial state of a callback object is usually
+completely parameterized by the corresponding element and its XML
+descendants. When these conditions hold, the callback object may be
+instantiated and initialized by using the standard callback object
+instantiation and initialization facilities of Eclipse.
+
+<p> Suppose that our extension processing code has traversed the parsed
+representation of an extension member to an element corresponding to a
+particular callback object (for example, an object standing in the
+<code>action</code> role within an <code>actionSets</code> extension).
+Suppose that this element is represented in a variable
+<code>IConfigurationElement element</code>, and that the name of this
+element's attribute designating the fully-qualified class name of the
+callback object is known to be <code>class</code>. Then, the method
+<code>createExecutableExtension(String classPropertyName)</code> of
+<code>IConfigurationElement</code> may be used to instantiate the callback
+object, as follows:
+
+<code>
+<pre>
+ICallback callback = (ICallback) element.createExecutableExtension("class")
+</pre>
+</code>
+
+<p>
+where <code>ICallback</code> is the expected interface for the
+corresponding callback role.
+
+<p>
+The method <code>createExecutableExtension</code> does two things:
+
+<ol>
+
+<p>
+<li>
+Instantiate a member of the required class by using its
+0-argument public constructor (one must exist).
+
+<p> The fully-qualified name of the required class is looked up in the
+configuration as the value of an attribute whose name is provided in the
+method's <code>classPropertyName</code> argument.
+
+<p>
+<li>
+Initialize this instance if it is initializable in a standard manner.
+
+<p>
+To become initializable in a standard manner, an extension class
+implements Eclipse's standard extension initialization interface
+<code>IExecutableExtension</code>:
+
+<code>
+<pre>
+package org.eclipse.core.runtime;
+public interface IExecutableExtension {
+ public void setInitializationData(IConfigurationElement config,
+ String classPropertyName, Object data) throws CoreException;
+}
+</pre>
+</code>
+
+<p> So if the instantiated callback object is an instance of
+<code>IExecutableExtension</code>, the method
+<code>createExecutableExtension</code> automatically calls
+<code>setInitializationData</code> on this extension object, giving it the
+configuration element of the callback object as a parameter (as well as its
+class attribute name, and a data parameter whose details are beyond the
+scope of this article, but can safely be ignored for now (see the Eclipse
+documentation for more details)).
+
+<p> What this initialization method actually does, of course, is up to the
+callback object's designer. The configuration of the callback object
+provided to this method as a parameter would drive the initialization
+process and would be reflected in the callback object's state by the
+initialization method.
+
+</ol>
+
+<p>
+A complete example of the use of this machinery to instantiate
+and initialize callback objects appears in section 4.
+
+<p> Note. As mentioned earlier and as we shall see in the next section,
+this entire machinery is generally used in a lazy fashion only, i.e.,
+when the callback object is actually required to do specific work. In the
+same spirit, a callback object's initialization method should, to the
+extent possible, defer time-consuming work to subsequent method calls on
+the object that would require or benefit from such work. For example, when
+a callback object manages access to a set of resources, it is often
+possible and preferable to open a managed resource only when it is actually
+required in a subsequent method call to the callback object.
+
+<h3>
+3.3. Lazy Extension Processing
+</h3>
+
+<p> When a host plug-in is activated, an eager processing of its extensions
+would cause the activation of all of its extender plug-ins, and,
+recursively, their extender plug-ins, down the plug-in hierarchy (or, more
+accurately, through the plug-in extension network). Activating all plug-ins
+reachable from a given plug-in involves loading their classes. And
+processing all extension-points of these plug-ins means loading the custom
+callback classes of all extensions of these extension-points. As a result,
+an eager extension processing regime can considerably slow down plug-in
+activation, and therefore system startup.
+
+<p>
+Plug-in developers are therefore encouraged to attempt to delay
+the creation of extender-specific callback objects, until such
+objects are actually required to perform some action.
+
+<h4>
+3.3.1. Using Virtual Proxies in Lazy Extension Processing
+</h4>
+
+<p> One way to implement a lazy activation regime is to use a <i>virtual
+proxy</i> for each callback object during the activation of a
+host plug-in. (See the <i>virtual</i> usage of the <i>proxy
+pattern</i> in [1].) Such a proxy stands in the role
+of a real callback object, and causes the real callback object to be
+instantiated only when some action is required of it. Often, it is possible
+to provide, within the proxy class, certain generic functions that are
+required of a callback object. These functions can then be furnished to
+the host plug-in without reference to particular custom extension
+classes, and without the need to activate particular extender plug-ins.
+
+<p>
+When using virtual proxies to initialize the extensions of a
+host plug-in, only a limited number of extension classes,
+one for each extension-point role, would be loaded in activating
+a host plug-in.
+
+<p>
+As an example, the internal package <code>org.eclipse.ui.internal</code>
+contains an abstract virtual proxy class called <code>PluginAction</code> for UI
+actions, and a number of concrete subclasses of this class.
+And initial extension processing for the <code>actionSets</code> extension
+point only instantiates such a proxy class for each UI action.
+
+<p>
+A generic constructor for an <i>action</i> proxy is defined in the abstract
+class <code>PluginAction</code>, and has the following signature:
+
+<code>
+<pre>
+ public PluginAction(IConfigurationElement actionElement,
+ String runAttribute, String definitionId, int style)
+</pre>
+</code>
+
+<p> The parameter <code>actionElement</code> provides a reference to the
+parsed representation of an extension XML element representing an action.
+And the parameter <code>runAttribute</code> identifies the XML attribute
+that represents the name of the custom action class to be instantiated to
+perform the action. The <code>PluginAction</code> proxy class simply keeps
+track of these properties for later use in instantiating and initializing
+the real action object.
+
+<p> The proxy class fields action calls by implementing the workbench's
+<i>action</i> interface, called <code>IAction</code>. The first time a call
+is made on the <code>run</code> method of this interface, the proxy
+instantiates the custom action implementation class whose name is provided
+in <code>runAttribute</code>, The <code>run</code> method call is then
+dispatched to this custom action instance. The custom action instance is
+known as the <i>action delegate</i>.
+
+<h5> 3.3.1.1. Callback Proxies versus Callback Adapters</h5>
+
+<p> In a canonical proxy pattern, both the proxy class and the delegate
+implementation class implement the <i>same</i> functional interface. But
+it is not necessary to adhere to a strict interpretation of the proxy
+pattern in implementing the virtual proxies of callback objects. In fact,
+an implementation following the <i>adapter</i> pattern provides a more
+flexible mechanism for the purpose of lazy callback instantiation.
+
+<p> For example, the Eclipse UI action handler, <code>PluginAction</code>,
+is more precisely described as a <i>virtual adapter</i>. It implements a
+high-level interface <code>IAction</code> and adapts it to a lower-level
+interface, <code>IActionDelegate</code>, which is expected of implementers
+of custom action callbacks. And the two interfaces <code>IAction</code> and
+<code>IActionDelegate</code> are unrelated. The handler class
+<code>PluginAction</code> provides some basic services without reference to
+a particular custom action handler, and <i>adapts</i> the <code>run</code>
+method of of the workbench's <code>IAction</code> interface to the
+<code>run</code> method of the action callback interface
+<code>IActionDelegate</code> to actually perform a requested action.
+
+<p> (Note that the interface <code>IWorkbenchWindowActionDelegate</code>
+expected of custom workbench menu and buttons handlers, mentioned earlier
+in <a href="#2.3.1.3.1.">section 2.3.1.3.1</a>, is derived from the action
+callback interface <code>IActionDelegate</code>.)
+
+<p> Even though Eclipse developers do not necessarily use a strict proxy
+regime to affect lazy callback instantiation, the term <i>proxy</i> is
+commonly used in Eclipse parlance as a generic designation for internal objects
+used to <i>front</i> custom callback objects for the purpose of delaying
+their instantiation.
+
+<a name="4."> </a>
+<h2>
+4. Example: An Extensible Arithmetic Function Service
+</h2>
+
+<p> So far in this article, we have used only pre-existing extension-points.
+But with the machinery of extension processing in place, we are now ready
+to create an extension-point of our own. Our example extension-point
+is similar in its outline structure to the <code>actionSets</code> extension-point
+which we have been using so far.
+
+<p>
+<ol>
+
+<li>
+
+It provides a slot for augmenting the functions of a host plug-in
+by a custom set of services.
+
+<li>
+
+It has a plural form, so that each of its extensions
+is free to add more than one service to the host plug-in.
+
+<li>
+
+It requires each extension to provide concrete callback
+objects that embody the services provided by that extension.
+
+<li>
+
+It obligates the host to add elements to its user interface for each
+extension (actually for each member of each extension), so that the user
+may interact with the services provided by the extension.
+
+</ol>
+
+<p>
+In addition, our example provides for the specific initialization
+of callback objects by using the standard callback initialization facilities
+of Eclipse.
+
+<p> The goal is to illustrate these salient features of extensions with as
+simple an extension-point as possible. Our major concern, of course, is to
+illustrate architectural issues, patterns of usage, and extension
+processing. User interface design issues are specifically excluded from
+this article. In fact, our example uses a very simple user interface, just
+sufficient to illustrate the types of interactions required between the
+user interface functions and extension processing functions.
+
+<h3>
+4.1. The Example in Outline
+</h3>
+
+<p>
+The host plugin, which supplies the user interface for this example,
+will be referred to as the <i>UI plug-in</i>.
+
+<p> A single extension-point is defined in the UI plug-in, and supports the
+extension of the plug-in by a very simple type of service: a service that
+provides access to an integer arithmetic function of a single argument. The
+signature of the function is defined in the following callback interface:
+
+<code>
+<pre>
+package com.bolour.sample.eclipse.service.ui;
+public interface IFunction {
+ public long compute(long x) throws ArithmeticException;
+}
+</pre>
+</code>
+
+<p> In our example, each member of each extension will provide an
+implementation of such a function through a callback object
+that implements the <code>IFunction</code> interface.
+
+<p> In order to illustrate the use of standard extension processing to
+initialize callback objects, we would like our functions to be configurable
+via configuration parameters (constants of the computation) supplied as XML
+attributes in extension declarations. Of course, we will have different
+classes of computations implemented by different callback classes, e.g.,
+addition of a parameter, multiplication by a parameter, etc. And, in
+general, each type of computation would be parameterized differently.
+
+<p> But to keep our example simple, we stipulate that our computations may
+be parameterized by at most one integer parameter. For example, if the
+function doubles the value of its argument, then it is considered as a
+multiplication by a constant factor of 2. And in this case the value 2 is
+supplied as an XML configuration parameter in the extension declaration of
+the corresponding callback object.
+
+<p> The UI plug-in provides an input field to enter the argument of a
+service function, a result field to display the function's value, and a
+<i>constant</i> field to display the constant parameter (if any) used in
+the computation. Each function also requires a specific button for
+invoking it, and a specific label for giving information about it.
+Therefore, for each member of each extension, the UI plug-in adds a
+corresponding button and label to its user interface. And when the button is
+selected, the UI plug-in calls back to the associated service function.
+
+<p>
+Figure 2 shows the UI plug-in's user interface for a typical configuration
+of extender plug-ins.
+
+<P>
+<spacer type=vertical size=10>
+
+<CENTER>
+<IMG SRC="images/functions_grid_view.jpg" ALT="Figure-2" BORDER="0">
+</CENTER>
+
+<BR>
+<table align=center width=600>
+<tr><td>
+Figure 2. Service UI plug-in's function invocation view. Extensions
+of this host plug-in declare arithmetic functions that are made
+accessible through this plug-in's function invocation view.
+</td></tr>
+</table>
+
+<p> The UI plug-in class is <code>com.bolour.sample.eclipse.service.ui</code>.
+The extension-point is called <code>functions</code>.
+
+<h3>
+4.2. The Extension-Point
+</h3>
+
+<p>
+The <code>functions</code> extension-point is declared in the UI
+plug-in manifest file as follows:
+
+<code>
+<pre>
+ &lt;extension-point id="functions" name="Functions"
+ schema="schema/functions.exsd"/&gt;
+</pre>
+</code>
+
+<p> Here is the <a
+href="doc\com_bolour_sample_eclipse_service_ui_functions.html"> reference
+page</a> for this extension-point. (The source schema file for this
+extension, <code>functions.exsd</code> may be found in the <a
+href="samples.zip">companion plug-ins zip file</a>.) As indicated in the
+reference page, a <code>functions</code> extension is a sequence of
+<code>function</code> members each of which has the following attributes:
+
+<p>
+<ul>
+
+<li>
+<strong>class</strong>: The member function's custom callback class.
+
+<li>
+<strong>name</strong>: The member function's name. Used
+in labeling the function on the user interface.
+
+<li>
+<strong>constant</strong>: An optional attribute used to parameterize
+the member's function by a constant.
+
+</ul>
+
+<p> Complete examples of extensions using these attributes appear in the
+next section. For now, here is an example extension member declaration for
+a multiplication function,
+<code>compute(x)&nbsp;=&nbsp;constant&nbsp;*&nbsp;x</code>, with a constant
+factor of 2:
+
+<code>
+<pre>
+&lt;function
+ name="DOUBLE"
+ constant="2"
+ class="com.bolour.sample.eclipse.service.multiplication.Multiplication"/&gt;
+</pre>
+</code>
+
+<p> In this case, the <code>Multiplication</code> class implements the
+standard Eclipse callback initialization interface
+<code>IExecutableExtension</code> to allow its instances to be initialized
+with the supplied constant factor. The details are provided in <a
+href="#4.3.2.">section 4.3.2</a>. Of course, the designer of a computation
+may decide not to parameterize it with a constant. The <i>echo</i>
+function, <code>compute(x)&nbsp;=&nbsp;x</code> (see <a
+href="#4.3.1.">section 4.3.1</a>), provides an example of such a
+non-parameterized computation. In this case, no specific initialization is
+required for the corresponding callback object, and the associated callback
+class would not implement <code>IExecutableExtension</code>.
+
+<p>
+Figure 3 shows the relationship between the functions UI plug-in
+and its extensions.
+
+<P>
+<spacer type=vertical size=10>
+
+<CENTER>
+<IMG SRC="images/services_extensions.jpg" ALT="Figure-3" BORDER="0">
+</CENTER>
+
+<CENTER>
+
+</CENTER>
+<BR>
+<table align=center width=600>
+<tr><td>
+Figure 3. The <code>functions</code> extension-point and its extensions.
+Sets of arithmetic functions are added to the UI
+plug-in by extending that plug-in's <code>functions</code> extension-point.
+</td></tr>
+</table>
+
+<p> At this point, we have in place all the information we need to create
+sample extensions of the <code>functions</code> extension-point. So before
+getting into the implementation details of the UI plug-in, we will
+present sample extensions of this extension-point. Section 4.3 presents two
+such sample extensions. Then in section 4.4 we will return to the implementation
+of the UI plug-in by providing the details of extension
+processing in that plug-in.
+
+<h3>
+4.3. Extension Examples
+</h3>
+
+<a name="4.3.1."> </a>
+<h4>
+4.3.1. Echo: A Simple Extension
+</h4>
+
+<p>
+The echo service provides a function that echoes its input
+to its output. Its service class is defined as:
+
+<p>
+<table width=550 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+package com.bolour.sample.eclipse.service.echo;
+import com.bolour.sample.eclipse.service.ui.IFunction;
+public class Echo implements IFunction {
+ public long compute(long x) {
+ return x;
+ }
+}
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 4.1. The Echo Callback Function Class.
+</td></tr> </table>
+
+<p>
+The echo plug-in makes itself available to the user by extending
+the <code>functions</code> extension-point.
+Here is the specification of an echo
+extension.
+
+<p>
+<table width=550 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+&lt;extension
+ id="functions.echo"
+ name="EchoFunction"
+ point="com.bolour.sample.eclipse.service.ui.functions"&gt;
+ &lt;function
+ name="ECHO"
+ class="com.bolour.sample.eclipse.service.echo.Echo"/&gt;
+&lt;/extension&gt;
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 4.2. An Echo Extension Specification.
+</td></tr> </table>
+
+<p>
+This specification declares the service callback class, and specifies
+the name of the service operation to be <code>ECHO</code>.
+
+<p>
+Note that in this simple case, no specific state is required
+to initialize an <code>Echo</code> object. So the optional
+<code>constant</code> attribute is not used, and the
+<code>Echo</code> callback class does not implement
+the <code>IExecutableExtension</code> interface.
+
+<a name="4.3.2."> </a>
+<h4>
+4.3.2. Multiplication: An Extension with Custom Initialization
+</h4>
+
+<p> Suppose now that the service function to be provided is the
+multiplication of the input argument by a constant value. Such a service
+is more useful if it can be configured at deployment time with the required
+multiplication factor. The function attribute <code>constant</code> is used
+for this purpose.
+
+<p>
+Here is a sample multiplication extension.
+
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+&lt;extension
+ id="functions.multiplication"
+ name="MultiplicationFunctions"
+ point="com.bolour.sample.eclipse.service.ui.functions"&gt;
+ &lt;function
+ name="DOUBLE"
+ constant="2"
+ class="com.bolour.sample.eclipse.service.multiplication.Multiplication"/&gt;
+ &lt;function
+ name="TRIPLE"
+ constant="3"
+ class="com.bolour.sample.eclipse.service.multiplication.Multiplication"/&gt;
+&lt;/extension&gt;
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 4.3. A Multiplication Extension Specification.
+</td></tr> </table>
+
+<p>
+When this extension is processed, the attribute <code>constant</code> is
+interpreted as a multiplication factor.
+
+<p>
+The multiplication callback class is reproduced below (minimally redacted
+for brevity).
+
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+package com.bolour.sample.eclipse.service.multiplication;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import com.bolour.sample.eclipse.service.ui.IFunction;
+
+public class Multiplication implements IFunction, IExecutableExtension {
+
+ private static final String FACTOR_ATTRIBUTE = "constant";
+ private int factor = 0;
+
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> public long compute(long x) {
+ return factor * x;
+ }
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> public void setInitializationData(IConfigurationElement member,
+ String classPropertyName, Object data) throws CoreException {
+
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> String s = member.getAttribute(FACTOR_ATTRIBUTE);
+ try {
+ <img src="images/tag_4.gif" height=13 width=24 align=CENTER> factor = Integer.parseInt(s);
+ }
+ catch (NumberFormatException ex) {
+ // throw exception ...
+ }
+ }
+}
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 4.3. The Multiplication Function Callback Class.
+</td></tr> </table>
+
+<p>
+Note that the <code>compute</code> method
+(<img src="images/tag_1.gif" height=13 width=24 align=CENTER>)
+of this class provides the implementation of the service interface
+<code>IFunction</code>, and that the <code>setInitializationData</code> method
+(<img src="images/tag_2.gif" height=13 width=24 align=CENTER>)
+of this class provides the implementation of the standard initialization
+interface <code>IExecutableExtension</code>.
+
+<p> We will see in the next section that extension processing for the
+<code>functions</code> extension-point uses the standard callback
+instantiation method <code>createExecutableExtension</code>. So because
+the <code>Multiplication</code> class implements the
+<code>IExecutableExtension</code> interface, the method
+<code>createExecutableExtension</code> automatically calls a callback
+instance's <code>setInitializationData</code> method, providing that
+instance's parsed XML element as a parameter. The initialization method can
+then extract the specified multiplication factor from the element's
+<code>constant</code> XML attribute, and keep track of it for future
+computations (<img src="images/tag_3.gif" height=13 width=24 align=CENTER>,
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER>).
+
+
+<h3>
+4.4. Processing the "functions" Extension-Point
+</h3>
+
+<p> Now that we have examined some sample test cases for the
+<code>functions</code> extension-point, we are ready to dig deeper into the
+implementation of this extension-point and its defining UI plug-in. Our
+extension-processing class is called <code>ProcessServiceMembers</code>.
+This class embodies the standard idioms of extension processing in Eclipse,
+specialized to the <code>functions</code> extension-point. In particular,
+this class implements a standard and lazy extension processing regime
+for the <code>functions</code> extension-point. A separate UI class
+called <code>FunctionsGrid</code> encapsulates all UI processing
+for our UI plug-in.
+
+<p> As usual in lazy extension processing, processing is required
+in two distinct phases of the operation of the application.
+
+<p> In the host plug-in startup phase, there is an initial run through the
+members of all extensions of the <code>functions</code> extension-point for
+the purpose of obtaining the configurations of these members, creating
+generic callback proxies, and building the user interface of the host
+plug-in. In this phase, our extension processing code repeatedly calls a
+UI method called <code>addFunction</code> to augment the host plug-in's
+user interface with function invocation elements for each extension
+function
+
+(see Listing 4.4 <img src="images/tag_5.gif" height=13 width=24 align=CENTER>)
+
+
+<p> Then, in the interactive phase of the application, the specific
+callback objects required to perform the computations of each configured
+function are created in a lazy fashion, as calls are received by proxy
+objects. During this phase, selecting the UI button for a function causes a
+callback to that function through a proxy callback object provided by the
+extension processing class. The call is delegated by the proxy to the real
+callback object. And the first time such a call is made to each proxy, the
+real callback object is instantiated and initialized via standard extension
+processing.
+
+<p>
+Section 4.4.1 outlines the extension processing class.
+Section 4.4.2 outlines the parts of the UI class that
+interact with extension processing. The bulk of the user interface
+code concerns UI details not directly related to extension processing
+and is therefore not presented in this article.
+
+<h4>
+4.4.1. The Extension Processing Class
+</h4>
+
+<p>
+Here is a redacted version of our initial extension processing function:
+
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+package com.bolour.sample.eclipse.service.ui;
+public class ProcessServiceMembers {
+ private static final String EXTENSION_POINT =
+ "com.bolour.sample.eclipse.service.ui.functions";
+ private static final String FUNCTION_NAME_ATTRIBUTE = "name";
+ private static final String CLASS_ATTRIBUTE = "class";
+ private static final String CONSTANT_ATTRIBUTE = "constant";
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> public static void process(FunctionsGrid grid)
+ throws WorkbenchException {
+ IPluginRegistry registry = Platform.getPluginRegistry();
+ IExtensionPoint extensionPoint =
+ registry.getExtensionPoint(EXTENSION_POINT);
+ IConfigurationElement[] members =
+ extensionPoint.getConfigurationElements();
+ // For each service:
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> for (int m = 0; m &lt; members.length; m++) {
+ IConfigurationElement member = members[m];
+ IExtension extension = member.getDeclaringExtension();
+ String pluginLabel =
+ extension.getDeclaringPluginDescriptor().getLabel();
+ String functionName =
+ member.getAttribute(FUNCTION_NAME_ATTRIBUTE);
+ String label = pluginLabel + "/" + functionName;
+ Integer constant = null;
+ String s = member.getAttribute(CONSTANT_ATTRIBUTE);
+ if (s != null) {
+ try {
+ constant = new Integer(s);
+ }
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> catch (NumberFormatException ex) {
+ // Invalid function. Inform the user ... and ignore.
+ continue;
+ }
+ }
+ <img src="images/tag_4.gif" height=13 width=24 align=CENTER> IFunction proxy = new FunctionProxy(member);
+ <img src="images/tag_5.gif" height=13 width=24 align=CENTER> grid.addFunction(proxy, functionName, label, constant);
+ }
+ }
+ // ...
+}
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 4.4. Extension Member Processing for Service Functions.
+</td></tr> </table>
+
+<p>
+The extension processing loop
+(<img src="images/tag_2.gif" height=13 width=24 align=CENTER>)
+follows the <a href="#shorthand">shorthand
+idiom for getting the members of all extensions of an extension-point</a>
+introduced in section 3.1.1.
+This run through the extension members of the <code>functions</code> extension-point
+creates a proxy callback object for each function
+
+(<img src="images/tag_4.gif" height=13 width=24 align=CENTER>),
+
+and adds this proxy and its associated UI widgets to the UI
+by calling the <code>addFunction</code> method of the UI's function
+grid
+
+(<img src="images/tag_5.gif" height=13 width=24 align=CENTER>).
+
+(The body of the <code>addFunction</code> method is presented later in
+<a href="#listing4.6">Listing 4.6</a>
+
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER>.)
+
+<p> Note that certain configuration errors, such as an invalid constant in
+our example, can be detected in a generic manner, that is, without recourse
+to specific callback objects (whose instantiations we are deferring). Such
+errors should be handled during initial extension processing, so that, to the
+extent possible, the host plug-in is not polluted with invalid callback
+objects and associated widgets. Thus, when a non-integral constant is encountered in the
+initial extension processing of the <code>functions</code> extension-point,
+the corresponding misconfigured function is ignored
+
+(<img src="images/tag_3.gif" height=13 width=24 align=CENTER>).
+
+<p>
+During the interactive phase of the application, when a function
+call is received by a callback proxy, it must be delegated to the
+custom implementation of the function. And
+that implementation is instantiated in a lazy fashion the
+first time a call is received by a proxy. The details appear
+in the following code fragment.
+
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+package com.bolour.sample.eclipse.service.ui;
+public class ProcessServiceMembers {
+ // ...
+ private static final String CLASS_ATTRIBUTE = "class";
+ // ...
+ private static class FunctionProxy implements IFunction {
+ private IFunction delegate = null; // The real callback.
+ private IConfigurationElement element; // Function's configuration.
+ private boolean invoked = false; // Called already.
+ public FunctionProxy(IConfigurationElement element) {
+ this.element = element;
+ }
+ public final long compute(long x) throws ArithmeticException {
+ try {
+ getDelegate();
+ }
+ catch (Exception ex) {
+ throw new ArithmeticException("invalid function");
+ }
+ if (delegate == null) {
+ throw new ArithmeticException("invalid function");
+ }
+ return delegate.compute(x);
+ }
+ private final IFunction getDelegate() throws Exception {
+ if (invoked) {
+ return delegate;
+ }
+ invoked = true;
+ try {
+ Object callback =
+ element.createExecutableExtension(CLASS_ATTRIBUTE);
+ <img src="images/tag_1.gif" height=13 width=24 align=CENTER> if (!(callback instanceof IFunction)) {
+ // throw exception ...
+ }
+ delegate = (IFunction)callback;
+ }
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> catch (CoreException ex) {
+ // process and rethrow ...
+ }
+ return delegate;
+ }
+ }
+}
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 4.5. Extension Member Processing for Service Functions.
+</td></tr> </table>
+
+<p>
+This is a straightforward example of the use of the virtual proxy pattern,
+and other than error processing, which is discussed in the next section,
+requires no further comment.
+
+<h5>
+4.4.1.1. Error Processing
+</h5>
+
+<p> In the previous section, we saw that certain configuration errors may
+be detected in a generic manner during initial extension processing, and
+can be handled at that time. Unfortunately, not all configuration errors
+are of this variety, since deferring the instantiation of callback objects in
+a lazy regime also defers the detection of errors related to instantiating
+and initializing callback objects. We will call configuration errors
+that are detected during the interactive phase of the application,
+<i>interaction time</i> configuration errors.
+
+<p> Interaction time configuration errors fall into two categories:
+interface mismatches: callback classes that do not implement their required
+callback interfaces, and creation/initialization errors, e.g.,
+non-existent classes, or invalid specific configuration parameters (for
+example, 0 denominator for a division function). In Listing 4.5, interface
+mismatches are detected at
+
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER>,
+
+and creation/initialization errors are detected at
+
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER>.
+
+Note that an error detected anywhere within the execution of
+<code>createExecutableExtension</code>, including an error in the
+initialization of a callback object, is communicated back to the caller via
+a <code>CoreException</code>.
+
+<p> In our application, an interaction time configuration error causes an
+<code>ArithmeticException</code> to be thrown. The exception is handled in
+the UI trivially by displaying <code>error</code> in the <code>result</code> field of
+function invocations. However, our simple application does not disable the
+UI elements associated with such misconfigured functions once the
+configuration error is detected, and allows the user to repeat the failure. A
+more sophisticated application might dynamically disable or remove user
+interface elements associated with misconfigured members of extensions.
+
+<p>
+The <a href="samples.zip">companion plug-ins zip file</a> includes
+a sample plug-in, <code>errortest</code>, that exemplifies
+configuration errors. By default the <code>functions</code>
+extension that includes these errors is commented out.
+To test the effect of configuration errors in this application,
+uncomment the <code>functions.error</code> extension in the
+<code>errortest</code> plug-in's manifest file, and restart
+Eclipse.
+
+<p> In summary, the late detection of configuration errors in lazy
+extension processing makes it more difficult to handle configuration
+errors gracefully. And in general, a tension exists between application
+startup performance, graceful error processing, and the customizability of
+callback objects standing in a given role.
+
+<h4>
+4.4.2. The User Interface Class
+</h4>
+
+<p> This section outlines the user interface class of the UI plug-in
+insofar as it interacts with the extension processing class.
+
+<p>
+For each function specification included in an extension of
+the <code>functions</code> extension-point, initial extension
+processing adds a function invocation button and a corresponding
+label to the UI plug-in's user interface. Here is an abbreviated
+version of the UI code used for this purpose:
+
+<a name="listing4.6"> </a>
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+package com.bolour.sample.eclipse.service.ui;
+
+public class FunctionsGrid {
+ private Composite buttons; // Function invocation area.
+ // ...
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> public void addFunction(IFunction function, String functionName,
+ String label, Integer constant) {
+ GridRow row = new GridRow(function, functionName, label, constant);
+ }
+ // ...
+ private class GridRow {
+ private IFunction function; // Callback object.
+ private Button button; // UI widget.
+ private Label functionLabel; // UI widget.
+ // Constant of the computation (for display only).
+ private String constantDisplay;
+
+ public GridRow(IFunction function, String functionName,
+ String label, Integer constant) {
+ // ...
+ <img src="images/tag_2.gif" height=13 width=24 align=CENTER> this.function = function;
+ this.constantDisplay =
+ constant == null ? "none" : constant.toString();
+ button = new Button(buttons, SWT.NONE);
+ button.setText(functionName);
+ // ...
+ button.addSelectionListener(new SelectionListener() {
+ public void widgetSelected(SelectionEvent e) {
+ handleButton(e);
+ }
+ // ...
+ });
+ functionLabel = new Label(buttons, SWT.NONE);
+ functionLabel.setText(label);
+ // ...
+ }
+ <img src="images/tag_3.gif" height=13 width=24 align=CENTER> public void handleButton(SelectionEvent e) {
+ String t = input.getText();
+ parameter.setText("");
+ try {
+ int x = Integer.parseInt(t);
+ <img src="images/tag_4.gif" height=13 width=24 align=CENTER> result.setText(String.valueOf(function.compute(x)));
+ parameter.setText(constantDisplay);
+ }
+ catch (Exception ex) {
+ result.setText("error");
+ }
+ }
+ }
+}
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 4.6. Adding a Function to the User Interface.
+</td></tr> </table>
+
+<p> Extension processing makes a call to the <code>addFunction</code>
+
+(<img src="images/tag_1.gif" height=13 width=24 align=CENTER>)
+
+method of the UI to build a <i>grid row</i> that includes the required button
+and label. This method takes four arguments:
+
+<p>
+<ul>
+
+<li>
+<code>IFunction function</code>: provides the callback object to be called when the
+button is selected.
+
+<li>
+<code>String functionName</code>: provides the display name of the
+function's button.
+
+<li>
+<code>String label</code>: provides the text of the associated label.
+
+<li>
+<code>Integer constant</code>: provides the constant parameter (if any) used in the
+computation. The constant is transmitted to the UI for display purposes only,
+and is displayed along with the result of a computation when the corresponding
+button is selected.
+
+</ul>
+
+<p> Each invocation of the <code>addFunction</code> method is delegated to
+a <code>GridRow</code> constructor with identical parameters. A
+<code>GridRow</code> encapsulates the representation of a function in the
+user interface. For each function, the <code>GridRow</code> constructor
+saves the reference to the callback object for future calls
+
+(<img src="images/tag_2.gif" height=13 width=24 align=CENTER>).
+
+It also associates a button event handler <code>handleButton</code>
+
+(<img src="images/tag_3.gif" height=13 width=24 align=CENTER>)
+
+with the button. When the button is later selected by the user,
+the event handler obtains the user input from the UI input field, invokes the
+service function associated with the button on that input, and displays the
+resulting value of the function (<img src="images/tag_4.gif" height=13
+width=24 align=CENTER>). It also displays the constant parameter (if any)
+used in the computation.
+
+<p> This completes the description of our arithmetic function invocation
+service The function invocation UI plug-in and sample extender plug-ins
+are included in this article's companion samples. See the <a
+href="#instructions">instructions</a> at the end of this article for
+configuring the companion plug-ins.
+
+<a name="5."> </a>
+<h3>
+5. Listener Extensions and the Observer Pattern
+</h3>
+
+<p>
+The previous section provided a simple example of what might be
+called the <i>service extension pattern</i>. Each member of
+a <i>service extension</i> defines a unique set of user
+interface widgets, and events on these widgets trigger
+callbacks to objects unique to the extension.
+
+<p> Other usage patterns of extensions are possible, of course. And
+in this section we briefly outline one such pattern that is akin to the
+<i>observer</i> design pattern of [1]. Our examination of this usage
+pattern leads naturally to a comparison of the extension model of Eclipse
+with the much simpler observer pattern.
+
+<p> In the language of Java APIs, observers are called
+<code>listeners</code>, and the pattern of extension usage discussed in
+this section may be called the <i>listener extension pattern</i>. In the
+listener extension pattern, multiple extension members may listen for the
+same event in a host plug-in. And the host plug-in notifies all these
+extension members, or rather their associated listener callbacks, when the
+event occurs.
+
+<p> The Eclipse JDT JUnit plug-in <code>org.eclipse.jdt.junit</code> uses such a
+pattern to allow multiple observers within the Eclipse workbench to get
+notification of testing events, such as the start or the completion of a
+JUnit test. This usage is covered in the Beck and Gamma manuscript [2],
+which is where I was first introduced to the listener extension pattern.
+
+<p> In the listener extension pattern, the host plug-in acts as the
+<i>subject</i> of the observation, and extender plug-ins act as the
+<i>observers</i> or <i>listeners</i>. The host plug-in therefore
+provides an extension-point that may be called <code>listeners</code>, and
+a corresponding interface that may be called <code>IListener</code>. Each
+extender plug-in then extends the <code>listeners</code> extension-point by
+supplying a specific listener that implements the <code>IListener</code>
+interface, or by supplying a sequence of such listeners.
+
+<p> Because the listeners are then specified declaratively through the
+plug-in extension mechanism, these listeners can be automatically
+registered for event notification by extension processing. The first time
+notification is required, the subject plug-in processes its
+<code>listeners</code> members, and for each member, instantiates a
+specific listener callback object and registers that listener for event
+notification.
+
+<p> The companion sample plug-ins include an example of the listener
+extension pattern, whose structure is shown in Figure 4.
+
+<P>
+<spacer type=vertical size=10>
+
+<CENTER>
+<IMG SRC="images/listeners_extensions.jpg" ALT="Figure-4" BORDER="0">
+</CENTER>
+
+<CENTER>
+
+</CENTER>
+<BR>
+<table align=center width=600>
+<tr><td>
+Figure 4. Extension structure of the <i>listener</i> extension pattern.
+Each member of each <i>listener</i> extension provides a notification callback
+for <i>subject</i> events.
+</td></tr>
+</table>
+
+<p>
+In this example, an update of the subject causes notifications to be
+broadcast to all members of all extensions of the <code>listeners</code>
+extension-point.
+
+<p>
+Here is the
+<a href="doc/com_bolour_sample_eclipse_listener_subject_listeners.html">
+reference page of the <code>listeners</code>
+extension-point</a>.
+
+<p> As configured out of the box, the example includes two plug-ins that
+extend the <code>listeners</code> extension-point, and are called
+<code>firstlistener</code> and <code>secondlistener</code>. Each of these
+plug-ins has an extension with two <code>listener</code> members,
+<code>ListenerX</code> and <code>ListenerY</code>. Thus, the first listener
+plug-in's extension specification looks like:
+
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+&lt;extension
+ point = "com.bolour.sample.eclipse.listener.subject.listeners"&gt;
+ &lt;listener
+ class="com.bolour.sample.eclipse.listener.firstlistener.ListenerX"/&gt;
+ &lt;listener
+ class="com.bolour.smaple.eclipse.listener.firstlistener.ListenerY"/&gt;
+&lt;/extension&gt;
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 5.1. A Listener Extension Specification.
+</td></tr> </table>
+
+<p> The host plug-in defines a menu item, which, when selected, causes the
+state of the subject to be updated. In turn, the state change in the
+subject causes listener notifications to be broadcast to each listener
+configured into the system.
+
+<p> The listener callbacks in this example are trivial and simply print an
+informational message to standard output, as shown in the following
+listener class:
+
+<p>
+<table width=600 bgcolor="#CCCCCC"><tr><td>
+<code>
+<pre>
+package com.bolour.sample.eclipse.listener.firstlistener;
+import com.bolour.sample.eclipse.listener.subject.IListener;
+public class ListenerX implements IListener {
+ public void listen() {
+ System.out.println(this.getClass().getName() + " notified");
+ }
+}
+</pre>
+</code>
+&nbsp;&nbsp;&nbsp;&nbsp;
+Listing 5.2. A Listener Callback Implementation.
+</td></tr> </table>
+
+<p>
+So running this example out of the box results in the following console
+messages:
+
+<p>
+<code>
+<pre>
+com.bolour.sample.eclipse.listener.secondlistener.ListenerX notified
+com.bolour.sample.eclipse.listener.secondlistener.ListenerY notified
+com.bolour.sample.eclipse.listener.firstlistener.ListenerX notified
+com.bolour.sample.eclipse.listener.firstlistener.ListenerY notified
+</pre>
+</code>
+
+</ol>
+
+<h3>
+5.1. The Eclipse Extension Model versus the Observer Pattern
+</h3>
+
+<p> As we have seen, the listener extension pattern is analogous to the
+observer pattern, except for its static deployment-time registration of
+listeners. So ignoring the dynamic nature of observer registrations,
+the observer pattern may be thought of as a specialization of
+the Eclipse extension model. In fact, modulo dynamic registration,
+the extension model of Eclipse adds power to the observer pattern
+at a number of levels:
+
+<ol>
+
+<p>
+<li>
+
+<strong>Callback Bundle versus Single Callback</strong>.
+A single extension may provide multiple callback objects.
+A single observer provides a single callback object.
+
+<p>
+<li>
+
+<strong>Differentiation of Extenders versus Uniform Treatment of Observers</strong>.
+Depending on the parameters of an extension and the specifics of the
+extension-point contract, different extensions of a given extension-point
+can be treated differently. In contrast, the observer pattern treats
+all observers of a given subject uniformly, notifying every one
+of an observable event.
+
+<p>
+<li>
+
+<strong>Arbitrary Semantics in Host versus Fixed Notification Semantics in Subject</strong>.
+
+There can be arbitrary parameterized host semantics associated with an
+extension instance. Based on the configuration of the extension, the
+host can accept a variety of customizable responsibilities under the
+extension contract, e.g., the provision of user interface elements.
+There is no such parameterization and customizability
+in the observer design pattern.
+
+</ol>
+
+<p> But a closer comparison exists between the Eclipse extension model and the
+extension model of a <i>microkernel</i> by so-called <i>internal servers</i>,
+e.g., OS device drivers (see, for example, the microkernel pattern in [4]).
+Both models allow a core set of services to be extended by additional
+provider-supplied services. But the Eclipse extension model generalizes the
+internal extension model of the microkernel architecture in two
+ways. First, Eclipse plug-ins provide a packaging mechanism for sets of
+related extensions. Second, in Eclipse any plug-in may provide
+extension-points and make itself extensible by other plug-ins. In contrast,
+in the microkernel architecture, the microkernel core (e.g., an OS
+kernel) has unique standing as the sole extensible component in a system.
+
+<a name="6."> </a>
+<h2>
+6. Summary and Conclusions
+</h2>
+
+<p> The plug-in extension model of Eclipse provides a powerful and general
+paradigm for architecting extensible systems based on loosely-coupled
+components. The principle use of this architecture, of course, is the
+Eclipse workbench. But the basic extension model is an abstract
+architectural pattern quite apart from its specific incarnation in the
+workbench.
+
+<p>
+The principle facilities of this abstract model are:
+
+<ol>
+
+<p>
+<li>
+
+<strong>Deployment-time pluggable components</strong>.
+
+Plug-ins are components that are assembled into a system at deployment time. A
+plug-in is implemented in a running system as an instance of a plug-in
+class. Characteristics of each plug-in are declaratively specified in a
+manifest file, which is interpreted at runtime to instantiate the plug-in
+and relate it to other plug-ins.
+
+<p>
+<li>
+
+<strong>Extension-points</strong>.
+
+A particular way in which a plug-in allows itself to be extended is embodied
+in an <i>extension-point</i>. An extension-point is defined by a plug-in that
+stands in a <i>host</i> role with respect to the extension-point, and may be
+extended by one or more plug-ins that stand in an <i>extender</i> role with
+respect the extension-point. There is a contract associated
+with each extension-point. The contract puts obligations on both the host
+and the extender plug-ins.
+
+<p>
+<li>
+
+<strong>Extensions as Parameterized Callback Bundles</strong>.
+
+An extension-point contract generally provides one or more
+callback interfaces, and requires extenders to provide custom
+implementations (callback objects) for these interfaces. Then
+the host is obligated to call back on these callback objects under
+certain conditions specified in the contract, and based on a particular
+extension's configuration parameters.
+
+<p>
+<li>
+
+<strong>Obligations of the Host</strong>.
+
+The host obligations under an extension-point contract may include
+additional requirements on the behavior of the host, such as a
+requirement on the host to augment its interface by additional
+processing elements.
+
+<p>
+<li>
+
+<strong>Obligations of the Extender</strong>.
+
+The extender describes the characteristics of an extension declaratively in
+its manifest file. The extension-point contract provides an XML schema for
+this description, and the extension specification in the extender's
+manifest file must conform to this schema. The schema includes slots for
+the concrete classes of the extension's callback objects, and for the
+parameters required to construct these objects. The concrete classes are
+furnished by the extender, and must conform to expected interfaces defined
+by the host. At runtime, the host instantiates the configured
+callback objects based on their configuration parameters.
+
+</ol>
+
+
+<p> In summary, Eclipse plug-ins offer a flexible model of extensibility,
+and their abstract architecture for composing systems out of
+loosely-coupled components provides a significant addition to the available
+repertoire of architectural patterns for software systems (see, e.g., [4]).
+
+<a name="instructions"> </a>
+<p><b>
+Sample Code Installation.
+</b>
+
+<p>
+To run the samples appearing in this article and view their source code,
+extract the contents of the <a href="samples.zip">companion plug-ins
+zip file</a> into your Eclipse installation.
+
+<p>
+In order to interact with the samples through the workbench,
+you will have to enable their user interface elements
+as follows:
+
+<ul>
+
+<p>
+<li>
+<i>Extension Processing Demo</i>.
+Bring up the <i>Windows-&gt;Customize
+Perspective</i> dialog, and under <i>Other</i>, enable <i>Demo Menu Actions</i>.
+Close the dialog. The <i>Demo</i> menu should now be available.
+
+<p>
+<li>
+<i>Arithmetic Service</i>.
+Bring up the <i>Windows-&gt;Customize
+Perspective</i> dialog, and under <i>Window-&gt;Show View</i> enable
+<i>Functions Grid View</i>, and close the dialog. In the workbench <i>Window-&gt;Show
+View</i> list, you should now see the list item <i>Functions Grid View</i>.
+Select that item to display the view for this sample.
+
+<p>
+<li>
+<i>Listener Extensions</i>.
+Bring up the <i>Windows-&gt;Customize
+Perspective</i> dialog, and under <i>Other</i> enable <i>Listener
+Menu Actions</i>. Close the dialog. The <i>Listener</i> menu should now
+be available.
+
+</ul>
+
+<p> Note that for simplicity, <i>standard output</i> and <i>standard
+error</i> are used to display messages in these samples. By default, on a
+<i>win32</i> platform, Eclipse uses the <i>javaw</i> virtual machine, which
+does not have an associated console for standard IO. To bring up Eclipse on
+a <i>win32</i> platform with an associated console, the Eclipse executable
+may be asked to use <i>java</i>, rather than <i>javaw</i>, by using the
+<code>-vm</code> option, e.g.,
+
+<code>
+<pre>
+eclipse -vm C:\jdk1.3.1_02\jre\bin\java.exe
+</pre>
+</code>
+
+<p>
+The samples have been tested with Eclipse 2.1 and JDK 1.3.1_02
+on Windows 2000.
+
+<p><b>
+References
+</b>
+
+<ol>
+<li value=1>
+Gamma, Erich, Richard Helm, Ralph Johnson, John Vlissides,
+<i>Design Patterns, Elements of Reusable Object-Oriented Software</i>,
+Addition-Wesley, 1995.
+<li value=2>
+Beck, Kent, and Erich Gamma,
+<a href="http://groups.yahoo.com/group/contributingtoeclipse/files/030410.pdf">
+<i>Contributing to Eclipse</i></a>
+(pre-publication draft) 2003.
+<li value=3>
+Shavor, S., Jim D'Anjou, et. al. <i>The Java Developer's Guide to
+Eclipse</i>, Addison-Wesley, 2003.
+<li value=4>
+Buschmann, Frank, et. al., <i>Pattern-Oriented Software Architecture, A
+System of Patterns, Volume 1</i>,
+John Wiley and Sons, 1996.
+<li value=5>
+Estberg, Don.
+<a href="http://eclipsewiki.swiki.net/2587"><i>How the Minimum Set of Platform
+Plugins Are Related</i></a>, Wiki Page 2587, Eclipse Wiki.
+
+</ol>
+
+<p><b>Acknowledgments</b> </br> This article originated in discussions within
+the <i>Silicon Valley Patterns Group</i> on Eclipse plug-ins. Thanks to the
+members of the group, and in particular to Tracy Bialik, Phil Goodwin, Jan
+Looney, Jerry Louis, Chris Lopez, Russ Rufer, Rich Smith, and Carol
+Thistlethwaite for the original conversations leading to these notes, and
+for many great suggestions for improving the content and presentation of
+the material. Special thanks to Russ Rufer and Tracy Bialik for blazing
+the Eclipse trail for the rest of the group. The group discussions were
+organized around a review of an early manuscript by Kent Beck and Erich
+Gamma: <a href="http://groups.yahoo.com/group/contributingtoeclipse/files/030410.pdf">
+Contributing to Eclipse </a>. These notes, therefore, owe much to Beck and
+Gamma for introducing us to the concepts and facilities of Eclipse
+plug-ins. Don Estberg devised the diagrammatic representation of
+extension-points used in this article, based on the <i>power-strip</i>
+metaphor. Thanks also to Don for his detailed comments. Finally, my thanks
+to Dennis Allard and Dan Conde for their generous offer of time in
+reviewing the final draft of this article, and to Jim des Rivi&egrave;res for his
+detailed review and numerous suggestions for enhancements.
+
+</body>
+
+</html>
+
diff --git a/Article-Plug-in-architecture/samples.zip b/Article-Plug-in-architecture/samples.zip
new file mode 100644
index 0000000..11ed934
--- /dev/null
+++ b/Article-Plug-in-architecture/samples.zip
Binary files differ
diff --git a/Article-Plug-in-architecture/specific_style.css b/Article-Plug-in-architecture/specific_style.css
new file mode 100644
index 0000000..75acf94
--- /dev/null
+++ b/Article-Plug-in-architecture/specific_style.css
@@ -0,0 +1,4 @@
+ul, ol { font-family: arial, helvetica, geneva; font-size: 10pt}
+h4 { font-family: arial, helvetica, geneva; font-size: 12pt; font-weight: bold}
+h5 { font-family: arial, helvetica, geneva; font-size: 12pt; font-weight: bold}
+h6 { font-family: arial, helvetica, geneva; font-size: 10pt; font-weight: bold}
diff --git a/Article-Plugging-into-SourceForge/images/SourceForge.net.png b/Article-Plugging-into-SourceForge/images/SourceForge.net.png
new file mode 100644
index 0000000..afe08c4
--- /dev/null
+++ b/Article-Plugging-into-SourceForge/images/SourceForge.net.png
Binary files differ
diff --git a/Article-Plugging-into-SourceForge/images/WinSCP.png b/Article-Plugging-into-SourceForge/images/WinSCP.png
new file mode 100644
index 0000000..7c1c09e
--- /dev/null
+++ b/Article-Plugging-into-SourceForge/images/WinSCP.png
Binary files differ
diff --git a/Article-Plugging-into-SourceForge/images/cvs-view.png b/Article-Plugging-into-SourceForge/images/cvs-view.png
new file mode 100644
index 0000000..d836321
--- /dev/null
+++ b/Article-Plugging-into-SourceForge/images/cvs-view.png
Binary files differ
diff --git a/Article-Plugging-into-SourceForge/images/frs.png b/Article-Plugging-into-SourceForge/images/frs.png
new file mode 100644
index 0000000..4c11e10
--- /dev/null
+++ b/Article-Plugging-into-SourceForge/images/frs.png
Binary files differ
diff --git a/Article-Plugging-into-SourceForge/images/new-cvs.png b/Article-Plugging-into-SourceForge/images/new-cvs.png
new file mode 100644
index 0000000..d632056
--- /dev/null
+++ b/Article-Plugging-into-SourceForge/images/new-cvs.png
Binary files differ
diff --git a/Article-Plugging-into-SourceForge/images/sfpde-med.png b/Article-Plugging-into-SourceForge/images/sfpde-med.png
new file mode 100644
index 0000000..51f3ac2
--- /dev/null
+++ b/Article-Plugging-into-SourceForge/images/sfpde-med.png
Binary files differ
diff --git a/Article-Plugging-into-SourceForge/images/working-set.png b/Article-Plugging-into-SourceForge/images/working-set.png
new file mode 100644
index 0000000..087f694
--- /dev/null
+++ b/Article-Plugging-into-SourceForge/images/working-set.png
Binary files differ
diff --git a/Article-Plugging-into-SourceForge/sourceforge.html b/Article-Plugging-into-SourceForge/sourceforge.html
new file mode 100644
index 0000000..a23e7f4
--- /dev/null
+++ b/Article-Plugging-into-SourceForge/sourceforge.html
@@ -0,0 +1,935 @@
+<html>
+
+ <head>
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=windows-1252"/>
+
+ <title>Plugging into SourceForge.net</title>
+
+ <link href="../default_style.css" rel="stylesheet"/>
+
+ <meta content="David J. Biesack (david_biesack@users.sourceforge.net)"
+ name="author"/>
+
+ <meta content="pombredanne@nexb.com"
+ name="editor"/>
+
+ <meta content="Describes how you can publish your open source Eclipse Plug-In on SourceForge.net"
+ name="description"/>
+
+ <meta content="https://bugs.eclipse.org/bugs/show_bug.cgi?id=94940"
+ name="bugzilla"/>
+
+ </head>
+
+ <body>
+
+ <div align="right">
+
+ Copyright © 2005 by David J. Biesack
+ <table border="0" cellpadding="2" cellspacing="0" width="100%">
+
+ <tbody>
+
+ <tr>
+
+ <td align="left" bgcolor="#0080c0" colspan="2" valign="top">
+ <font color="#ffffff"><b>  Eclipse Corner
+ Article</b></font></td>
+
+ </tr>
+
+ </tbody>
+
+ </table>
+
+ </div>
+
+ <div align="left">
+
+ <h1><img align="middle" alt="" height="86" src="../images/Idea.jpg"
+ width="120"/></h1>
+
+ </div>
+
+ <h1 style="align: center;">Plugging into SourceForge.net</h1>
+
+ <blockquote>
+
+ <p><b>Summary</b></p>
+
+ <p>Congratulations on taking the plunge and writing an open source
+ plug-in for the Eclipse platform.
+ SourceForge.net can provide a good home your plug-in, but
+ information on how best to set up an Eclipse project there is sparse.
+ This article is an introduction to SourceForge for the Eclipse
+ developer. You will learn the features available to the
+ SourceForge.net open source developer community and be guided
+ through the process, from creating a SourceForge project to
+ hosting your Eclipse Update site.</p>
+
+ <p><b>By David Biesack, SAS</b></p>
+
+ <p>October 15, 2005</p>
+
+ </blockquote>
+
+ <hr />
+
+ <h3>SourceForge: A site for everything open source and nothing in
+ particular</h3>
+
+ <div><img align="right" alt="SourceForge.net logo"
+ src="images/SourceForge.net.png"
+ style="margin:5px; width: 210px; height: 62px;" title="SourceForge.net"/></div>
+
+ <p><a href="http://www.sourceforge.net/">SourceForge.net</a> (or
+ simply SourceForge) is the world's largest open source
+ software repository and developer resource. Just as Eclipse is an
+ &quot;<a href="http://www.eclipse.org/articles/Article-UI-Guidelines/v200202/Contents.html"
+ >IDE for everything and nothing in particular</a>&quot;,
+ SourceForge is a developer site for everything open source and
+ nothing in particular. Similar to how an Eclipse plug-in plugs into
+ the Eclipse framework through extensions of well-known extension
+ points, open source projects &quot;plug into&quot; the rich
+ collaboration community hosted by SourceForge.</p>
+
+ <p>SourceForge is language and platform agnostic &mdash;
+ it may be Java, .Net, Perl,
+ Ruby, PHP, or any other software project. For each project, regardless of
+ language or platform, a wide array of services is freely
+ available. The project 'extension points' include server
+ space for a project web site, your own project sub-domain, a CVS
+ server, file release management, GNU Mailman mailing lists, project
+ categorization, on-line discussion forums, bug tracking, secure
+ login shell and FTP, a compile farm, task lists and even an on-line
+ financial donation management.</p>
+
+ <div><img align="right"
+ alt="SFPDE - SourceForge Plug-In Development Environment"
+ src="images/sfpde-med.png" style="margin: 5px;width: 360px; height: 265px;"
+ title="SFPDE - SourceForge Plug-In Development Environment"/></div>
+
+ <p>There are too many services available to cover in this article,
+ so I present one common scenario &mdash; the creation of a new project
+ &mdash; and I introduce features as they come into play in the life
+ cycle of developing, publishing, and supporting an open source
+ plug-in for Eclipse.</p>
+
+ <p>You will see how SourceForge extends the Eclipse Plug-in
+ Development Environment (PDE) to create what I refer to as the
+ SourceForge <strong>Plug-in Development Environment</strong>
+ (SFPDE). Eclipse provides the coding, testing, debugging, and
+ packaging aspects of Plug-in development. The SFPDE adds the source
+ management, distribution, collaboration, discovery, web hosting,
+ and support capabilities. The combined SFPDE services offer a
+ comprehensive environment for Eclipse plug-ins
+ development.</p>
+
+ <p>I will use a humble plug-in that I wrote and released on
+ SourceForge as an example (the
+ <a href="http://eclipseexeditor.sourceforge.net/">Eclipse Text
+ Editor Extensions</a> ), so you can refer to a concrete plug-in
+ project.</p>
+
+ <p>For this article, I assume that you are already familiar with
+ writing Eclipse plug-ins, and you have an idea that will
+ revolutionize the Eclipse community: if only you had a way to share
+ it as an open source project! You have some code to commit to CVS
+ and would like to attract one or two open source contributors
+ to help you polish it off. I also assume you are familiar with
+ most of the concepts of open source projects, including license
+ models, community involvement, patches and contributions, etc. If
+ not, there are resources available at the
+ <a href="http://www.opensource.org/">open source Initiative</a>
+ (OSI).</p>
+
+ <h3>Planning</h3>
+
+ <p>As with any software endeavor, a little bit of planning will
+ reduce your long-term frustration. With an open source project,
+ you probably do not have a software manager and marketing
+ department pushing you to release the new product, so you may
+ actually have time for planning!</p>
+
+ <p>This is an outline of an open source project's lifecycle
+ within the SFPDE:</p>
+
+ <ol>
+
+ <li>Understanding the SourceForge open source Software model</li>
+
+ <li>How to structure a SourceForge project</li>
+
+ <li>Naming the project</li>
+
+ <li>Naming the Java package</li>
+
+ <li>Choosing a license</li>
+
+ <li>Registering on SourceForge</li>
+
+ <li>Trove classification</li>
+
+ <li>Using SourceForge's CVS server for Eclipse projects</li>
+
+ <li>Secure services: private and public keys and SSH</li>
+
+ <li>Making a software release</li>
+
+ <li>Building a web site</li>
+
+ <li>Hosting an update site</li>
+
+ <li>Registering with a plug-in promotion site</li>
+
+ </ol>
+
+ <h3>Plugging In</h3>
+
+ <h4>Understanding the SourceForge open source Software model</h4>
+
+ <p>Before you begin an open source project on SourceForge, be sure
+ you understand the SourceForge definition of open source and its
+ requirements for hosted projects. You should read and grok the
+ SourceForge
+ <a href="http://sourceforge.net/docman/display_doc.php?docid=6048&amp;group_id=1"
+ >Terms of Use</a> , and be fully comfortable with the requirements
+ outlined there. SourceForge users assume certain aspects
+ of open source projects, so be sure you know what the open source and
+ SourceForge communities will expect of you.</p>
+
+ <h4>How to structure a SourceForge project</h4>
+
+ <p>The next step in the planning process is to get your project in
+ order before shipping it up to SourceForge. I have found that it
+ is convenient to create four separate Eclipse projects. Below is
+ the layout of my projects for my sample plug-in. I named the
+ project based on the root Java package, net.sf.eclipseexeditor
+ (described below).</p>
+
+ <table border="0" cellpadding="0" cellspacing="0" style="text-align: left; width: 600px;">
+
+ <tbody>
+
+ <tr>
+
+ <th>Eclipse Project Description</th>
+
+ <th>Example</th>
+
+ </tr>
+
+ <tr>
+
+ <td>Your plug-in, as an Eclipse PDE project.</td>
+
+ <td>net.sf.eclipseexeditor</td>
+
+ </tr>
+
+ <tr>
+
+ <td>Your Plug-In Feature, created from the Eclipse feature
+ wizard.</td>
+
+ <td>net.sf.eclipseexeditor-feature</td>
+
+ </tr>
+
+ <tr>
+
+ <td>Your update site, created from the Eclipse update site
+ wizard.</td>
+
+ <td>net.sf.eclipseexeditor-update-site</td>
+
+ </tr>
+
+ <tr>
+
+ <td>Your web site, your public documentation.</td>
+
+ <td>net.sf.eclipseexeditor-web-site</td>
+
+ </tr>
+
+ </tbody>
+
+ </table>
+
+ <p>Some projects may have several plug-ins, each with its own PDE
+ project. For example, solareclipse has the following project/file
+ structure:</p>
+
+ <ul>
+
+ <li>net.sf.solareclipse-feature</li>
+
+ <li>net.sf.solareclipse-home</li>
+
+ <li>net.sf.solareclipse.jsp.ui</li>
+
+ <li>net.sf.solareclipse.ui</li>
+
+ <li>net.sf.solareclipse.xml.core</li>
+
+ <li>net.sf.solareclipse.xml.ui</li>
+
+ <li>net.sf.solareclipse.xslt.debug.core</li>
+
+ <li>net.sf.solareclipse.xslt.debug.ui</li>
+
+ <li>net.sourceforge.solareclipse.web.ui</li>
+
+ <li>net.sourceforge.solareclipse.xml.core</li>
+
+ </ul>
+
+ <p>Be sure to review your project's names before committing to
+ CVS: the project name will become the CVS module name. The
+ solareclipse project's
+ <a href="http://cvs.sourceforge.net/viewcvs.py/solareclipse/">
+ CVS</a> tree has apparently obsolete modules named
+ <code>org.sourceforge.solareclipse.web.ui</code> and a misspelled
+ <code>net.courceforge.solareclipse.web.ui</code> module.</p>
+
+ <p>You may also find it convenient to define
+ <a href="images/working-set.png">an Eclipse Working Set</a> that
+ contains all your projects. This can help with restricted file
+ searches in Eclipse, i.e. text/file searches for classes or package
+ names in plugin.xml or web site content, in case you need to rename
+ classes or packages. Note that you can host <strong>all</strong>
+ your related Eclipse PDE projects within a single SFPDE project
+ space.</p>
+
+ <h4>Naming the project</h4>
+
+ <p>Patterns, packages, projects have more in common than their
+ first letter. In all cases, a good name cannot be beat. Sadly,
+ my project name (eclipseexeditor) is not a good example. It was
+ only after I had created my SourceForge project and worked on it
+ significantly that I realized that ETEE &mdash; an acronym for
+ Eclipse Text Editor Extensions &mdash; would have been a better
+ choice.</p>
+
+ <p>Your SourceForge project name will be used everywhere in
+ SourceForge: in the Unix file system as the directory name, as a
+ CVS root, as a component of a domain name/URL &mdash;
+ <a href="http://eclipseexeditor.sf.net">
+ http://eclipseexeditor.sf.net</a>, in your project's summary
+ page url &mdash; <a href="http://sf.net/projects/eclipseexeditor">
+ http://sf.net/projects/eclipseexeditor</a> , in Mailman mailing
+ lists names, etc. In other words, choose a name that is easy for
+ your users to use and remember and that still conveys the purpose
+ of your project. SourceForge does not support renaming projects
+ after their creation.</p>
+
+ <p>Here are the SourceForge rules for a project name:</p>
+
+ <ul>
+
+ <li>It must begin with a letter</li>
+
+ <li>It must be between 3 and 15 characters in length</li>
+
+ <li>It can only contain only lowercase letters (a-z), numbers
+ (0-9), and dashes (&quot;-&quot;) or underscores
+ (&quot;_&quot;)</li>
+
+ <li>It cannot match the name of any other project or one of
+ SourceForge's reserved names</li>
+
+ </ul>
+
+ <p>Once again, remember that you cannot change the project name after its creation... so
+ be sure you are happy with the name!</p>
+
+ <h4>Naming the Java package</h4>
+
+ <p>Since we are talking naming, it is a good idea to
+ consider carefully the Java packages names for your plug-ins.   If you are
+ part of a commercial organization or org site that is sponsoring
+ the plug-in development, you may wish to release the plug-in as a
+ specific package within that name space, such as the veloedit
+ Velocity editor: <a href="http://sourceforge.net/projects/veloedit/"
+ ><code>org.vaulttec.velocity.ui</code></a> . Presumably, one should
+ not use <code>org.eclipse</code> as a base package name, as that
+ name space is reserved for official Eclipse projects at
+ www.eclipse.org. I chose the pattern of <code>net.sf.</code> +
+ <i><code>projectname</code></i> (i.e.
+ <code>net.sf.eclipseexeditor</code> ) over something like
+ <code>org.biesack</code> so that the code base will feel more
+ &quot;open&quot; to other contributors. After all, a key aspect of
+ an open source project is that potential collaborators feel
+ welcome.</p>
+
+ <p>Other projects on SourceForge have followed this example, such
+ as <a href="http://sourceforge.net/projects/solareclipse/">
+ net.sf.solareclipse</a> and
+ <a href="http://sourceforge.net/projects/lunar-eclipse/">
+ net.sf.lunar_eclipse</a> . Note that if you wish to follow this
+ pattern, you should avoid using a dash in your project name, which
+ is illegal in Java. The biggest reason to use this format is that
+ it follows
+ <a href="http://java.sun.com/docs/books/jls/second_edition/html/packages.doc.html#40169"
+ >Sun's recommended package naming convention</a> of reversing
+ the domain name. Since your domain name will be
+ <code><i>projectname</i>.sourceforge.net</code> or
+ <code><i>projectname</i>.sf.net</code> , this leads to a Java
+ package name space of <code>net.sf.<i>projectname</i></code>. Other
+ projects do not follow Sun's recommendations. For
+ example, <a href="http://sfutils.sourceforge.net/">sfutils</a> has
+ packages like <code>sfutils.frs</code> with no <code>net</code>
+ or <code>org</code> or <code>com</code> prefix.</p>
+
+ <h4>Choosing a license</h4>
+
+ <p>SourceForge has a well-defined specification
+ for open source projects, including a license. SourceForge requires
+ that you use either an approved an approved open source initiative
+ license, or a license that complies with the
+ <a href="http://www.opensource.org/docs/definition.php">open source definition</a>. See the
+ <a href="http://sourceforge.net/docman/display_doc.php?docid=778&amp;group_id=1"
+ >B6. open source license overview</a> for more details: &quot;<cite>It is vital that you read and
+ understand all of the terms of a license, and verify that it meets
+ the needs of your project, before deciding to use that license;
+ this should not be a decision taken lightly.</cite> &quot;</p>
+
+ <p>The license you select can also influence
+ your ability to draw contributors to your plug-in. In addition, changing a license later often
+ alienates your user and contributing developers' community.
+ Eclipse plug-in developers may want
+ to consider the
+ <a href="http://www.opensource.org/licenses/eclipse-1.0.php">
+ Eclipse Public License</a> (EPL), an <a href="http://opensource.org"
+ >OSI approved</a> and SourceForge acceptable license. By choosing
+ EPL, you will be using the same license as the Eclipse.org
+ projects, and your plug-in license will be compatible with future
+ Eclipse developments.</p>
+
+ <h4>Registering on SourceForge</h4>
+
+ <p>Now that you have some of the planning done and your plug-in is
+ complete enough for an initial code contribution, it is time to
+ start your registration process. Naturally, SourceForge has an
+ on-line web based registration process that guides you through the
+ following steps:</p>
+
+ <ol>
+
+ <li>Hosting information</li>
+
+ <li>Registering a project</li>
+
+ <li>Terms of Use Agreement</li>
+
+ <li>Hosting requirements</li>
+
+ <li>Project license details</li>
+
+ <li>Project description details</li>
+
+ <li>Project name details</li>
+
+ <li>Final review</li>
+
+ <li>Submission completed</li>
+
+ </ol>
+
+ <p>There is plenty of documentation and help along the way. If
+ you have done the suggested planning, this should only take 10 to
+ 15 minutes. Once your new project submission is complete, it will
+ take a few days for the SourceForge staff to process the request
+ and create your project.</p>
+
+ <p>You start by logging into SourceForge. If you do not already
+ have an account, simply click on the <strong>
+ <a href="http://sourceforge.net/account/newuser_emailverify.php"
+ >New User via SSL</a></strong> link on the front page and enter
+ your email address and a create a password. SourceForge will send
+ an email to the address you supply to confirm it is a valid
+ address. (If you have some spam filtering enabled, configure it to
+ allow mail from the domain &quot;sourceforge.net&quot; and any
+ sub domains). You must visit the confirmation URL in that email
+ message. At this point, you will be able to choose an account user
+ name.</p>
+
+ <p>Next, log in using your userid and password, and then click the
+ <strong><a href="http://sourceforge.net/register/">Register New
+ Project</a></strong> link to begin the registration process. Review
+ the Hosting information and the Terms of Use Agreement that you
+ must accept before proceeding. You will need to supply some of the
+ important information discussed above: your project name,
+ license, a short public project description, and a longer project
+ justification to help the SourceForge administrators understand how
+ your project adds value or is different from existing solutions.</p>
+
+ <p>Once you complete your registration, you must wait a few days
+ for the SourceForge administrators to review your request and set
+ up the infrastructure. You should receive an email response
+ informing you of the project's creation when it is ready. You
+ can check the status of any of your project requests by visiting
+ your SourceForge home page:
+ <code>http://sourceforge.net/users/<i>your-userid</i>/</code> .
+ There, you can view all of your SourceForge projects. Also, on the
+ '<a href="https://sourceforge.net/my/myprojects.php">my
+ projects</a>' page you can see all your projects regardless of
+ their approval status.</p>
+
+ <p>When accepted, your project will also receive a unique numeric
+ identifier, called a <i>group id</i>, used to access some project
+ resources on SourceForge instead of the Unix project
+ name.</p>
+
+ <p>Once your project is created, the next step is to verify your
+ project's public information in the Public Info section, and
+ to classify your project in the <a>Trove Software Map</a>.</p>
+
+ <h4>Understanding the Trove Classification</h4>
+
+ <p>The Trove &mdash; or <a href="http://sourceforge.net/softwaremap/">
+ software map</a> &mdash; is a software categorization and classification
+ system to organize all SourceForge projects. The software map is
+ one of the key links on the SourceForge front page. Together with
+ your keywords and description, the Trove makes your
+ plug-in easier to find.</p>
+
+ <p>Unfortunately, the Trove organization does not always fit
+ everyone's model. For example, although there is a top-level
+ category for
+ <a href="http://sourceforge.net/softwaremap/trove_list.php?form_cat=45"
+ >Software Development</a> , the topic
+ <a href="http://sourceforge.net/softwaremap/trove_list.php?form_cat=65"
+ >Integrated Development Environments (IDE)</a> &mdash; a good location
+ for many Eclipse plug-ins &mdash; is instead under the main topic
+ <a href="http://sourceforge.net/softwaremap/trove_list.php?form_cat=63"
+ >Text Editors</a>.   I recommend placing Eclipse plug-ins that
+ are un-related to Software Development &mdash; such as the
+ <a href="http://sourceforge.net/projects/morphine/">Eclipse RSS
+ Reader</a> &mdash; in Trove categories that reflect
+ their use, not their implementation technology.</p>
+
+ <p>Using the software map, you will have the opportunity to select
+ one to six, and sometimes more, project values in each of several
+ categories: Topic, Operating System, Programming Language, License,
+ Intended Audience, User Interface, Translations, Database
+ Environment, and Development Status . Eclipse plug-in writers
+ should include
+ <a href="http://sourceforge.net/softwaremap/trove_list.php?form_cat=583"
+ ><strong>User Interface :: Plugins :: Eclipse</strong></a> in the
+ set of User Interface values, and under Operating Systems, you may
+ want to choose
+ <a href="http://sourceforge.net/softwaremap/trove_list.php?form_cat=235"
+ ><strong>System :: Grouping and Descriptive Categories :: OS
+ Portable (Source code to work with many OS platforms)</strong></a>
+ . You can also use the
+ <a href="http://sourceforge.net/softwaremap/trove_list.php?form_cat=472"
+ ><strong>User Interface :: Graphical :: Java SWT</strong></a>
+ category.</p>
+
+ <p>Review carefully all the options to help your users locate
+ your plug-in while browsing projects categories. See
+ <a href="http://sourceforge.net/docman/display_doc.php?docid=12973&amp;group_id=1"
+ >Software Search and the SourceForge.net Software Map</a> for
+ details.</p>
+
+ <p>Note also that you must add each classification one by one by
+ selecting the value in a drop down list then clicking the Add
+ button to its right. You cannot select values for several
+ categories and add them all at once.</p>
+
+ <h4>Using SourceForge's CVS server for Eclipse projects</h4>
+
+ <p>Now that you have a project that other's can find,
+ it is time to put some content there. The most important
+ content is the source code, managed in a
+ <a href="http://www.cvshome.org/">Concurrent Versions System</a>
+ (CVS) repository. Since Eclipse has built-in support for CVS
+ repositories in the Team development plug-ins, it is
+ straightforward to use within the SFPDE.</p>
+
+ <p>Once approved, your project will have a CVS repository dedicated
+ for it at
+ <code>cvs.sourceforge.net/cvsroot/<i>yourprojectname</i></code> .
+ For example, the net.sf.eclipseexeditor project is at
+ <code>cvs.sourceforge.net/cvsroot/eclipseexeditor</code>.
+ Here is my project's CVS view:</p>
+
+ <p><img alt="Sample CVS project view" src="images/cvs-view.png"
+ style="width: 407px; height: 222px;"
+ title="Sample CVS project view"/></p>
+
+ <p>You can visualize the project partitioning here: I use one directory
+ for the PDE project source, one for the plug-in feature project,
+ one for the update site project, and one for the web site.</p>
+
+ <p>For each of your Eclipse projects, invoke the project's
+ context menu from the Package Explorer view and select the menu
+ Team -&gt;Share Project. Chose CVS and complete the Share Project
+ wizard (see the
+ <a href="http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc.user/gettingStarted/qs-61f_syncproject.htm"
+ >Eclipse help</a> for more details) to attach it to the SourceForge
+ CVS repository. If instead you are going to be joining a project
+ that already resides in CVS, you can simply check the project out
+ of CVS using the standard Eclipse Team operations.   Once your CVS
+ repository is defined in Eclipse, you can use the normal Team
+ operations to commit your source to CVS by invoking Team-&gt;Commit
+ from each of the project folders. I recommend keeping Eclipse
+ metadata files &mdash; <code>.project</code> and <code>.classpath</code>
+ &mdash; under version control so that others can simply checkout
+ the projects from Eclipse's CVS client. Eclipse will
+ automatically detect the project's Java nature, and build path
+ configuration.</p>
+
+ <h4>Secure Services</h4>
+
+ <p>To commit files to SourceForge's CVS servers and access the
+ shell, you must use SSH.</p>
+
+ <p>This means using the <code>extSSH</code> connection method if
+ you want to use Eclipse's built-in CVS and SSH client, or
+ using a properly configured <code>ext</code> method to rely on your
+ favorite SSH client. SSH provides secure communication with the
+ server through encryption.</p>
+
+ <p>If your system already has a SSH implementation, you should be
+ able to use it. SSH implementations are available on Macs and most Unix
+ variants, including Linux. Windows users of the Cygwin tool
+ set can use <a href="http://www.openSSH.org/">OpenSSH</a> , or
+ users without Cygwin and OpenSSH can try <a href="http://www.putty.nl/">
+ PUTTY</a> or another secure shell tool set.</p>
+
+ <p>If available, SourceForge recommends using a tool set that uses
+ the SSH2 protocol for greater security, which is the version
+ supported by Eclipse's built-in CVS SSH client.</p>
+
+ <p>You will also need SSH to copy files to your project's
+ shell and web space. The SourceForge site help
+ provides complete documentation to
+ <a href="http://sourceforge.net/docman/display_doc.php?docid=6841&amp;group_id=1"
+ >configure SSH</a>.   Windows users may also consider
+ <a href="http://www.winscp.net">WinSCP</a> , a SourceForge
+ <a href="http://sourceforge.net/projects/winscp">project</a> that
+ provides drag and drop integration with Windows. For example, after
+ you update your web site in Eclipse, you can open WinSCP, authenticate, then jump via a WinSCP favorite to your SourceForge
+ project web space and <a href="images/WinSCP.png">drag files
+ from the Eclipse Package Explorer</a> to the WinSCP view.</p>
+
+ <h4>Making a software release</h4>
+
+ <p>Software releases are the primary mechanism that SourceForge
+ users employ to make downloads available software to their users.
+ SourceForge supports a robust system for releasing your software.
+ Released files are preserved for the lifetime of the project, allowing
+ anyone to download previous releases &mdash; although you can hide
+ releases if needed. Making a software release on SourceForge is
+ well documented in the
+ <a href="http://sourceforge.net/docman/display_doc.php?docid=6445&amp;group_id=1"
+ >Guide to the File Release System (FRS)</a>.</p>
+
+ <p>SFPDE users can use the FRS to publish plug-in jar files. You
+ should also release your plug-in source as part of each release.
+ There are several ways to do this: you can include source in your
+ jar file (to facilitate debugging in Eclipse) or you can use an
+ Ant task to create a zip file of your source. The fewer the number
+ of files in a release, the easier it is to manage, so it is best to
+ minimize files by using archive files (jar files, zip files, tar.gz
+ files, etc.) to collect the files for a release. Note that with open source projects, users often expect releases to
+ contain the source. It is considered impolite to force users to fetch the
+ source from CVS. Do not forget to include your license file in
+ your release.</p>
+
+ <p>To create a release, follow these steps:</p>
+
+ <ol>
+
+ <li>Login to SourceForge</li>
+
+ <li>Select your project</li>
+
+ <li>Go to the Admin panel for your project and select the File
+ Releases link from the navigation menu to enter the FRS.</li>
+
+ <li>Define a <em>FRS package</em> if none is defined.
+ A FRS package a collection of files associated with a
+ project; each plug-in can map to a FRS package.
+ For my eclipseexeditor project, the FRS contains one package &mdash;
+ eclipseexeditor &mdash; as shown in the
+ <a href="http://sourceforge.net/project/showfiles.php?group_id=137861"
+ >Files</a> page .</li>
+
+ <li>Use anonymous FTP to upload files to upload.sourceforge.net.
+ You may use your favorite FTP client for this. SourceForge does
+ not provide anonymous web upload.</li>
+
+ <li>Define a new release &mdash; typically named after the version
+ number, such as 0.1, 1.0Beta2, 1.0, 2.0, etc. &mdash; for your package
+ by using the SourceForge web interface.</li>
+
+ <li>Add files from the anonymous FTP site to the release. The
+ SourceForge web interface provides all you need for this &mdash; you
+ add a new file to the release, select that file from the set of all
+ files in the upload area and select a file type. Remember that other SourceForge users are
+ building releases at the same time, so you will see other files
+ there.</li>
+
+ <li>Verify the release contents by downloading and installing the
+ plug-in in a clean Eclipse installation.</li>
+
+ </ol>
+
+ <p>To create a new release, simply click the
+ Add Release button and submit the web form to create a new release.
+ You can then add the files from the anonymous upload site to the
+ release.</p>
+
+ <div style="text-align: center;">
+
+ <p><img alt="File Release System - Add a Release"
+ src="images/frs.png"
+ title="File Release System - Add a Release"/></p>
+
+ </div>
+
+ <p>SourceForge offers download statistics for each released file.
+ You can monitor how many people have downloaded your source zip or
+ Eclipse plug-in. </p>
+
+ <p>You may also want to have a look at the <a href="http://sfutils.sourceforge.net">sfutils</a> package.
+ It provides an Ant task and
+ Java API to automate software releases on SourceForge. With
+ sfutils, you can make a release directly from Eclipse by running
+ Ant.</p>
+
+ <h4>Building a web site</h4>
+
+ <p>SourceForge provides enhanced web hosting for projects. In
+ addition to basic HTML services, you get:</p>
+
+ <ol>
+
+ <li>DNS registration. The URL
+ <code>http://yourprojectname.sourceforge.net</code> is reserved
+ for your project web site. For example, my ETEE project is
+ hosted at <a href="http://eclipseexeditor.sourceforge.net">
+ http://eclipseexeditor.sourceforge.net</a>. I emphasize again
+ the importance of choosing a good project name from the
+ beginning.</li>
+
+ <li><a href="http://php.net/">PHP</a>,
+ <a href="http://perl.com/">Perl</a>,
+ <a href="http://python.org/">Python</a> scripting.</li>
+
+ <li>MySQL database.</li>
+
+ </ol>
+
+ <p>You can of course use Eclipse to develop this content. For
+ example, you may use the Eclipse Web Tools project to create your
+ HTML content. There are also PHP authoring plug-ins.</p>
+
+ <p>To publish your content, you must use SSH secure copy.
+ You must login under a
+ project's administrator id, which gives you write access to
+ the web page space. Due to the large number of hosted projects,
+ SourceForge uses a branching directory structure to make it
+ easier to navigate and so that clients do not have to download
+ extremely large directory listings. For example, my eclipseexeditor
+ project is stored at
+ <code>/home/groups/e/ec/eclipseexeditor</code>. I use WinSCP to
+ copy files from my home computer to the SourceForge server. In this
+ <a href="images/WinSCP.png">screenshot</a>, I drag a file
+ from the Eclipse package explorer to WinSCP's folder
+ representing my SourceForge-hosted project web space.</p>
+
+ <p>Each project is required to
+ <a href="http://sourceforge.net/docs/E07/en/#top">display the
+ SourceForge logo</a> on their web pages hosted on the project web
+ service. There are several logos available. You get the logo
+ image from a special SourceForge URL that includes your project
+ group id. The SourceForge server records a page hit for your project
+ when a web browser displays the image. For example, the image URL
+ <code>http://sourceforge.net/sflogo.php?group_id=137861&amp;type=1</code>
+ counts as a web hit for my ETEE project with the group id 137861.
+ Be sure to use the correct logo image URL so your project gets
+ accurate web statistics.</p>
+
+ <h4>Hosting an update site</h4>
+
+ <p>You may wonder if you can use the SourceForge web hosting
+ service to host an Eclipse Plug-in update site. There is little
+ guidance on this that I know of. Some people report that this is
+ frowned upon because SourceForge encourages the use of the File
+ Release System (FRS) for hosting binaries. The FRS uses mirror
+ sites around the world to support scalable download services for
+ SourceForge projects. In addition, if you use the FRS, you get the
+ benefits of download statistics that show download counts. Such
+ download counts can raise your project's activity rating and
+ add some momentum to your project. Nevertheless, you have the following
+ alternative for your update site:</p>
+
+ <ul>
+
+ <li>If you want to host an update site on your project web site
+ instead of using the FRS, you should ask the SourceForge
+ administrators first. It may be bad etiquette to
+ place binary files on the project web site &mdash; if overused, binary
+ file downloads could affect web page hosting performance for all
+ SourceForge projects. To deploy your update, you will just need
+ to copy the site to your project web space.</li>
+
+ <li>If you want to host an update site using the FRS, the
+ procedure is a bit more complex. The FRS uses mirror sites, so
+ you will need to design your update site so that it obtains files
+ from one mirror only. In addition, the FRS is a flat structure
+ with a single directory per project. Therefore any plug-in and feature
+ you release must have a unique name &mdash; you cannot have a feature jar
+ that has the same name as a plug-in jar.
+ You then need to make a release for each feature
+ and plug-in jars to the FRS. Then you need to create an enhanced
+ site.xml file manually. You can find a good example
+ <a href="http://eplug.sourceforge.net/site.xml">here</a> with
+ some explanations at the bottom of the
+ <a href="http://eplug.sourceforge.net/">eplug project home page</a>, which uses that approach.
+ With a bit more
+ work, it should even be possible to take advantage of the Sourceforge mirrors.</li>
+ </ul>
+
+ <p>One additional option to consider is to bundle a full update
+ site (the <code>site.xml</code> and jar files etc.) into an
+ archive, and make that file part of your release. Then, users can
+ download the update site and host it locally, for example on a
+ local Eclipse update site on a corporate intranet. Since people
+ will share binaries anyway, you can make it easier and help with
+ wider adoption of your plug-in.</p>
+
+ <p>Since an update site can manage multiple plug-ins versions, you
+ should consider defining a separate SourceForge FRS
+ 'package' for your update site archive. If you simply
+ include the update site (call it <code>update-site.zip</code> ) in
+ the normal plug-in package, version 1.0 of
+ <code>update-site.zip</code> will contain version 1.0 of your
+ plug-in. Version 1.1 of <code>update-site.zip</code> will contain
+ both 1.0 and 1.1 of your plug-in. Since SourceForge never deletes
+ previous releases, this practice leads to a lot of unnecessary wasted
+ server space and potential confusion. I find easier to maintain
+ only one release of an update site package (with a release name of
+ &quot;updates&quot; instead of a numbered release name). Then, each
+ time you release a new version of the plug-in, simply replace the
+ current <code>update-site.zip</code> &mdash; which contains whatever
+ plug-in versions you wish &mdash; within that updated package's
+ release.</p>
+
+ <h4>Registering with a plug-in promotion site</h4>
+
+ <p>Once you have your plug-in deployed via SFPDE, you need to tell
+ the Eclipse community about it. In addition to the SourceForge
+ Trove, you may wish to consider registering your Plug-in on one of
+ several plug-in listing sites that you can find on the Eclipse.org
+ <a href="http://www.eclipse.org/community/osplugins.html">community
+ page</a>.</p>
+
+ <p>If one of these sites does not drive enough traffic to your
+ plug-in, you can always write and publish an article about Eclipse
+ and figure out an interesting way to plug your plug-in in your
+ article!</p>
+
+ <h3>Parting Thoughts</h3>
+
+ <p>Explore all the services the '<strong>SourceForge Plug-in
+ Development Environment</strong>' has to offer. Once you have created,
+ configured, and populated your project site, refer to your
+ project's Admin link and the on-line SourceForge documentation
+ to learn how to:</p>
+
+ <ul>
+
+ <li>Backup up your configuration</li>
+
+ <li>Use the compile farm</li>
+
+ <li>Choosing your support options</li>
+
+ <li>Creating Mailman mailing lists and hosting web discussion
+ forums</li>
+
+ </ul>
+
+ <p>You will find that SourceForge is a tremendous resource for open
+ source development and the project management of Eclipse plug-ins
+ development projects &mdash; a web hosting equivalent of the Eclipse
+ desktop experience.
+ Plug into SourceForge today and see your plug-in reap the myriad
+ benefits SFPDE &mdash; SourceForge + Eclipse PDE &mdash; has to offer.</p>
+
+ <h3>Resources</h3>
+
+ <ul>
+
+ <li><a href="http://sourceforge.net/">SourceForge.net</a></li>
+
+ <li>SourceForge.net
+ <a href="http://sourceforge.net/docman/display_doc.php?docid=6048&amp;group_id=1"
+ >Terms of Use</a></li>
+
+ <li><a href="http://sourceforge.net/docs/">SourceForge End User
+ documentation</a></li>
+
+ <li><a href="http://www.opensource.org/">opensource.org</a> (OSI)</li>
+
+ <li><a href="http://www.javaforge.com/">JavaForge (a SourceForge alternative)</a></li>
+
+ </ul>
+
+ <hr style="width: 100%; height: 2px;"/>
+
+ <h3>Revision History</h3>
+
+ <table border="1" cellpadding="2" cellspacing="2" style="width: 100%; text-align: left;">
+
+ <tbody>
+
+ <tr>
+
+ <th style="vertical-align: top;">Date</th>
+
+ <th style="vertical-align: top;">Comment</th>
+
+ </tr>
+
+ <tr>
+
+ <td
+ style="vertical-align: top; background-color: rgb(238, 238, 238);">
+ October 14, 2005</td>
+
+ <td
+ style="vertical-align: top; background-color: rgb(238, 238, 238);">
+ Created; David J. Biesack,
+ david_biesack@users.sourceforge.net</td>
+
+ </tr>
+
+ </tbody>
+
+ </table>
+ <p>Copyright © 2005 by David J. Biesack</p>
+ <p>To discuss or report problems in this article see <a
+ href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=94940">bug 94940</a>.</p>
+
+ <p><small>VA Software and OSTG are trademarks of VA Software
+ Corporation. SourceForge is a registered trademark of VA Software
+ Corporation in the United States and other countries.</small></p>
+
+ <p><small>Java and all Java-based trademarks and logos are
+ trademarks or registered trademarks of Sun Microsystems, Inc. in
+ the United States, other countries, or both.</small></p>
+
+ <p />
+
+ </body>
+
+</html>
+
diff --git a/Article-Preferences/images/Idea.jpg b/Article-Preferences/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Preferences/images/Idea.jpg
Binary files differ
diff --git a/Article-Preferences/images/badwordpreference.gif b/Article-Preferences/images/badwordpreference.gif
new file mode 100644
index 0000000..8dd4607
--- /dev/null
+++ b/Article-Preferences/images/badwordpreference.gif
Binary files differ
diff --git a/Article-Preferences/images/colorpreference.gif b/Article-Preferences/images/colorpreference.gif
new file mode 100644
index 0000000..a57f60d
--- /dev/null
+++ b/Article-Preferences/images/colorpreference.gif
Binary files differ
diff --git a/Article-Preferences/images/tag_1.gif b/Article-Preferences/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Preferences/images/tag_1.gif
Binary files differ
diff --git a/Article-Preferences/images/tag_2.gif b/Article-Preferences/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Preferences/images/tag_2.gif
Binary files differ
diff --git a/Article-Preferences/images/tag_3.gif b/Article-Preferences/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Preferences/images/tag_3.gif
Binary files differ
diff --git a/Article-Preferences/images/tree.gif b/Article-Preferences/images/tree.gif
new file mode 100644
index 0000000..b317603
--- /dev/null
+++ b/Article-Preferences/images/tree.gif
Binary files differ
diff --git a/Article-Preferences/preferences.htm b/Article-Preferences/preferences.htm
new file mode 100644
index 0000000..3781132
--- /dev/null
+++ b/Article-Preferences/preferences.htm
@@ -0,0 +1,414 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+
+
+<title>Preferences and Properties in the Eclipse Workbench UI</title>
+<link rel="stylesheet" type="text/css" href="../default_style.css">
+</head>
+
+<body>
+<DIV align=right><FONT face="Times New Roman, Times, serif"
+size=2>Copyright © 2001,2002 Object Technology International, Inc.</FONT> </DIV>
+<TABLE border=0 cellPadding=2 cellSpacing=0 width="100%">
+ <TBODY>
+ <TR>
+ <TD align=left bgColor=#0080c0 colSpan=2 vAlign=top><B><FONT
+ face=Arial,Helvetica><FONT color=#ffffff>&nbsp;Eclipse Corner
+ Article</FONT></FONT></B></TD></TR></TBODY></TABLE>
+<H1><img align=center
+src="images/Idea.jpg" width="120" height="86">
+<center>Preferences in the Eclipse Workbench UI</center></H1>
+<blockquote>
+<b>Summary</b><br>
+In the Eclipse Platform plug-in developers define preference pages for their plug-ins
+for use in the Workbench Preferences Dialog. This article explains when to use a
+preference and some of the features the Eclipse Platform provides to support
+preferences.
+ <p><b>By Tod Creasey, OTI<br>
+ </b> August 15, 2002</p>
+ <p>Editor's note: This article was originally published in December 2001 and
+ described Eclipse release 1.0. This revision reflects the minor enhancements
+ made to UI preferences in Eclipse release 2.0.</p>
+</blockquote>
+<HR width="100%">
+
+<h2>Introduction</h2>
+<p>The Eclipse Platform has support for&nbsp; preferences that are
+persisted along with the workspace. This article will discuss what type of data
+should be stored as a preference and will show how to develop and register a
+user interface to allow the user to set these preferences as well as how to
+store them independent of the workbench by use of the import and export
+functions. It will also cover
+how to initialize and retrieve preferences for use by other other plug-ins that
+use your plug-in. This functionality will be shown using an example that
+searches files for bad words. We will set our preferences for this tool
+using two preference pages, one simple one to set a highlight color and one more
+complex one to set the list of words.
+</p>
+<h2>When to Use a Preference
+</h2>
+<p>A preference is data that is persisted between workspace sessions to allow
+the user to keep the state of a plug-in consistent between Eclipse sessions. As
+of 2.0 Eclipse offers two varieties of preference, UI preferences (the same as
+in 1.0) and Core Preferences. This article is concerned only with how to use the
+UI preference store. Typical UI preferences are
+default values for new instances, colors for editors and paths. Core preferences
+are used for values that are not part of the user interface.&nbsp;
+</p>
+<p>Preferences are not intended to reference any resource currently defined in
+the workspace and instead should be used for editors, views or other objects that
+perform operations on a resource. Data persisted on a resource instance is better suited to be
+a property which will be discussed in a later article.
+</p>
+<p>A preference can be made available to any plug-in that has your plug-in as a
+prerequisite. The usual way to do that is to provide API on your plug-in that
+allows for access to the preferences you want to make available. The values of
+these preferences are stored in the .metadata/.plugins directory of the
+workspace on a per plug-in basis. We demonstrate
+how to do this below.
+</p>
+<h2>The Preference Store and the Plug-in</h2>
+<p>Every plug-in has it's own preference store provided by the workspace. For
+ this example we will define a plug-in and use its preference store for our preferences.
+ As we are going to use this plug-in within the UI we define it as a subclass
+ of AbstractUIPlugin. Our constructor (see <img border="0" src="images/tag_2.gif" width="24" height="13">)
+ will create a singleton to allow easy access to the plug-in instance in the
+ workbench. We also implement the method initializeDefaultPreferences() to set
+ up our default values for our two preferences. We are defining a preference
+ for the bad words and a preference for the color of the highlight. Each preference
+ value is looked up using a given key. In the code below the keys we are using
+ are defined by the constants in <img src="images/tag_1.gif" width="24" height="13">.
+</p>
+<p>The default value should be set for all preferences to be sure that there is
+ a value to use at all times. A default value also ensures that the UI can provide
+ a way to reset a preference value back to a reasonable initial setting via the
+ Restore Defaults button.The default value of the preference should be initialized
+ in the plug-in so that it is set before any of the UI is created.&nbsp; </p>
+<p> IAbstractWorkbenchPlugin defines a method called initializeDefaultPreferences(IPreferenceStore)
+ which is called when the preference store is created the first time. In this
+ method (see <img border="0" src="images/tag_3.gif" width="24" height="13">) you should
+ set the default value for all values that you will be using the preference store
+ for. We set a default color using the helper methods in the PreferenceConverter
+ which allows the plug-in developer to set and get values for a preference of
+ commonly stored types like FontData, Point etc. This API is provided because
+ preferences are stored and retrieved as Strings in a human readable format in
+ order to leverage the java properties mechanism.&nbsp; Our more complex bad
+ words preference is initialized using a set of preselected bad words defined
+ in the format we are going to store them in as we do not have API on the PreferenceConvertor
+ to store or retreive arrays of Strings.</p>
+<pre>Color color= Display.getDefault().getSystemColor(SWT.COLOR_BLUE);
+PreferenceConverter.setDefault(store, HIGHLIGHT_PREFERENCE, color.getRGB());</pre>
+<pre>public class BadWordCheckerPlugin extends AbstractUIPlugin {
+ //The shared instance.
+ private static BadWordCheckerPlugin plugin;
+
+ //The identifiers for the preferences
+<img border="0" src="images/tag_1.gif" width="24" height="13"> public static final String BAD_WORDS_PREFERENCE = &quot;badwords&quot;;
+ public static final String HIGHLIGHT_PREFERENCE = &quot;highlight&quot;;
+
+ //The default values for the preferences
+ public static final String DEFAULT_BAD_WORDS = &quot;bug;bogus;hack;&quot;;
+ public static final int DEFAULT_HIGHLIGHT = SWT.COLOR_BLUE;
+
+ public BadWordCheckerPlugin(IPluginDescriptor descriptor) {
+ super(descriptor);
+<img border="0" src="images/tag_2.gif" width="24" height="13"> plugin = this;
+ }
+
+ public static BadWordCheckerPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Initializes a preference store with default preference values
+ * for this plug-in.
+ */
+ protected void initializeDefaultPreferences(IPreferenceStore store) {
+<img border="0" src="images/tag_3.gif" width="24" height="13"> store.setDefault(BAD_WORDS_PREFERENCE, DEFAULT_BAD_WORDS);
+ Color color= Display.getDefault().getSystemColor(DEFAULT_HIGHLIGHT);
+ PreferenceConverter.setDefault(store, HIGHLIGHT_PREFERENCE, color.getRGB());
+
+ }
+}</pre>
+<h2>Defining Preference Pages in plugin.xml</h2>
+<p>Now that we have defined the preference we want to provide a way for the user
+to set the preference value. Preference pages for the workbench can be found in
+the preferences dialog. The preferences dialog is accessible via the Window-&gt;Preferences
+menu group. Plug-in developers should add their preference pages to this dialog using the plugin.xml of their
+plug-in in order to maintain a consistent look and feel with other Eclipse
+plug-ins. The definition of the preference pages within plugin.xml looks like
+this:
+</p>
+<pre>&lt;extension point=&quot;org.eclipse.ui.preferencePages&quot;&gt;
+ &lt;page id=&quot;BadWordsPreferencePage&quot;
+<img border="0" src="images/tag_1.gif" width="24" height="13"> name=&quot;Bad Words&quot;
+<img border="0" src="images/tag_2.gif" width="24" height="13"> class=&quot;org.eclipse.ui.articles.badwordchecker.BadWordsPreferencePage&quot;&gt;
+ &lt;/page&gt;
+
+ &lt;page id=&quot;BadWordsColorPreferencePage&quot;
+ name=&quot;Colors&quot;
+ class=&quot;org.eclipse.ui.articles.badwordchecker.BadWordsColorPreferencePage&quot;
+<img border="0" src="images/tag_3.gif" width="24" height="13"> category=&quot;BadWordsPreferencePage&quot;&gt;
+ &lt;/page&gt;
+&lt;/extension&gt;</pre>
+<p>The definition above sets the name (<img border="0" src="images/tag_1.gif" width="24" height="13">)
+of the preference page for use in the list
+of pages in the preference dialog and also specifies the class(<img border="0" src="images/tag_2.gif" width="24" height="13">) to be
+instantiated for creating the preference page. This class must conform to
+IWorkbenchPreferencePage.</p>
+<p>In the second definition there is a category (<img border="0" src="images/tag_3.gif" width="24" height="13">)
+tag which is used to make one
+page the child of another in the list in the preferences dialog. Preference
+pages can be stored as the children of other pages. This is useful
+for keeping a series of pages together that are related to each other and also
+reduces the clutter in the workbench preferences page. A page can be made the
+child of another page by setting the id of the parent page as the value of the
+category field in the plugin.xml. A page with no parent is displayed as a child
+with no root.</p>
+<p>With the above declarations in our plugin.xml the list of preference pages
+shown in the preference dialog will look like Figure 1.</p>
+<p align="center"><img border="0" src="images/tree.gif" width="187" height="291"></p>
+<p align="center"><b>Figure 1</b>:Preference dialog showing Bad Words and Colors
+ preferences</p>
+<h2>The Color Preference Page
+</h2>
+<p>The color preference page is an example of a simple page that uses a single
+JFace field editor to manage its values. Initially a preference page class is
+defined.&nbsp; All
+classes used in the preference dialog must conform to IWorkbenchPreferencePage.
+Eclipse includes the class PreferencePage which implements most of the necessary API
+for a preference page. PreferenceDialog will save the preference store whenever
+OK is pressed - if you wish to use PreferencePages in places other than the
+default dialog in Window-&gt;Preferences be sure that you save the preference
+store after changes have been applied.</p>
+<p>The class definition for our preference page is:</p>
+<pre>class BadWordsColorPreferencePage
+ extends PreferencePage
+ implements IWorkbenchPreferencePage</pre>
+<p>Once we have defined the page we want to initialize it.&nbsp; IWorkbenchPreferencePage
+specifies a message init(IWorkbench) for this purpose. We will not use the Workbench
+argument for this page. Our implementation only sets
+the preference store for the page.</p>
+<pre>public void init(IWorkbench workbench) {
+ //Initialize the preference store we wish to use
+ setPreferenceStore(BadWordCheckerPlugin.getDefault().getPreferenceStore());
+}</pre>
+<p>The other required method we must implement is createContents().
+All we are going to do is use a ColorFieldEditor
+to set our preference. It is also suggested that performDefaults is
+implemented so that the current state can be reset to the defaults defined in
+the plug-in. We also need to implement performOK so that the settings defined by the user are
+stored in the preference store for our plug-in. Our
+implementation is simple as the ColorFieldEditor has the code to load defaults
+and store the results of an apply for a preference already defined and performOK
+and performDefaults can call the corresponding methods on ColorFieldEditor. See
+figure 2 for the Colors preference page.</p>
+<pre>protected void performDefaults() {
+ colorEditor.loadDefault();
+}
+/**
+ * Save the color preference to the preference store.
+ */
+public boolean performOk() {
+ colorEditor.store();
+ return super.performOk();
+}</pre>
+<p>&nbsp;</p>
+<p align="center"><img border="0" src="images/colorpreference.gif" width="606" height="532"></p>
+<p align="center"><b>Figure 2</b>: Preference dialog showing Colors preference
+page</p>
+<h2>The Bad Words Preference Page
+</h2>
+<p>We have seen how to do a simple preference page with just a color and categorize it.
+Now we will show how to use a complex object as a
+preference and still have it persisted by the preference store and editable in a
+preference page. For this example
+we are going to add a bad words preference which is an array of Strings.
+</p>
+<p>As the PreferenceConverter does not have API for conversion of arrays of
+Strings we will implement it ourselves in the BadWordCheckerPlugin.
+By implementing it in the plug-in we put the API for the use of the preference in
+a place visible to all objects that have access to this plug-in. Normally we
+would use the PreferenceConverter for conversion to and from the storage format.</p>
+<p>Methods for getting the default value of the
+preference and a getter and a setter are
+defined first - getBadWordsDefaultPreference (which returns an array of Strings),
+getBadWordsPreference (which also returns an array of Strings) and
+setBadWordsPreference which takes an array of Strings as its argument. The
+String array is stored in the preference store as a single string separated by semicolons. We choose
+semicolons as this character is only ever used as punctuation and will therefore never
+be part of a word we are searching for.</p>
+<pre>/**
+ * Return the bad words preference default.
+ */
+public String[] getDefaultBadWordsPreference(){
+ return convert(getPreferenceStore().getDefaultString(BAD_WORDS_PREFERENCE));
+}
+
+/**
+ * Returns the bad words preference.
+ */
+public String[] getBadWordsPreference() {
+ return convert(getPreferenceStore().getString(BAD_WORDS_PREFERENCE));
+}
+
+/**
+ * Converts PREFERENCE_DELIMITER delimited String to a String array.
+ */
+private String[] convert(String preferenceValue) {
+ StringTokenizer tokenizer =
+ new StringTokenizer(preferenceValue, PREFERENCE_DELIMITER);
+ int tokenCount = tokenizer.countTokens();
+ String[] elements = new String[tokenCount];
+ for (int i = 0; i &lt; tokenCount; i++) {
+ elements[i] = tokenizer.nextToken();
+ }
+
+ return elements;
+}
+
+/**
+ * Sets the bad words preference.
+ */
+public void setBadWordsPreference(String[] elements) {
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i &lt; elements.length; i++) {
+ buffer.append(elements[i]);
+ buffer.append(PREFERENCE_DELIMITER);
+ }
+ getPreferenceStore().setValue(BAD_WORDS_PREFERENCE, buffer.toString());
+}
+</pre>
+<p>There is no field editor defined in JFace
+for&nbsp; editing String arrays so we will define a list that shows the
+items with widgets to add and remove them. Our performOK method will send the
+current contents of the list to the setBadWordsPreference method and the
+performDefaults method will reset the list of strings to be the result of
+getDefaultBadWordsPreference. Both methods are defined in BadWordCheckerPlugin. As a List widget takes an array of Strings as its
+content we can use the results of these helper methods directly
+in conjunction with the methods we defined for the bad words preference in the
+plug-in. The performOK and performDefaults for this preference page use these
+methods to update the preference and reset the values in the list widget
+respectively. See Figure 3 for the Bad Words preference page.
+</p>
+<pre>/**
+ * Sets the contents of the nameEntry field to be the default
+ */
+protected void performDefaults() {
+ badWordList.setItems(BadWordCheckerPlugin.getDefault().getDefaultBadWordsPreference());
+}
+/**
+ * Saves the author name to the preference store.
+ */
+public boolean performOk() {
+ BadWordCheckerPlugin.getDefault().setBadWordsPreference(badWordList.getItems());
+ return super.performOk();
+}</pre>
+<p align="center"><img border="0" src="images/badwordpreference.gif" width="606" height="532">
+</p>
+<p align="center"><b>Figure 3</b>: Preference dialog showing Bad Words preference
+ page </p>
+<h2>Propagating Values With IPropertyChangeListener
+</h2>
+<p>Frequently a preference is
+used to set a value in another object or needs to be applied to an open editor
+or view. When this is required you can listen for these changes with an
+IPropertyChangeListener. IPropertyChangeListener is a class that is used to add a listener to an
+IPropertyStore so that the listener is informed whenever a change is made. Change
+notifications are issued whenever a preference is changed in the preference
+store with setValue(); this typically happens when the user hits OK or Apply in a
+preference dialog, or when a previously saved preference setting is imported.</p>
+<p>In the bad word checker example we have implemented a view that displays the
+bad words for a file highlighted in the selected Color (see attached code). This
+view has a IPropertyChangeListener defined on it that updates the display color
+when it changes (see <img border="0" src="images/tag_1.gif" width="24" height="13">).&nbsp;
+When the view is created it is added as an IPropertyChangeListener on the
+preference store in the init(IViewSite) method (see <img border="0" src="images/tag_2.gif" width="24" height="13">).
+We also remove it as a listener on the preference store when we dispose of it so
+that any further changes to the preference store do not try and refer to a
+disposed page (see <img border="0" src="images/tag_3.gif" width="24" height="13">).
+The init(IViewSite) method is defined on IViewPart and the dispose() method is
+defined on IWorkbenchPart.
+</p>
+<pre>
+<img border="0" src="images/tag_1.gif" width="24" height="13"> new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(BadWordCheckerPlugin.HIGHLIGHT_PREFERENCE)) {
+ //Update the colors by clearing the current color,
+ //updating the view and then disposing the old color.
+ Color oldForeground = foreground;
+ foreground = null;
+ setBadWordHighlights(text.getText());
+ oldForeground.dispose();
+ }
+ if (event.getProperty().equals(BadWordCheckerPlugin.BAD_WORDS_PREFERENCE))
+ //Only update the text if only the words have changed
+ setBadWordHighlights(text.getText());
+ }
+};</pre>
+
+<pre>
+<img border="0" src="images/tag_2.gif" width="24" height="13"> public void init(IViewSite site) throws PartInitException {
+ super.init(site);
+ site.getPage().addSelectionListener(...);
+ BadWordCheckerPlugin
+ .getDefault()
+ .getPreferenceStore()
+ .addPropertyChangeListener(preferenceListener);}
+</pre>
+<pre>
+<img border="0" src="images/tag_3.gif" width="24" height="13"> public void dispose() {
+ getSite().getPage().removeSelectionListener(...);
+ BadWordCheckerPlugin
+ .getDefault()
+ .getPreferenceStore()
+ .removePropertyChangeListener(preferenceListener);
+ if (foreground != null)
+ foreground.dispose();
+ super.dispose();
+}
+</pre>
+
+<h2>Importing and Exporting Preference Settings
+</h2>
+<p>As of Eclipse 2.0 there is now a facility to import and export your preferences so
+that you can reload them when you get a new workspace. This can be done by use
+of the Import and Export buttons on the preferences dialog. The currently set
+preferences are stored in a .epf file that you specify when you export. Any
+preference that is still set to it's default value will not be saved in this
+file. When you import from a .epf file any preferences defined in that file will
+be set to the value stored. Preferences not stored in the .epf file are not
+affected.
+</p>
+<p>If your preferences just
+use the preference store for storing and retrieving values then there is no more
+work to do to when writing your preferences as they will be saved and restored
+as part of the import and export support for preference stores. Should you need
+to have extra functionality executed when preferences are imported you can use
+an IPropertyChangeListener&nbsp;
+</p>
+
+<h2>Conclusions
+</h2>
+<p>In this article we have demonstrated how to use the preferences store and
+preferences pages provided by Eclipse to allow a plug-in to maintain and update
+preferences between Eclipse sessions and to import and export them using the
+preference dialog. By use of the preference store in
+conjunction with the preferences dialog and provided field editors a plug-in
+developer can quickly put together a user interface for managing preferences. To
+find out more about the preferences that Eclipse provides see the Platform
+Plug-in Developers Guide in the Help Perspective. The help information is in the
+Programmers Guide Preferences and Properties section.
+</p>
+<p>The full implementation of the example in this article can be found in <a href="preferences.zip">preferences.zip</a>.
+</p>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+
+</body>
+
+</html>
diff --git a/Article-Preferences/preferences.zip b/Article-Preferences/preferences.zip
new file mode 100644
index 0000000..e33f2ef
--- /dev/null
+++ b/Article-Preferences/preferences.zip
Binary files differ
diff --git a/Article-Properties-View/images/Idea.jpg b/Article-Properties-View/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Properties-View/images/Idea.jpg
Binary files differ
diff --git a/Article-Properties-View/images/default.jpg b/Article-Properties-View/images/default.jpg
new file mode 100644
index 0000000..fc05d47
--- /dev/null
+++ b/Article-Properties-View/images/default.jpg
Binary files differ
diff --git a/Article-Properties-View/images/linux_only.gif b/Article-Properties-View/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Properties-View/images/linux_only.gif
Binary files differ
diff --git a/Article-Properties-View/images/properties.jpg b/Article-Properties-View/images/properties.jpg
new file mode 100644
index 0000000..28db669
--- /dev/null
+++ b/Article-Properties-View/images/properties.jpg
Binary files differ
diff --git a/Article-Properties-View/images/tag_1.gif b/Article-Properties-View/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Properties-View/images/tag_1.gif
Binary files differ
diff --git a/Article-Properties-View/images/tag_2.gif b/Article-Properties-View/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Properties-View/images/tag_2.gif
Binary files differ
diff --git a/Article-Properties-View/images/tag_3.gif b/Article-Properties-View/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Properties-View/images/tag_3.gif
Binary files differ
diff --git a/Article-Properties-View/images/tag_4.gif b/Article-Properties-View/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Properties-View/images/tag_4.gif
Binary files differ
diff --git a/Article-Properties-View/images/tag_5.gif b/Article-Properties-View/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Properties-View/images/tag_5.gif
Binary files differ
diff --git a/Article-Properties-View/images/tag_6.gif b/Article-Properties-View/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Properties-View/images/tag_6.gif
Binary files differ
diff --git a/Article-Properties-View/images/tag_7.gif b/Article-Properties-View/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Properties-View/images/tag_7.gif
Binary files differ
diff --git a/Article-Properties-View/images/tag_a.jpg b/Article-Properties-View/images/tag_a.jpg
new file mode 100644
index 0000000..3728217
--- /dev/null
+++ b/Article-Properties-View/images/tag_a.jpg
Binary files differ
diff --git a/Article-Properties-View/images/tag_b.jpg b/Article-Properties-View/images/tag_b.jpg
new file mode 100644
index 0000000..a7903ad
--- /dev/null
+++ b/Article-Properties-View/images/tag_b.jpg
Binary files differ
diff --git a/Article-Properties-View/images/tag_c.jpg b/Article-Properties-View/images/tag_c.jpg
new file mode 100644
index 0000000..03516e7
--- /dev/null
+++ b/Article-Properties-View/images/tag_c.jpg
Binary files differ
diff --git a/Article-Properties-View/images/tag_d.jpg b/Article-Properties-View/images/tag_d.jpg
new file mode 100644
index 0000000..8c27fb5
--- /dev/null
+++ b/Article-Properties-View/images/tag_d.jpg
Binary files differ
diff --git a/Article-Properties-View/images/tag_e.jpg b/Article-Properties-View/images/tag_e.jpg
new file mode 100644
index 0000000..c28f7ce
--- /dev/null
+++ b/Article-Properties-View/images/tag_e.jpg
Binary files differ
diff --git a/Article-Properties-View/images/tag_f.jpg b/Article-Properties-View/images/tag_f.jpg
new file mode 100644
index 0000000..7d1538c
--- /dev/null
+++ b/Article-Properties-View/images/tag_f.jpg
Binary files differ
diff --git a/Article-Properties-View/images/tip.gif b/Article-Properties-View/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Properties-View/images/tip.gif
Binary files differ
diff --git a/Article-Properties-View/images/tryit.gif b/Article-Properties-View/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Properties-View/images/tryit.gif
Binary files differ
diff --git a/Article-Properties-View/images/win_only.gif b/Article-Properties-View/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Properties-View/images/win_only.gif
Binary files differ
diff --git a/Article-Properties-View/properties-view.html b/Article-Properties-View/properties-view.html
new file mode 100644
index 0000000..727d717
--- /dev/null
+++ b/Article-Properties-View/properties-view.html
@@ -0,0 +1,412 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Take control of your properties</title>
+<link rel="stylesheet" href="../default_style.css">
+</head>
+
+<body link="#0000ff" vlink="#800080">
+
+<div align="right">
+ &nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright © 2003
+ Broadvision Corp.</font>
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP" colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height="86" width="120" align="CENTER"></h1>
+</div>
+<h1 align="CENTER">Take control of your properties</h1>
+<blockquote>
+ <b>Summary</b><br>
+ The Eclipse workbench provides a properties view which is used to view (and/or
+ edit) properties of a selected item. In this article, you will learn how to
+ use the properties view to dynamically modify the properties of a GUI button.
+ <p><b>By Dicky Johan, Broadvision, dicky.johan@broadvision.com</b><br>
+ <font size="-1">May 20, 2003</font></p>
+</blockquote>
+<hr width="100%">
+<h2>Introduction</h2>
+<p>The Eclipse workbench provides a lot of views, but one of the highly
+extensible views is the properties view. It provides a way for you, as a plug-in
+developer, to display the properties of a selected item. The properties view can
+display read-only information, such as the properties of a file resource. Or it
+can display information that can be edited, such as the properties of an
+extension point in a plugin.xml file.</p>
+<p>The properties view can display properties for various kinds of items. An
+item may be a directory resource, a file resource, or an element within a
+resource (such as an extension in a plugin.xml file). The items may reside in
+different views within the Eclipse workbench, and the properties view can be
+triggered from different views or editors to display the properties of a
+selected item.</p>
+<p>In this article, I will show you how to control the different properties of a
+GUI resource using the properties view. Using a button as a sample GUI resource,
+I will create a button, a view containing that button, and a list of editable
+and complex properties. I will show how the button responses to changes of its
+properties thru the property view.</p>
+<h2>Installation</h2>
+<p>To run the sample, please unzip <a href="propertyviewsample.zip">propertyviewsample.zip</a>
+into your <i>eclipse</i> subdirectory. Restart eclipse as necessary.</p>
+<h2>Running the sample</h2>
+<p><img src="images/tryit.gif" width="61" height="13"> Switch to the Resource
+perspective, Window&gt;Open Perspective&gt;Resource. Next open the properties
+view, Window&gt;Show View&gt;Other... and select<br>
+Basic&gt;Properties. Now goto Go to Window&gt;Show View&gt;Other... and select
+&quot;Sample Category/Sample1 View&quot; and you should see the view being shown
+below.&nbsp;</p>
+<p>When you select the &quot;Button&quot; in the view, notice that the
+properties view is changed to display the current properties of the button. You
+can modify the properties and see how the button changes! Cool!</p>
+<p><img border="0" src="properties-view.jpg" width="486" height="220"></p>
+<p>Now the excitement is over, let's get on with the details!</p>
+<h2>Connecting our view to the Properties View</h2>
+<p>The properties view is designed to respond to workbench selection changes.
+The workbench selection is determined by the selection provider (implements <code>ISelectionProvider</code>)
+for the currently active workbench part (view or editor).</p>
+<p>Every workbench part has a <code>IWorkbenchPartSite</code>, and one can set
+the selection provider for this site. When I created our sample view, I
+instantiated a <code>ListViewer</code>, which implements <code>ISelectionProvider</code>.
+I pass this <code>ListViewer</code> to the <code>IWorkbenchPartSite</code>
+object via <img src="images/tag_1.gif" width="24" height="13"><code>setSelectionProvider</code>.
+This enables the property view to be informed of selection changes in our list
+when our view is the active workbench part.</p>
+<pre><font color="#4444cc"> // configure the viewer
+ viewer.setContentProvider(new ListContentProvider());
+ viewer.setLabelProvider(new LabelProvider() {
+ public String getText(Object element) {
+ return ((ButtonElement)element).getName();
+ }
+ });
+ viewer.setInput(input);
+ <img src="images/tag_1.gif" width="24" height="13">getSite().setSelectionProvider(viewer);
+</font></pre>
+<h2>Creating the IAdaptable item</h2>
+<p>When the properties view is notified of a workbench selection change, the
+selected item will be queried for a property source. There are two ways to
+provide a property source for a particular selection:</p>
+<ul>
+ <li>The selected item can implement the <code>IPropertySource</code> interface
+ and provide the properties.</li>
+ <li>The selected item can implement the <code>IAdaptable</code> interface and
+ return an <code>IPropertySource</code> object when <code>getAdapter</code>
+ is called.</li>
+</ul>
+<p>We will use the latter approach. The first thing we need to do is to create
+our own custom item. In this case, it is a element used to store a GUI button.</p>
+<pre><font color="#4444cc">public class ButtonElement implements <img src="images/tag_1.gif" width="24" height="13">IAdaptable {
+
+ private Button button;
+ private String name;
+
+ /**
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class adapter) {
+ if (adapter == IPropertySource.class) {
+ <img src="images/tag_2.gif" width="24" height="13">if (btnElPS == null) {
+ // cache the buttonelementpropertysource
+ btnElPS = new ButtonElementPropertySource(this,name);
+ }
+ return btnElPS;
+ }
+ return null;
+ }</font></pre>
+<p>Notice that this class implements <img src="images/tag_1.gif" width="24" height="13"><code>IAdaptable</code>,
+which is used to query for a property source. When <code>getAdapter</code> is
+called with the <code>IPropertySource.class</code> argument, it will create an
+instance of the class <img src="images/tag_2.gif" width="24" height="13"><code>ButtonElementPropertySource</code>
+that describes the button's properties. We cache this instance in the class for
+two reasons. One is for performance (since for every call, we are creating
+similar objects), and the other is for tracking property changes as you will see
+later.</p>
+<h2>Creating the Property Source object</h2>
+<p>The <code>ButtonElementPropertySource</code> class implements <code>IPropertySource</code>,
+which is an interface that provides a description of an item's properties. In
+our example, I am storing the button control within the element, and since I
+will be modifying the properties of the button in real time, I want to gain
+access to its handle within the <code>ButtonElementPropertySource</code> object.
+Thus <img src="images/tag_1.gif" width="24" height="13">the constructor of <code>ButtonElementPropertySource</code>
+takes a <code>ButtonElement</code> object. It also takes on a defaultText
+string, this is used for storing the default value of the button text.</p>
+<pre>
+<font color="#4444cc"> /**
+ * This class provides property sheet properties
+ * for ButtonElement.
+ */
+ public class ButtonElementPropertySource implements IPropertySource {
+
+ private static final String PROPERTY_FONT = &quot;mview.views.font&quot;;
+ private static final String PROPERTY_SIZE = &quot;mview.views.size&quot;;
+ private static final String PROPERTY_TEXT = &quot;mview.views.text&quot;;
+ private final Button button;
+ private final SizePropertySource sizePropertySource = new SizePropertySource();
+
+ private String defText;
+
+ private IPropertyDescriptor[] propertyDescriptors;
+
+ /**
+ * Creates a new ButtonElementPropertySource.
+ *
+ * @param element the element whose properties this instance represents
+ */
+ public <img src="images/tag_1.gif" width="24" height="13">ButtonElementPropertySource(ButtonElement element, String defaultText) {
+ button = element.getControl();
+ defText = defaultText;
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
+ */
+ public IPropertyDescriptor[] getPropertyDescriptors() {
+ if (propertyDescriptors == null) {
+ // Create a descriptor and set a category
+ PropertyDescriptor fontDescriptor = new FontDataPropertyDescriptor(PROPERTY_FONT, &quot;Font&quot;);
+ <img src="images/tag_2.gif" width="24" height="13">fontDescriptor.setCategory(&quot;Label&quot;);
+
+ PropertyDescriptor sizeDescriptor = new PropertyDescriptor(PROPERTY_SIZE, &quot;Size&quot;);
+ // set a custom label provider for a point
+ sizeDescriptor.setLabelProvider(new LabelProvider() {
+ public String getText(Object element) {
+ Point point = (Point)element;
+ StringBuffer buf = new StringBuffer();
+ buf.append(&quot;Height:&quot;);
+ buf.append(point.y);
+ buf.append(&quot; &quot;);
+ buf.append(&quot;Width:&quot;);
+ buf.append(point.x);
+ return buf.toString();
+ }
+ });
+ sizeDescriptor.setCategory(&quot;Button&quot;);
+
+ PropertyDescriptor textDescriptor = new TextPropertyDescriptor(PROPERTY_TEXT,&quot;Text&quot;);
+ textDescriptor.setCategory(&quot;Label&quot;);
+
+ <img src="images/tag_3.gif" width="24" height="13">propertyDescriptors = new IPropertyDescriptor[] {
+ fontDescriptor,
+ sizeDescriptor, // Read-only (instance of PropertyDescriptor)
+ textDescriptor};
+ }
+ return propertyDescriptors;
+ }</font></pre>
+<p>Every property needs to be described by a property descriptor. You can create
+your own custom property descriptor, I will show you an example of this later,
+or you can use some standard ones that are already included:</p>
+<ul>
+ <li><code>PropertyDescriptor</code> - read-only property</li>
+ <li><code>TextPropertyDescriptor </code>- edits with a <code>TextCellEditor</code></li>
+ <li><code>CheckboxPropertyDescriptor</code> - edits with a <code>CheckboxCellEditor</code></li>
+ <li><code>ComboBoxPropertyDescriptor </code>- edits with a <code>ComboBoxCellEditor</code></li>
+ <li><code>ColorPropertyDescriptor </code>- edits with a <code>ColorCellEditor</code></li>
+</ul>
+<p>Two property descriptors are categorized under <img src="images/tag_2.gif" width="24" height="13">
+&quot;Label&quot;, the other under &quot;Button&quot;. Notice how these
+categories show up in the properties view when the &quot;Show Categories&quot;
+button is pressed in the view's local toolbar. Altogether, I created three <img src="images/tag_3.gif" width="24" height="13">
+property descriptors.</p>
+<h2>Creating a custom property descriptor</h2>
+<p>It would be too boring to only display a button with a plain vanilla default
+font. I decided to spice it up by providing an editable font property. Checking
+out the list of default property descriptors, I cannot find any font related
+property descriptor. So, let's try to be a bit adventurous and create our own.</p>
+<pre><font color="#4444cc"> public class FontDataPropertyDescriptor extends PropertyDescriptor {
+ /**
+ * Creates a property descriptor with the given id and display name.
+ *
+ * @param id the id of the property
+ * @param displayName the name to display for the property
+ */
+ public FontPropertyDescriptor(Object id, String displayName) {
+ super(id, displayName);
+ setLabelProvider(new FontDataLabelProvider());
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#createPropertyEditor(Composite)
+ */
+ public CellEditor createPropertyEditor(Composite parent) {
+ CellEditor editor = <img src="images/tag_1.gif" width="24" height="13">new FontDataDialogCellEditor(parent);
+ if (getValidator() != null)
+ editor.setValidator(getValidator());
+ return editor;
+ }
+ }</font></pre>
+<p>I derive the <code>FontDataPropertyDescriptor</code> class from the default <code>PropertyDescriptor</code>.
+When <code>createPropertyEditor</code> is called, I need to instantiate our own <img src="images/tag_1.gif" width="24" height="13"><code>FontDataDialogCellEditor</code>.</p>
+<p>The <code>FontDialogCellEditor </code>needs to instantiate a dialog, and thus
+behaves like a <code>DialogCellEditor</code>. So, I derive from it.</p>
+<pre><font color="#4444cc"> public class FontDataDialogCellEditor extends DialogCellEditor {
+ /**
+ * Creates a new Font dialog cell editor parented under the given control.
+ * The cell editor value is &lt;code&gt;null&lt;/code&gt; initially, and has no
+ * validator.
+ *
+ * @param parent the parent control
+ */
+ protected FontDataDialogCellEditor(Composite parent) {
+ super(parent);
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.DialogCellEditor#openDialogBox(Control)
+ */
+ protected Object openDialogBox(Control cellEditorWindow) {
+ <img src="images/tag_2.gif" width="24" height="13">FontDialog ftDialog = new FontDialog(cellEditorWindow.getShell());
+ String value = (String) getValue();
+
+ if (getValue() != null) {
+ ftDialog.setFontData((FontData)getValue());
+ }
+ FontData fData = ftDialog.open();
+
+ if (fData != null) {
+ <img src="images/tag_3.gif" width="24" height="13">return fData;
+ }
+ return getValue();
+ }
+ }</font></pre>
+Exploring the rich UI functionality provided by Eclipse, I find out that SWT
+provides the system <code>FontDialog</code>. How handy! So, I just use that to <img src="images/tag_2.gif" width="24" height="13">instantiate
+our font dialog. SWT uses a <code>FontData</code> to represent the font and this
+is what we use as the <img src="images/tag_3.gif" width="24" height="13">property's
+value. After setting the font, I need to present its value as a human readable
+string in the properties view. A <code>FontDataLabelProvider</code> is used for
+this purpose. Using a few simple classes, I have created a custom property
+descriptor.
+<h2>Implementing complex property descriptors</h2>
+<p>From time to time, we encounter properties that are quite complex, i.e. their
+values are not simple objects such as strings or integers. As an example,
+consider the size property of a <code>Button</code>. It expects and returns a <code>Point</code>
+object. But if you look closer, a point object is really comprised of two simple
+integer values. Thus we can describe the size using a <code>SizePropertySource</code>
+which has &quot;width&quot; and &quot;height&quot; properties.</p>
+<pre><font color="#4444cc"> /**
+ * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(Object)
+ */
+ public Object getPropertyValue(Object name) {
+ ...
+ if (name.equals(PROPERTY_SIZE)) {
+ // By returning a property source for the value, this property
+ // will have &quot;child properties&quot; in the view.
+ // These child properties are determined by the property source
+ // we return here
+ sizePropertySource.setPoint(button.getSize());
+ <img src="images/tag_1.gif" width="24" height="13">return sizePropertySource;
+ }
+ ...
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(Object, Object)
+ */
+ public void setPropertyValue(Object name, Object value) {
+ ...
+ if (name.equals(PROPERTY_SIZE)) {
+ // We returned a SizePropertySource as the value for PROPERTY_SIZE
+ // The SizePropertySource's editValue will be set as the value
+ // for PROPERTY_SIZE here
+ <img src="images/tag_2.gif" width="24" height="13">button.setSize((Point)value);
+ }
+ ...
+ }</font>
+</pre>
+<p>The Eclipse workbench supports the notion of nested properties (good job in
+thinking ahead!). When <code>getProperty</code> is called on the <code>ButtonElementPropertySource</code>,
+we return an <img src="images/tag_1.gif" width="24" height="13"><code>IPropertySource</code>
+object instead of a value. In this case, I created the <code>SizePropertySource</code>
+class for describing the size property. <code>SizePropertySource</code> is
+similar to <code>ButtonElementPropertySource</code>, so I would not elaborate on
+it further.&nbsp;Note that when an <code>IPropertySource</code> is used as a
+property value, its <code>getEditValue</code> is used by the properties view to <img src="images/tag_2.gif" width="24" height="13">set
+the property value.</p>
+<h2>Controlling the button</h2>
+<p>In order to update the button once a property has been changed, I make a call
+to the button within the <code>setPropertyValue</code> function of the <code>ButtonElementPropertySource</code>
+class. Since I hold the <code>ButtonElement</code> handle within the <code>ButtonElementPropertySource</code>
+object, I can set the properties of the element's button control directly.</p>
+<h2>Default Properties</h2>
+<p>The IPropertySource interface also provides a means of implementing default
+values for properties. This is accomplished via two methods on the
+IPropertySource interface: <code>isPropertySet</code> and <code>resetPropertyValue</code>.
+In the diagram shown below, there is a default button that the user can press.
+If the function &lt;resetPropertyValue&gt; is implemented, it will cause the the
+property value to reset to its default.</p>
+<p><img src="images/default.jpg" width="165" height="60"></p>
+<p>Whenever the Default button is clicked, the isPropertySet will be called for
+the property that is being selected. If isPropertySet returns true, then it will
+call resetPropertyValue to reset the property to a specified default value. In
+the sample code that is enclosed, I only show how to reset the text property,
+but you can apply the same concept to the other properties.</p>
+<p>I store the default Name for the button text in a member variable of the <code>ButtonElementPropertySource</code>
+class. The default Name is <font color="#4444cc"><img src="images/tag_1.gif" width="24" height="13"></font>set
+during construction time. In the <code>isPropertySet</code> call, <font color="#4444cc"><img src="images/tag_2.gif" width="24" height="13"></font>a
+check is made between the current text property and the default text property.
+If they are different, then the <code>resetPropertyValue</code> method will be
+invoked, and in there, I made the call to <code><font color="#4444cc"><img src="images/tag_3.gif" width="24" height="13"></font>setPropertyValue</code>
+method with the default text value.</p>
+<pre><font color="#4444cc">/**
+ * Creates a new ButtonElementPropertySource.
+ *
+ * @param element the element whose properties this instance represents
+ * @param defaultText the default text of the button
+ */
+ public ButtonElementPropertySource(ButtonElement element, String defaultText) {
+ btnEl = element;
+ button = element.getControl();
+ <img src="images/tag_1.gif" width="24" height="13">defText = defaultText;
+ }
+
+...
+
+/**
+ * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(Object)
+ */
+
+ public boolean isPropertySet(Object id) {
+ if (id.equals(PROPERTY_TEXT)) {
+ <img src="images/tag_2.gif" width="24" height="13"> String curName = (String)getPropertyValue(id);
+ return !curName.equals(defText);
+ }
+ // other properties are not supported currently
+ return false;
+ }
+
+/**
+ * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(Object)
+ */
+
+ public void resetPropertyValue(Object id) {
+ // tracks the text property only
+ if (id.equals(PROPERTY_TEXT)) {
+ <img src="images/tag_3.gif" width="24" height="13">setPropertyValue(id,defText);
+ }
+ }</font></pre>
+<h2>Summary</h2>
+<p>I have discussed how to register a workbench selection provider so that a
+selection will be passed to the properties view. I demonstrated creating a
+property source and its property descriptors. I showed how a descriptor supports
+the display and editing of a property.</p>
+<p>There are several other advanced properties view topics that have not been
+discussed. For example, the properties view supports having more than one item
+selected and showing only those properties which are common to all the selected
+items. The workbench also provides a mechanism for workbench parts to provide
+their own custom &quot;page&quot; for the properties view (by asking the part
+for an <code>IPropertySheetPage</code> via <code>getAdapter</code>). Such a
+custom page can be an instance of <code>PropertySheetPage</code> configured with
+an <code>IPropertySourceProvider</code> or a custom root <code>IPropertySheetEntry</code>
+or the custom page can be an independent implementation of <code>IPropertySheetPage</code>.
+This mechanism allows the properties view to work with non-<code>IPropertySource</code>
+items.&nbsp;</p>
+<p>Now that you have discovered some of the magic of the properties view, I hope
+that you can make good use of it.</p>
+</body>
+
+</html>
diff --git a/Article-Properties-View/properties-view.jpg b/Article-Properties-View/properties-view.jpg
new file mode 100644
index 0000000..390bdcc
--- /dev/null
+++ b/Article-Properties-View/properties-view.jpg
Binary files differ
diff --git a/Article-Properties-View/propertyviewsample.zip b/Article-Properties-View/propertyviewsample.zip
new file mode 100644
index 0000000..2234947
--- /dev/null
+++ b/Article-Properties-View/propertyviewsample.zip
Binary files differ
diff --git a/Article-RCP-1/images/spin.png b/Article-RCP-1/images/spin.png
new file mode 100644
index 0000000..a7314c9
--- /dev/null
+++ b/Article-RCP-1/images/spin.png
Binary files differ
diff --git a/Article-RCP-1/part1.zip b/Article-RCP-1/part1.zip
new file mode 100644
index 0000000..ccd8e33
--- /dev/null
+++ b/Article-RCP-1/part1.zip
Binary files differ
diff --git a/Article-RCP-1/tutorial1.html b/Article-RCP-1/tutorial1.html
new file mode 100644
index 0000000..4444163
--- /dev/null
+++ b/Article-RCP-1/tutorial1.html
@@ -0,0 +1,382 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+<title>Rich Client Platform</title>
+<link href="../default_style.css" rel=stylesheet>
+</head>
+
+<body>
+
+<div align="right">
+ <font face="Times New Roman, Times, serif" size="2">Copyright © 2003-2005 Ed
+ Burnette.</font>
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tbody>
+ <tr>
+ <td align="left" valign="top" colspan="2" bgcolor="#0080c0"><b><font face="Arial,Helvetica"><font color="#ffffff">Eclipse
+ Article</font></font></b></td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+<div align="left">
+ <h1 title="RCP Tutorial"><img src="../images/Idea.jpg" align="middle" width="120" height="86"></h1>
+</div>
+<h1 align="center">Rich Client Tutorial Part 1</h1>
+<p class="summary">The Rich Client Platform (RCP) is an exciting new way to
+build Java applications that can compete with native applications on any
+platform. This tutorial is designed to get you started building RCP applications
+quickly. It has been updated for Eclipse 3.1.</p>
+<p><b>By Ed Burnette, SAS</b><br>
+<font size="-1">July 28, 2004 (Updated July 2005 for Eclipse 3.1)</font></p>
+<hr width="100%">
+<h2>Introduction</h2>
+<p>Try this experiment: Show Eclipse to some friends or co-workers who haven't
+seen it before and ask them to guess what language it is written in. Chances
+are, they'll guess VB, C++, or C#, because those languages are used most often
+for high quality client side applications. Then watch the look on their faces
+when you tell them it was created in Java, especially if they are Java
+programmers.</p>
+<p>Because of its unique open source license, you can use the technologies that
+went into Eclipse to create your own commercial quality programs.
+Before version 3.0, this was possible but difficult, especially when you wanted
+to heavily customize the menus, layouts, and other user interface elements. That
+was because the &quot;IDE-ness&quot; of Eclipse was hard-wired into it. Version
+3.0 introduced the Rich Client Platform (RCP), which is basically a refactoring of the
+fundamental parts of Eclipse's UI, allowing it to be used for non-IDE
+applications.
+Version 3.1 updated RCP with new capabilities, and, most importantly,
+new tooling support to make it easier to create than before.</p>
+<p>If you want to cut to the chase and look at the code for this part
+you can find it in the <a href="part1.zip">accompanying zip file</a>.
+Otherwise, let's take a look at how to construct
+an RCP application.</p>
+
+<h2><a name="section_1"></a> Getting started</h2>
+<p>RCP applications are based on the familiar Eclipse plug-in architecture, (if
+it's not familiar to you, see the references section). Therefore, you'll need to
+create a plug-in to be your main program.
+Eclipse's Plug-in Development Environment (PDE) provides a number of
+wizards and editors that take some of the drudgery out of the process.
+Select <b>File &gt; New &gt; Project &gt; Plug-in
+Development &gt; Plug-in Project</b> to bring up the Plug-in Project wizard. On the
+subsequent pages, enter a Project name such as <b>org.eclipse.ui.tutorials.rcp.part1</b>,
+indicate you want a Java project, select the version of Eclipse you're targetting,
+and enable the option to Create an OSGi bundle manifest.
+Then click Next.
+</p>
+<p>
+<img src="../images/note.gif" alt="Note: " width="62" height="13">
+Beginning in Eclipse 3.1 you will get best results by using the OSGi bundle manifest.
+In contrast to previous versions, this is now the default.
+</p>
+
+<p>
+In the next page of the Wizard you can change the Plug-in ID and other
+parameters.
+Of particular importance is the question, "Would you like to create a
+rich client application?".
+Select <b>Yes</b>.
+The generated plug-in class is optional but for this example
+just leave all the other options at their default values.
+Click Next to continue.
+</p>
+
+<p>
+Starting with Eclipse 3.1, several templates have been provided
+to make creating an RCP application a breeze.
+We'll use the simplest one available and build up from there.
+Make sure the option to Create a plug-in using one of the templates is enabled,
+then select the Hello RCP template.
+This is RCP's equivalent of "Hello, world".
+Click Finish to accept all the defaults and generate the project.
+Eclipse will open the Plug-in Manifest Editor.
+The Plug-in Manifest editor puts a friendly
+face on the various configuration files that control your RCP application.
+</p>
+
+<p>
+<img src="../images/note.gif" alt="Note: " width="62" height="13">
+If you get a dialog asking if Eclipse can switch to the Plug-in Development
+Perspective click Remember my decision and select Yes (this is optional).
+</p>
+
+<h2>Taking it for a spin</h2>
+<p>
+Trying out RCP applications used to be somewhat tedious.
+You had to create a custom launch configuration,
+enter the right application name,
+and tweak the plug-ins that were included.
+Thankfully the PDE keeps track of all this now.
+All you have to do is click on the
+Launch an Eclipse Application button in the
+Plug-in Manifest editor's Overview page.
+You should see a bare-bones Workbench start up (see Figure 1).
+</p>
+
+<img src="images/spin.png">
+<p><b>Figure 1. World's simplest RCP application.
+</b></p>
+
+<h2>Creating a feature</h2>
+<p>
+In Eclipse, features are just collections of plug-ins.
+Features are optional but recommended because you'll need
+one if you want to later use Eclipse's Automatic Update
+Manager capabilities, or if you want to export your application with JNLP.
+To create a feature, select <b>File &gt; New &gt; Project &gt; Plug-in
+Development &gt; Feature Project</b>.
+The convention is to use the same name as your plug-in project with
+"-feature" appended, so call the feature
+<b>org.eclipse.ui.tutorials.rcp.part1-feature</b>.
+Click Next to get to the Feature Properties page,
+and Next again to get to the Referenced Plug-ins page.
+Put a check mark next to org.eclipse.ui.tutorials.rcp.part1 .
+Click Finish to generate the feature.
+</p>
+
+<h2>Making it a product</h2>
+<p>
+In Eclipse terms a product is everything that goes with your
+application, including all the other plug-ins it depends on,
+a command to run the application (called the native launcher),
+and any branding (icons, etc.) that make your application distinctive.
+Although as we've just seen you can run a RCP application
+without defining a product,
+having one makes it a whole lot easier to run the application
+outside of Eclipse.
+This is one of the major innovations that Eclipse 3.1
+brought to RCP development.
+</p>
+
+<p>
+Some of the more complicated RCP templates already come with a
+product defined, for example the one called "RCP Application with an Intro"
+and "RCP Mail".
+More templates will likely be added with each release so this list
+may change.
+The Hello RCP template does not so we'll have to make one.
+</p>
+<p>
+In order to create a product you first have to add a
+product configuration file to the project.
+Right click on the plug-in project
+and select <b>New &gt; Product Configuration</b>.
+Then enter a file name for this new configuration file, such as
+<b>part1.product</b>.
+Select the option to Use a launch configuration,
+and select <b>Eclipse Application</b> from the list.
+(Note if you've been doing other plug-in development in
+the current workspace you may see a different configuration
+name here. Pick the one associated with the RCP
+plug-in you ran earlier.)
+Then click Finish.
+The Product Configuration editor will open.
+This editor lets you control
+exactly what makes up your product including all its plug-ins
+and branding elements.
+</p>
+
+<p>
+In the Overview page,
+type in the Product Name, for example <b>RCP Tutorial 1</b>.
+Select the option that says This project configuration is based on features.
+Then select the New... button to create a new product.
+Type in or browse to the defining plug-in (<b>org.eclipse.ui.tutorials.rcp.part1</b>).
+Enter a Product ID such as <b>product</b>,
+and for the Product Application select
+<b>org.eclipse.ui.tutorials.rcp.part1.application</b>.
+Click Finish to define the product.
+</p>
+
+<p>
+<img src="../images/note.gif" alt="Note: " width="62" height="13">
+In Eclipse 3.1 if you create the product before filling in the
+Product Name you may see an error appear in the Problems view.
+The error will go away when you Synchronize (see below).
+This is a known bug that will be fixed in future versions.
+</p>
+
+<p>
+Back in the Product Configuration editor's Overview page,
+Click on the product configuration link or on the tab for the Configuration page
+and add both your feature (org.eclipse.ui.tutorials.rcp.part1_feature) and
+the RCP feature (org.eclipse.rcp).
+Then go back to the Overview page and
+press <b>Ctrl+S</b> or <b>File &gt; Save</b> to save
+your work.
+</p>
+
+<p>
+<img src="../images/tip.gif" alt="Tip: " width="62" height="13">
+If your application needs to reference plug-ins outside of the
+basic RCP plug-ins, then you'll need to either include them in your
+feature or make up a new feature to contain them.
+</p>
+
+
+<p>
+At this point you should test out the product to make sure
+it runs correctly.
+In the Testing section of the Overview page, click Synchronize
+then click on Launch the product.
+If all goes well, the application should start up just like before.
+</p>
+
+<h2>Running it outside of Eclipse</h2>
+<p>The whole point of all this is to be able to run stand-alone applications
+without the user having to know anything about the Java and Eclipse code being
+used under the covers. For a real application you may want to provide
+a self-contained executable generated by an install program like InstallShield.
+That's really beyond the scope of this article though, so we'll do something
+simpler.</p>
+
+<p>We need to create a simplified version of the Eclipse install directory
+because the Eclipse plug-in loader expects things to be in a certain layout.
+This directory has to contain the native launcher program,
+config files, and all the features and plug-ins required by the product.
+Thankfully, we've given the PDE enough information that it can
+put all this together for us now.
+</p>
+
+<p>
+In the Exporting section of the Product Configuration editor
+(not the Plug-in Manifest editor),
+click the link to open the Eclipse product export wizard.
+Change the root directory to something else like <b>RcpTutorial1</b>.
+Then select the option to deploy into a Directory, and
+enter a directory path to a temporary (scratch) area
+such as <b>C:\Deploy</b>.
+Check the option to Include source code if you're building an open source project.
+Press Finish to build and export the program.
+</p>
+
+<p>
+The application is now ready to run outside Eclipse.
+When you're
+done you should have a structure that looks like this:</p>
+<pre>
+ RcpTutorial1
+ | .eclipseproduct
+ | eclipse.exe
+ | startup.jar
+ +--- configuration
+ | | config.ini
+ +--- plugins
+ | | org.eclipse.core.commands_3.1.0.jar
+ | | org.eclipse.core.expressions_3.1.0.jar
+ | | org.eclipse.core.runtime_3.1.0.jar
+ | | org.eclipse.help_3.1.0.jar
+ | | org.eclipse.jface_3.1.0.jar
+ | | org.eclipse.osgi_3.1.0.jar
+ | | org.eclipse.rcp_3.1.0.jar
+ | | org.eclipse.swt.win32.win32.x86_3.1.0.jar
+ | | org.eclipse.swt_3.1.0.jar
+ | | <b>org.eclipse.ui.tutorials.rcp.part1_1.0.0.jar</b>
+ | | org.eclipse.ui.workbench_3.1.0.jar
+ | | org.eclipse.ui_3.1.0.jar
+ | | org.eclipse.update.configurator_3.1.0.jar
+ +--- features
+ +--- org.eclipse.ui.tutorials.rcp.part1_feature_1.0.0
+ +--- org.eclipse.rcp_3.1.0
+</pre>
+
+<p>
+<img src="../images/note.gif" alt="Note: " width="62" height="13">
+Starting in Eclipse 3.1 the recommended format for plug-ins is
+a jar file. Among other things this saves disk space in
+the deployed application.
+</p>
+
+<p>
+<img src="../images/tip.gif" alt="Tip: " width="62" height="13">
+Previous versions of this tutorial recommended using a batch file
+or shell script to invoke your RCP program.
+It turns out this is a bad idea because you will not be able to
+fully brand your application later on.
+For example, you won't be able to add a splash screen.
+So just stick with the native launcher.
+</p>
+
+<p>
+Give it a try!
+Execute the native launcher outside Eclipse and
+watch the application come up.
+The name of the launcher ("eclipse" by default) is controlled
+by branding options in the product configuration.
+</p>
+
+
+<h2>Troubleshooting</h2>
+<p>
+After I wrote the original version of this tutorial I started getting
+mail from people who couldn't run it for one reason or another.
+Much of this feedback went into the design of new versions of
+the PDE so that information is now obsolete.
+Therefore I'm leaving the troubleshooting section blank for now.
+If you have any problems running your application let me know
+and I'll add the solution here for the next person to see.
+</p>
+
+<h2>Compatibility and migration</h2>
+<p>
+If you are migrating a plug-in from version 2.1 to version 3.1
+there are number of issues covered in the on-line documentation
+that you need to be aware of.
+If you're making the smaller step from 3.0 to 3.1, the number of
+differences is much smaller.
+See the References section for more information.
+</p>
+<p>
+<img src="../images/tip.gif" alt="Tip: " width="62" height="13">
+One word of advice: be careful not to duplicate any information
+in both plug-in.xml and MANIFEST.MF.
+Typically this would not occur unless you are converting an older
+plug-in that did not use MANIFEST.MF into one that does,
+and even then only if you are editing the files by hand instead of
+going through the PDE.
+</p>
+
+<h2>Conclusion</h2>
+<p>In part 1 of this tutorial, we looked at what is necessary to create a
+bare-bones Rich Client application.
+The next part will delve into the classes created by the
+wizards such as the WorkbenchAdvisor class.
+All the sample code for this part may be found in the
+<a href="part1.zip">accompanying zip file</a>.
+</p>
+
+<h2>References</h2>
+<a href="../Article-RCP-2/tutorial2.html"> RCP Tutorial Part 2</a><br>
+<a href="../Article-RCP-3/tutorial3.html"> RCP Tutorial Part 3</a><br>
+<a href="http://www.eclipse.org/rcp" target="_blank">
+Eclipse Rich Client Platform</a><br>
+<a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.ui.examples.rcp.browser/readme.html" target="_blank">RCP Browser example
+(project org.eclipse.ui.examples.rcp.browser)</a><br>
+<a href="../Article-PDE-does-plugins/PDE-intro.html">PDE Does Plug-ins</a><br>
+<a href="../Article-Internationalization/how2I18n.html">How to Internationalize
+your Eclipse Plug-in</a><br>
+<a href="../Article-Plug-in-architecture/plugin_architecture.html">Notes on the
+Eclipse Plug-in Architecture</a><br>
+<a href="http://help.eclipse.org/help31/topic/org.eclipse.platform.doc.isv/porting/eclipse_3_1_porting_guide.html" target="_blank">
+Plug-in Migration Guide: Migrating to 3.1 from 3.0</a><br>
+<a href="http://help.eclipse.org/help31/topic/org.eclipse.platform.doc.isv/porting/eclipse_3_0_porting_guide.html" target="_blank">
+Plug-in Migration Guide: Migrating to 3.0 from 2.1</a><br>
+
+<p><small>ref: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=104146">bug
+104146</a></small></p>
+
+<p><small>IBM is trademark of International Business Machines Corporation in the
+United States, other countries, or both.</small></p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or
+registered trademarks of Sun Microsystems, Inc. in the United States, other
+countries, or both.</small></p>
+<p><small>Microsoft and Windows are trademarks of Microsoft Corporation in the
+United States, other countries, or both.</small></p>
+<p><small>Other company, product, and service names may be trademarks or service
+marks of others.</small></p>
+
+</body>
+
+</html>
diff --git a/Article-RCP-2/images/manifest-editor-overview.png b/Article-RCP-2/images/manifest-editor-overview.png
new file mode 100644
index 0000000..10cedfc
--- /dev/null
+++ b/Article-RCP-2/images/manifest-editor-overview.png
Binary files differ
diff --git a/Article-RCP-2/part2.zip b/Article-RCP-2/part2.zip
new file mode 100644
index 0000000..8e7366b
--- /dev/null
+++ b/Article-RCP-2/part2.zip
Binary files differ
diff --git a/Article-RCP-2/tutorial2.html b/Article-RCP-2/tutorial2.html
new file mode 100644
index 0000000..7d5a581
--- /dev/null
+++ b/Article-RCP-2/tutorial2.html
@@ -0,0 +1,918 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<!-- ======================================================== -->
+<!-- = Java Sourcecode to HTML automatically converted code = -->
+<!-- = Java2Html Converter V4.1 2004 by Markus Gebhard markus@jave.de = -->
+<!-- = Further information: http://www.java2html.de = -->
+<!-- xhtml format used, bugs in 4.1 fixed by hand/ebb -->
+<head>
+<title>Rich Client Platform</title>
+<link href="../default_style.css" rel="stylesheet">
+
+<style type="text/css">
+td.java, td.java-ln {vertical-align:top;}
+tt.java, tt.java-ln, pre.java, pre.java-ln {line-height:1em; margin-bottom:0em;}
+td.java-ln { text-align:right; }
+tt.java-ln, pre.java-ln { color:#888888 }
+/* UNDEFINED */ font.java90 { font-size: 10pt; color:#ff6100; }
+/* CODE */ font.java10 { font-size: 10pt; color:#000000; }
+/* CODE_KEYWORD */ font.java4 { font-size: 10pt; color:#7f0055; font-weight:bold; }
+/* CODE_TYPE */ font.java9 { font-size: 10pt; color:#7f0055;}
+/* QUOTE */ font.java5 { font-size: 10pt; color:#2a00ff; }
+/* COMMENT_LINE */ font.java3 { font-size: 10pt; color:#3f7f5f; font-style:italic; }
+/* COMMENT_BLOCK */ font.java2 { font-size: 10pt; color:#3f7f5f; font-style:italic; }
+/* COMMENT_JAVADOC */ font.java14 { font-size: 10pt; color:#3f5fbf; font-style:italic; }
+/* COMMENT_KEYWORD */ font.java11 { font-size: 10pt; color:#7f9fbf; font-style:italic; font-weight:bold; }
+/* EMPTY */ font.java99 {}
+/* NUM_CONSTANT */ font.java910 { font-size: 10pt; color:#990000; }
+/* CHAR_CONSTANT */ font.java911 { font-size: 10pt; color:#990000; }
+/* PARENTHESIS */ font.java8 { font-size: 10pt; color:#000000; font-style:bold; }
+</style>
+</head>
+
+<body>
+
+<div align="right"><font face="Times New Roman, Times, serif" size="2">Copyright
+© 2004-2005 Ed Burnette.</font>
+<table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tbody>
+ <tr>
+ <td align="left" valign="top" colspan="2" bgcolor="#0080c0"><b><font
+ face="Arial,Helvetica"><font color="#ffffff">Eclipse Article</font></font></b></td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<div align="left">
+<h1 title="RCP Tutorial"><img src="../images/Idea.jpg" align="middle"
+ width="120" height="86" alt=""></h1>
+</div>
+<h1 align="center">Rich Client Tutorial Part 2</h1>
+<p class="summary">The Rich Client Platform (RCP) allows you to build
+Java applications that can compete with native applications on any
+platform. Part 1 of the tutorial introduced you to the platform and the
+steps used to build the smallest possible RCP program. In part 2 we'll
+look at what we did in more detail and introduce some of the
+configuration classes that let you take control of much of the layout
+and functionality of an RCP application. This part has been updated for
+Eclipse 3.1.</p>
+<p><b>By Ed Burnette, SAS</b><br>
+<font size="-1">August 9, 2004 (Updated November 21, 2005 for Eclipse
+3.1)<br>
+</font></p>
+<hr width="100%">
+
+<h2>Introduction</h2>
+<p>In early versions of Eclipse, many functions of the IDE were
+hard-wired into the code. These included the name and location of the
+File menu, the title of the Workbench Window, and the existence of the
+status bar. This was fine for the IDE but when people started to use
+Eclipse as a basis for non-IDE programs, sometimes these things didn't
+make sense. Although all the source code was provided, it was
+inconvenient to find the right places that had to be changed.</p>
+<p>So, beginning in Eclipse 3.0, the designers refactored the API to
+make these and other hard-wired aspects of the user interface
+controllable through public API. Subsequent releases have fine tuned
+that API and provided tooling in the Plug-in Development Environment
+(PDE) to lower the barriers to getting started using it. However, you'll
+eventually need to look behind the PDE wizards and editors to really
+understand what is going on.</p>
+<p>In this part we'll examine the code and configuration files created
+in Part 1 of the tutorial. To keep the parts separate I've recreated the
+examples for each part under a different name. All the sample code for
+Part 2 may be found in the <a href="part2.zip">part2.zip archive file</a>.
+</p>
+
+<p><img src="../images/note.gif" alt="Note: " width="62" height="13"> If
+you're following along with this tutorial in Eclipse and you're thinking
+of just renaming your old project, I don't recommend it. In Eclipse 3.1,
+Refactor &gt; Rename does not work well on plug-in projects due to all
+the internal references in XML files and strings that don't participate.
+Hopefully this will be fixed in a future release.</p>
+
+<p>Before we go any further let's clear up some possible confusion about
+the relationship between Applications, Workbenches, and Workbench
+Windows.</p>
+
+<h2>Applications, Workbenches, and Workbench Windows</h2>
+<p>The Application is a class you create that acts as your RCP program's
+main routine. You can think of it as the controller for the program.
+Just like the controller in a Model2 architecture, it is short and sweet
+and doesn't change significantly for different projects. All it does is
+create a Workbench and attach another class called a Workbench Advisor
+to it (Workbench Advisors will be covered more later).</p>
+<p>The Workbench is declared and maintained for you as part of the RCP
+framework. There is only one Workbench but it can have more than one
+visible top-level Workbench Window. For example, in the Eclipse IDE,
+when you first start Eclipse you will see one Workbench Window, but if
+you select <b>Window &gt; New Window</b> a second window pops up -- two
+Workbench Windows, but only one Workbench.</p>
+
+<p>Ok, now that that's out of the way, let's see what those PDE wizards
+did for us, starting with the plug-in manifest.</p>
+
+<h2>Plug-in manifest</h2>
+<p>The plug-in manifest ties all the code and resources together. When
+you first create a plug-in, Eclipse will create and open the manifest
+for you automatically. The manifest is split into two files: MANIFEST.MF
+and plugin.xml. PDE provides a fancy editor to modify the options stored
+in these files (see Figure 1) but also allows you to edit the source
+directly.</p>
+
+<img src="images/manifest-editor-overview.png" alt="">
+<p><b> Figure 1. The plug-in manifest editor provides a single interface
+for editing the manifest and related files. The tabs along the bottom of
+the editor access all the different sections in the GUI or the raw text
+files.</b></p>
+
+
+<h3>MANIFEST.MF</h3>
+<p>The OSGi bundle manifest is stored in MANIFEST.MF. OSGi is the name
+of a standard that Eclipse uses for dynamically loading plug-ins (see
+refererences). Listing 1 shows the OSGi bundle manifest generated by the
+plug-in wizard. Everything in this file can be edited by the Manifest
+editor, so there should be no need to edit it by hand. However if you
+need to, just double-click it in the Package Explorer to bring up the
+Manifest editor, then click on the MANIFEST.MF tab in the editor to see
+and modify the source.</p>
+
+<p><img src="../images/note.gif" alt="Note: " width="62" height="13">
+For backwards compatability with Eclipse 2.1, Eclipse will recognize and
+load plug-ins that do not use MANIFEST.MF. However, this incurs a small
+performance penalty and is not recommended for plug-ins targeting
+Eclipse 3.0 and later.</p>
+
+<p><b>Listing 1. MANIFEST.MF </b></p>
+
+<pre>
+Manifest-Version: <font class="java5">1.0</font>
+Bundle-ManifestVersion: <font class="java5">2</font>
+Bundle-Name: <font class="java5">Part2 Plug-in</font>
+Bundle-SymbolicName: <font class="java5">org.eclipse.ui.tutorials.rcp.part2; singleton:=true</font>
+Bundle-Version: <font class="java5">1.0.0</font>
+Bundle-Activator: <font class="java5">org.eclipse.ui.tutorials.rcp.part2.Part2Plugin</font>
+Bundle-Localization: <font class="java5">plugin</font>
+Require-Bundle: <font class="java5">org.eclipse.ui,
+ org.eclipse.core.runtime</font>
+Eclipse-AutoStart: <font class="java5">true</font>
+</pre>
+
+<h3>plugin.xml</h3>
+<p>The Eclipse extension manifest is called plugin.xml. It's used for
+defining and using Eclipse extension points, so if you're not using
+extension points then this file may be omitted. Extension points are the
+fundamental way that Eclipse plug-ins are tied together so if you're not
+familiar with them see one of the articles in the Reference section.
+Listing 2 shows the plugin.xml file created by the PDE wizard.</p>
+
+<p><b>Listing 2. plugin.xml </b></p>
+<pre>
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;?eclipse version="3.0"?&gt;
+&lt;plugin&gt;
+
+ &lt;extension
+ id=<font class="java5">"application"</font>
+ point=<font class="java5">"org.eclipse.core.runtime.applications"</font>&gt;
+ &lt;application&gt;
+ &lt;run
+ class=<font class="java5">"org.eclipse.ui.tutorials.rcp.part2.Application"</font>&gt;
+ &lt;/run&gt;
+ &lt;/application&gt;
+ &lt;/extension&gt;
+ &lt;extension
+ point=<font class="java5">"org.eclipse.ui.perspectives"</font>&gt;
+ &lt;perspective
+ name=<font class="java5">"Part2 Perspective"</font>
+ class=<font class="java5">"org.eclipse.ui.tutorials.rcp.part2.Perspective"</font>
+ id=<font class="java5">"org.eclipse.ui.tutorials.rcp.part2.perspective"</font>&gt;
+ &lt;/perspective&gt;
+ &lt;/extension&gt;
+ &lt;extension
+ id=<font class="java5">"product"</font>
+ point=<font class="java5">"org.eclipse.core.runtime.products"</font>&gt;
+ &lt;product
+ application=<font class="java5">"org.eclipse.ui.tutorials.rcp.part2.application"</font>
+ name=<font class="java5">"RCP Tutorial 2"</font>/&gt;
+ &lt;/extension&gt;
+
+&lt;/plugin&gt;
+</pre>
+
+<p>The class name of the main program is defined with the <code>org.eclipse.core.runtime.applications</code>
+extension.</p>
+<p><img src="../images/note.gif" alt="Note: " width="62" height="13">
+Although it's not an absolute requirement, I recommend keeping your id's
+and your class names the same except possibly for case. For historical
+reasons, Eclipse prepends the plug-in's id to the id of your top level
+plug-in elements (like <code>extension</code>). For example, even though
+the plugin.xml in listing 2 says <code>id="application"</code>, the
+fully qualified id for that extension is <code>org.eclipse.ui.tutorials.rcp.part2.application</code>.
+Since the perspective's id is written on a sub-element (<code>perspective</code>)
+it has to be spelled out completely in the manifest (<code>org.eclipse.ui.tutorials.rcp.part2.perspective</code>).
+By convention only, package names and ids are lower case and class names
+
+
+
+
+
+
+
+<h2>The main program</h2>
+<p>The <code>org.eclipse.core.runtime.applications</code> extension
+tells the Eclipse runtime the name of your main program. This is a class
+that implements <code>IPlatformRunnable</code> and a <code>run()</code>
+method. Listing 3 shows the simple implementation supplied by the
+plug-in wizard.</p>
+
+<p><b>Listing 3. Application.java </b></p>
+
+<tt class="java"><font class="java4">package </font><font class="java10">org.eclipse.ui.tutorials.rcp.part2;<br />
+<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.core.runtime.IPlatformRunnable;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.swt.widgets.Display;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.PlatformUI;<br />
+<br />
+</font><font class="java14">/**<br />
+* This class controls all aspects of the application's execution<br />
+*/<br />
+</font><font class="java4">public class </font><font class="java10">Application
+</font><font class="java4">implements </font><font class="java10">IPlatformRunnable
+</font><font class="java8">{<br />
+<br />
+&#xA0; </font><font class="java2">/* (non-Javadoc)<br />
+&#xA0;&#xA0; * @see
+org.eclipse.core.runtime.IPlatformRunnable#run(java.lang.Object)<br />
+&#xA0;&#xA0; */<br />
+&#xA0; </font><font class="java4">public </font><font class="java10">Object
+run</font><font class="java8">(</font><font class="java10">Object args</font><font
+ class="java8">) </font><font class="java4">throws </font><font
+ class="java10">Exception </font><font class="java8">{<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java10">Display display =
+PlatformUI.createDisplay</font><font class="java8">()</font><font
+ class="java10">;<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">try </font><font
+ class="java8">{<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java9">int </font><font
+ class="java10">returnCode = PlatformUI.createAndRunWorkbench</font><font
+ class="java8">(</font><font class="java10">display, </font><font
+ class="java4">new </font><font class="java10">ApplicationWorkbenchAdvisor</font><font
+ class="java8">())</font><font class="java10">;<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java4">if </font><font
+ class="java8">(</font><font class="java10">returnCode ==
+PlatformUI.RETURN_RESTART</font><font class="java8">) {<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java4">return
+</font><font class="java10">IPlatformRunnable.EXIT_RESTART;<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java8">}<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java4">return </font><font
+ class="java10">IPlatformRunnable.EXIT_OK;<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java8">} </font><font
+ class="java4">finally </font><font class="java8">{<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java10">display.dispose</font><font
+ class="java8">()</font><font class="java10">;<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java8">}<br />
+&#xA0; }<br />
+}</font></tt>
+
+<h2>The default perspective</h2>
+
+<p>A Perspective is a set of visible views, editors, and menus including
+their positions and sizes. In an RCP program you must define at least
+one perspective and make it the default. Perspectives are created by
+implementing <code>IPerspectiveFactory</code> using the class name
+referred to by the <code>org.eclipse.ui.perspectives</code> extension.
+See Listing 4 for the implementation provided by the plug-in wizard. The
+important part of this interface is the <code>createInitialLayout()</code>
+method where you position and open any views and/or editors you'd like
+the user to start with. So far in this example we haven't created any
+views so it's a pretty boring perspective.</p>
+
+<p><b>Listing 4. Perspective.java </b></p>
+
+<tt class="java"><font class="java4">package </font><font class="java10">org.eclipse.ui.tutorials.rcp.part2;<br />
+<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.IPageLayout;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.IPerspectiveFactory;<br />
+<br />
+</font><font class="java4">public class </font><font class="java10">Perspective
+</font><font class="java4">implements </font><font class="java10">IPerspectiveFactory
+</font><font class="java8">{<br />
+<br />
+&#xA0; </font><font class="java4">public </font><font class="java9">void
+</font><font class="java10">createInitialLayout</font><font
+ class="java8">(</font><font class="java10">IPageLayout layout</font><font
+ class="java8">) {<br />
+&#xA0; }<br />
+}</font></tt>
+
+<h2>The Advisor classes</h2>
+<p>The main program referenced a class called <code>ApplicationWorkbenchAdvisor</code>.
+This is one of three Advisor classes that you use to configure all
+aspects of the Workbench such as the title, menu bars, and so on. <b>These
+are the most important classes for an RCP developer to understand.</b>
+You extend the base version of the class, for example <code>WorkbenchAdvisor</code>,
+in your RCP application and override one or more of the methods to set
+whatever options you want. Let's examine these classes now in more
+detail.</p>
+
+<h3>Workbench Advisor</h3>
+<p>Methods in this class are called from the platform to notify you at
+every point in the lifecycle of the Workbench. They also provide a way
+to handle exceptions in the event loop, and provide important parameters
+to the Workbench such as the default perspective. With the exception of
+<code>createWorkbenchWindowAdvisor()</code> and <code>getInitialWindowPerspectiveId()</code>,
+the methods on <code>WorkbenchAdvisor</code> do not have to be
+overridden. Listing 5 shows the implementation that was provided by the
+plug-in wizard.</p>
+
+<p><b>Listing 5. ApplicationWorkbenchAdvisor.java </b></p>
+
+<tt class="java"><font class="java4">package </font><font class="java10">org.eclipse.ui.tutorials.rcp.part2;<br />
+<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.application.IWorkbenchWindowConfigurer;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.application.WorkbenchAdvisor;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.application.WorkbenchWindowAdvisor;<br />
+<br />
+</font><font class="java4">public class </font><font class="java10">ApplicationWorkbenchAdvisor
+</font><font class="java4">extends </font><font class="java10">WorkbenchAdvisor
+</font><font class="java8">{<br />
+<br />
+&#xA0; </font><font class="java4">private static final </font><font
+ class="java10">String PERSPECTIVE_ID = </font><font class="java5">&#34;org.eclipse.ui.tutorials.rcp.part2.perspective&#34;</font><font
+ class="java10">;<br />
+<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">public </font><font
+ class="java10">WorkbenchWindowAdvisor createWorkbenchWindowAdvisor</font><font
+ class="java8">(</font><font class="java10">IWorkbenchWindowConfigurer
+configurer</font><font class="java8">) {<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java4">return
+new </font><font class="java10">ApplicationWorkbenchWindowAdvisor</font><font
+ class="java8">(</font><font class="java10">configurer</font><font
+ class="java8">)</font><font class="java10">;<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java8">}<br />
+<br />
+&#xA0; </font><font class="java4">public </font><font class="java10">String
+getInitialWindowPerspectiveId</font><font class="java8">() {<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">return </font><font
+ class="java10">PERSPECTIVE_ID;<br />
+&#xA0; </font><font class="java8">}<br />
+}</font></tt>
+
+<p><img src="../images/note.gif" alt="Note: " width="62" height="13">
+Why not an interface? You'll notice that <code>WorkbenchAdvisor</code>
+is an abstract class. For the most part, Eclipse APIs shun abstract
+classes in favor of interfaces and base classes that implement those
+interfaces. In this case, the designers intend for <code>WorkbenchAdvisor</code>
+to <i>always</i> be implemented by the RCP application, and the base
+class doesn't contain any significant functionality. Also it is very
+likely that new methods will need to be added to the base class in the
+future (something that is difficult using interfaces). So this was a
+deliberate design choice. See the article on evolving Java APIs in the
+reference section for more tips.</p>
+
+
+<h4>Workbench lifecycle hooks</h4>
+
+<p>The Workbench Advisor class has several methods that are called at
+defined points in the Workbench's lifecycle (see Table 1). By overriding
+these you can run whatever code you want at these points.</p>
+
+<p><b>Table 1. Workbench lifecycle hooks provided by <code>WorkbenchAdvisor</code>.
+</b></p>
+<table border="1">
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ <th>Parameter(s)</th>
+ </tr>
+ <tr>
+ <td>initialize</td>
+ <td>Called first to perform any setup such as parsing the command
+ line, registering adapters, declaring images, etc..</td>
+ <td><code>IWorkbenchConfigurer</code></td>
+ </tr>
+ <tr>
+ <td>preStartup</td>
+ <td>Called after initialization but before the first window is opened.
+ May be used to set options affecting which editors and views are
+ initially opened.</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>postStartup</td>
+ <td>Called after all windows have been opened or restored, but before
+ the event loop starts. It can be used to start automatic processes and
+ to open tips or other windows.</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>preShutdown</td>
+ <td>Called after the event loop has terminated but before any windows
+ have been closed.</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>postShutdown</td>
+ <td>Called after all windows are closed during Workbench shutdown.
+ This can be used to save the current application state and clean up
+ anything created by <code>initialize</code>.</td>
+ <td>&nbsp;</td>
+ </tr>
+</table>
+
+
+<h4>Event loop hooks</h4>
+
+<p>The event loop is the code that is running most of the time during
+the life of the Workbench. It handles all user inputs and dispatches
+them to the right listeners. RCP provides a couple of hooks to handle
+crashes and perform work during idle time (see Table 2). Note however
+that the Jobs interface (see References) is a better way of performing
+long running work than this idle hook.</p>
+
+<p><b>Table 2. Event loop hooks provided by <code>WorkbenchAdvisor</code>.
+</b></p>
+<table border="1">
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ <th>Parameter(s)</th>
+ </tr>
+ <tr>
+ <td>eventLoopException</td>
+ <td>Called if there is an unhandled exception in the event loop. The
+ default implementation will log the error.</td>
+ <td><code>Throwable</code></td>
+ </tr>
+ <tr>
+ <td>eventLoopIdle</td>
+ <td>Called when the event loop has nothing to do.</td>
+ <td><code>Display</code></td>
+ </tr>
+</table>
+
+<h4>Information getting hooks</h4>
+<p>Next, there are few methods you can implement that the platform will
+call to get information about your application (see Table 3). The most
+important one (and the only one that is not optional) is <code>getInitialWindowPerspectiveId</code>.
+We used this in Listing 5 to return the id of the starting perspective.</p>
+
+<p><b>Table 3. Information request methods you can override in <code>WorkbenchAdvisor</code>.
+</b></p>
+<table border="1">
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ <th>Parameter(s)</th>
+ </tr>
+ <tr>
+ <td>getDefaultPageInput</td>
+ <td>Return the default input for new workbench pages. Defaults to
+ null.</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>getInitialWindowPerspectiveId</td>
+ <td>Return the initial perspective used for new workbench windows.
+ This is a required function that has no default.</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>getMainPreferencePageId</td>
+ <td>Return the preference page that should be displayed first.
+ Defaults to null, meaning the pages should be arranged alphabetically.
+ </td>
+ <td>&nbsp;</td>
+ </tr>
+</table>
+
+<h4>Advanced configuration</h4>
+<p>The <code>WorkbenchAdvisor</code> events above should be sufficient
+for most applications, but just in case, RCP provides another method to
+take complete control of how your application windows and controls are
+created. It's listed in Table 4 for completeness but I don't expect many
+programs will need it.</p>
+
+<p><b>Table 4. Advanced methods in <code>org.eclipse.ui.application.WorkbenchAdvisor</code>.
+</b></p>
+<table border="1">
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ <th>Parameter(s)</th>
+ </tr>
+ <tr>
+ <td>openWindows</td>
+ <td>Open all Workbench windows on startup. The default implementation
+ tries to restore the previously saved workbench state.</td>
+ <td>&nbsp;</td>
+ </tr>
+</table>
+
+
+<h3>Workbench Window Advisor</h3>
+<p>This class is used to control the status line, toolbar, title, window
+size, and other things you'll almost certainly want to customize. You
+can also use it to hook into all the various lifecycle events of the
+Workbench Windows. Listing 6 shows the implementation provided by the
+plug-in wizard.</p>
+
+<p><b>Listing 6. ApplicationWorkbenchWindowAdvisor.java </b></p>
+
+<tt class="java"><font class="java4">package </font><font class="java10">org.eclipse.ui.tutorials.rcp.part2;<br />
+<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.swt.graphics.Point;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.application.ActionBarAdvisor;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.application.IActionBarConfigurer;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.application.IWorkbenchWindowConfigurer;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.application.WorkbenchWindowAdvisor;<br />
+<br />
+</font><font class="java4">public class </font><font class="java10">ApplicationWorkbenchWindowAdvisor
+</font><font class="java4">extends </font><font class="java10">WorkbenchWindowAdvisor
+</font><font class="java8">{<br />
+<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">public </font><font
+ class="java10">ApplicationWorkbenchWindowAdvisor</font><font
+ class="java8">(</font><font class="java10">IWorkbenchWindowConfigurer
+configurer</font><font class="java8">) {<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java4">super</font><font
+ class="java8">(</font><font class="java10">configurer</font><font
+ class="java8">)</font><font class="java10">;<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java8">}<br />
+<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">public </font><font
+ class="java10">ActionBarAdvisor createActionBarAdvisor</font><font
+ class="java8">(</font><font class="java10">IActionBarConfigurer
+configurer</font><font class="java8">) {<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java4">return
+new </font><font class="java10">ApplicationActionBarAdvisor</font><font
+ class="java8">(</font><font class="java10">configurer</font><font
+ class="java8">)</font><font class="java10">;<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java8">}<br />
+&#xA0;&#xA0;&#xA0; <br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">public </font><font
+ class="java9">void </font><font class="java10">preWindowOpen</font><font
+ class="java8">() {<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java10">IWorkbenchWindowConfigurer
+configurer = getWindowConfigurer</font><font class="java8">()</font><font
+ class="java10">;<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; configurer.setInitialSize</font><font
+ class="java8">(</font><font class="java4">new </font><font
+ class="java10">Point</font><font class="java8">(</font><font
+ class="java7">400</font><font class="java10">, </font><font
+ class="java7">300</font><font class="java8">))</font><font
+ class="java10">;<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; configurer.setShowCoolBar</font><font
+ class="java8">(</font><font class="java4">false</font><font
+ class="java8">)</font><font class="java10">;<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; configurer.setShowStatusLine</font><font
+ class="java8">(</font><font class="java4">false</font><font
+ class="java8">)</font><font class="java10">;<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; configurer.setTitle</font><font
+ class="java8">(</font><font class="java5">&#34;Hello RCP&#34;</font><font
+ class="java8">)</font><font class="java10">;<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java8">}<br />
+}</font></tt>
+
+<p>Methods on WorkbenchWindowAdvisor (see Table 5 and Table 6) will all
+need access to a Configurer interface (in this case, <code>IWorkbenchWindowConfigurer</code>)
+in order to do anything so they're expected to call <code>getWindowConfigurer()</code>
+to fetch it. You call methods on the Configurer interfaces to actually
+change the options. These interfaces are not covered in any detail in
+this tutorial but you can refer to their Javadoc for more information.</p>
+
+<p><b>Table 5. Workbench window lifecycle hooks provided by <code>WorkbenchWindowAdvisor</code>.
+</b></p>
+<table border="1">
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ <th>Parameter(s)</th>
+ </tr>
+ <tr>
+ <td>preWindowOpen</td>
+ <td>Called in the constructor of the Workbench Window. Use this method
+ to set options such as whether or not the window will have a menu bar.
+ However none of the window's widgets have been created yet so they
+ can't be referenced in this method.</td>
+ <td><code></code></td>
+ </tr>
+ <tr>
+ <td>postWindowRestore</td>
+ <td>Optionally called for cases when a window has been restored from
+ saved state but before it is opened.</td>
+ <td><code></code></td>
+ </tr>
+ <tr>
+ <td>postWindowCreate</td>
+ <td>Called after a window has been restored from saved state or
+ created from scratch but before it is opened.</td>
+ <td><code></code></td>
+ </tr>
+ <tr>
+ <td>openIntro</td>
+ <td>Called immediately before a window is opened in order to create
+ the Intro component (if any).</td>
+ <td><code></code></td>
+ </tr>
+ <tr>
+ <td>postWindowOpen</td>
+ <td>Called right after the Workbench window is opened. Can be used to
+ tweak any of the window's widgets, for example to set a title or
+ change its size.</td>
+ <td><code></code></td>
+ </tr>
+ <tr>
+ <td>preWindowShellClose</td>
+ <td>Called before the Workbench window is closed (technically, before
+ its shell is closed). This is the only function that can veto the
+ close, so it's a good place for an "Are you sure" kind of dialog.</td>
+ <td><code></code></td>
+ </tr>
+ <tr>
+ <td>postWindowClose</td>
+ <td>Called after the Workbench window is closed. Can be used to clean
+ up anything created by <code>preWindowOpen</code>.</td>
+ <td><code></code></td>
+ </tr>
+</table>
+
+
+<p><b>Table 6. Advanced methods in <code>WorkbenchWindowAdvisor</code>.
+</b></p>
+<table border="1">
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ <th>Parameter(s)</th>
+ </tr>
+ <tr>
+ <td>createWindowContents</td>
+ <td>Creates the contents of one window. Override this method to define
+ custom contents and layout.</td>
+ <td><code>Shell</code></td>
+ </tr>
+ <tr>
+ <td>createEmptyWindowContents</td>
+ <td>Like <code>createWindowContents</code>, but used when the window
+ has no open pages. Override this method to show something other than
+ the default window background.</td>
+ <td><code>Composite</code></td>
+ </tr>
+</table>
+
+<h3>ActionBar Advisor</h3>
+<p>In Eclipse jargon, "action bar" is a catch-all term for menus,
+toolbars, and status bars. The ActionBar Advisor handles creating
+Actions within these locations. A plug-in can also contribute actions
+dynamically with its plugin.xml file. See Listing 7 for the
+implementation provided by the plug-in wizard and Table 7 for the
+methods.</p>
+
+<p><img src="../images/note.gif" alt="Note: " width="62" height="13">The
+whole action, command and keybinding system is a bit of a mess in
+Eclipse 3.1. For example you can't add combo boxes to action bars, and
+plugin.xml can't contribute actions to the status bar. Getting key
+bindings to work involves multiple steps. Hopefully this will be cleaned
+up in a future release.</p>
+
+<p><b>Listing 7. ApplicationActionBarAdvisor.java </b></p>
+
+<tt class="java"><font class="java4">package </font><font class="java10">org.eclipse.ui.tutorials.rcp.part2;<br />
+<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.jface.action.IMenuManager;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.IWorkbenchWindow;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.application.ActionBarAdvisor;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.application.IActionBarConfigurer;<br />
+<br />
+</font><font class="java4">public class </font><font class="java10">ApplicationActionBarAdvisor
+</font><font class="java4">extends </font><font class="java10">ActionBarAdvisor
+</font><font class="java8">{<br />
+<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">public </font><font
+ class="java10">ApplicationActionBarAdvisor</font><font class="java8">(</font><font
+ class="java10">IActionBarConfigurer configurer</font><font
+ class="java8">) {<br />
+&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </font><font class="java4">super</font><font
+ class="java8">(</font><font class="java10">configurer</font><font
+ class="java8">)</font><font class="java10">;<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java8">}<br />
+<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">protected </font><font
+ class="java9">void </font><font class="java10">makeActions</font><font
+ class="java8">(</font><font class="java10">IWorkbenchWindow window</font><font
+ class="java8">) {<br />
+&#xA0;&#xA0;&#xA0; }<br />
+<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">protected </font><font
+ class="java9">void </font><font class="java10">fillMenuBar</font><font
+ class="java8">(</font><font class="java10">IMenuManager menuBar</font><font
+ class="java8">) {<br />
+&#xA0;&#xA0;&#xA0; }<br />
+&#xA0;&#xA0;&#xA0; <br />
+}</font></tt>
+
+<p><b>Table 7. Methods you can override in <code>ActionBarAdvisor</code>.
+</b></p>
+<table border="1">
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ <th>Parameter(s)</th>
+ </tr>
+ <tr>
+ <td>makeActions</td>
+ <td>Called to create the actions used in the fill methods.</td>
+ <td><code>IWorkbenchWindow</code></td>
+ </tr>
+ <tr>
+ <td>fillMenuBar</td>
+ <td>Called to fill the menu bar with the main menus for the window.</td>
+ <td><code>IMenuManager</code></td>
+ </tr>
+ <tr>
+ <td>fillCoolBar</td>
+ <td>Called to fill the cool bar with the main toolbars for the window.</td>
+ <td><code>ICoolBarManager</code></td>
+ </tr>
+ <tr>
+ <td>fillStatusLine</td>
+ <td>Called to fill the status line with the main status line
+ contributions for the window.</td>
+ <td><code>IStatusLineManager</code></td>
+ </tr>
+ <tr>
+ <td>isApplicationMenu</td>
+ <td>Return true if the menu is one of yours. OLE specific; see Javadoc
+ for details.</td>
+ <td><code>String</code></td>
+ </tr>
+
+</table>
+
+<h2>Plug-in class</h2>
+<p>The plug-in class is an optional singleton class that can be used to
+store global information for the plug-in. It's also a convenient place
+to put a few static utility functions used by other classes in the
+plug-in. See Listing 8 for the plug-in class that was created for us by
+the plug-in wizard.</p>
+
+<p><b>Listing 8. Part2Plugin.java </b></p>
+
+<tt class="java"><font class="java4">package </font><font class="java10">org.eclipse.ui.tutorials.rcp.part2;<br />
+<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.ui.plugin.*;<br />
+</font><font class="java4">import </font><font class="java10">org.eclipse.jface.resource.ImageDescriptor;<br />
+</font><font class="java4">import </font><font class="java10">org.osgi.framework.BundleContext;<br />
+<br />
+</font><font class="java14">/**<br />
+* The main plugin class to be used in the desktop.<br />
+*/<br />
+</font><font class="java4">public class </font><font class="java10">Part2Plugin
+</font><font class="java4">extends </font><font class="java10">AbstractUIPlugin
+</font><font class="java8">{<br />
+<br />
+&#xA0; </font><font class="java3">//The shared instance.<br />
+&#xA0; </font><font class="java4">private static </font><font
+ class="java10">Part2Plugin plugin;<br />
+&#xA0; <br />
+&#xA0; </font><font class="java14">/**<br />
+&#xA0;&#xA0; * The constructor.<br />
+&#xA0;&#xA0; */<br />
+&#xA0; </font><font class="java4">public </font><font class="java10">Part2Plugin</font><font
+ class="java8">() {<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java10">plugin = </font><font
+ class="java4">this</font><font class="java10">;<br />
+&#xA0; </font><font class="java8">}<br />
+<br />
+&#xA0; </font><font class="java14">/**<br />
+&#xA0;&#xA0; * This method is called upon plug-in activation<br />
+&#xA0;&#xA0; */<br />
+&#xA0; </font><font class="java4">public </font><font class="java9">void
+</font><font class="java10">start</font><font class="java8">(</font><font
+ class="java10">BundleContext context</font><font class="java8">) </font><font
+ class="java4">throws </font><font class="java10">Exception </font><font
+ class="java8">{<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">super</font><font
+ class="java10">.start</font><font class="java8">(</font><font
+ class="java10">context</font><font class="java8">)</font><font
+ class="java10">;<br />
+&#xA0; </font><font class="java8">}<br />
+<br />
+&#xA0; </font><font class="java14">/**<br />
+&#xA0;&#xA0; * This method is called when the plug-in is stopped<br />
+&#xA0;&#xA0; */<br />
+&#xA0; </font><font class="java4">public </font><font class="java9">void
+</font><font class="java10">stop</font><font class="java8">(</font><font
+ class="java10">BundleContext context</font><font class="java8">) </font><font
+ class="java4">throws </font><font class="java10">Exception </font><font
+ class="java8">{<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">super</font><font
+ class="java10">.stop</font><font class="java8">(</font><font
+ class="java10">context</font><font class="java8">)</font><font
+ class="java10">;<br />
+&#xA0;&#xA0;&#xA0; plugin = </font><font class="java4">null</font><font
+ class="java10">;<br />
+&#xA0; </font><font class="java8">}<br />
+<br />
+&#xA0; </font><font class="java14">/**<br />
+&#xA0;&#xA0; * Returns the shared instance.<br />
+&#xA0;&#xA0; */<br />
+&#xA0; </font><font class="java4">public static </font><font
+ class="java10">Part2Plugin getDefault</font><font class="java8">() {<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">return </font><font
+ class="java10">plugin;<br />
+&#xA0; </font><font class="java8">}<br />
+<br />
+&#xA0; </font><font class="java14">/**<br />
+&#xA0;&#xA0; * Returns an image descriptor for the image file at the
+given<br />
+&#xA0;&#xA0; * plug-in relative path.<br />
+&#xA0;&#xA0; *<br />
+&#xA0;&#xA0; * </font><font class="java11">@param </font><font
+ class="java14">path the path<br />
+&#xA0;&#xA0; * </font><font class="java11">@return </font><font
+ class="java14">the image descriptor<br />
+&#xA0;&#xA0; */<br />
+&#xA0; </font><font class="java4">public static </font><font
+ class="java10">ImageDescriptor getImageDescriptor</font><font
+ class="java8">(</font><font class="java10">String path</font><font
+ class="java8">) {<br />
+&#xA0;&#xA0;&#xA0; </font><font class="java4">return </font><font
+ class="java10">AbstractUIPlugin.imageDescriptorFromPlugin</font><font
+ class="java8">(</font><font class="java5">&#34;org.eclipse.ui.tutorials.rcp.part2&#34;</font><font
+ class="java10">, path</font><font class="java8">)</font><font
+ class="java10">;<br />
+&#xA0; </font><font class="java8">}<br />
+}</font></tt>
+
+<h2>Build properties</h2>
+<p>The build.properties file (see Listing 9) will be needed when
+exporting the application for others to use. In particular if your
+application needs any resources like icons they should be listed here in
+the <code>bin.includes</code> section. The Plug-in Manifest editor
+provides a convenient interface to modify this file that is less
+error-prone than modifying it by hand.</p>
+
+<p><b>Listing 9. build.properties </b></p>
+
+<pre>
+source.. = <font class="java5">src/</font>
+output.. = <font class="java5">bin/</font>
+bin.includes = <font class="java5">plugin.xml,\
+ META-INF/,\
+ .</font>
+</pre>
+
+<h2>Conclusion</h2>
+<p>In part 2 of this tutorial, we looked at some of the API of the Rich
+Client Platform that allows you to develop customized native-looking
+client-side Java programs. The next part will delve into branding and
+deploying your application so others can use it. All the sample code for
+this part is included in the <a href="part2.zip">part2.zip archive file</a>
+that accompanies this document.</p>
+
+<h2>References</h2>
+<p><a href="../Article-RCP-1/tutorial1.html"> RCP Tutorial Part 1</a><br>
+<a href="../Article-RCP-3/tutorial3.html"> RCP Tutorial Part 3</a><br>
+<a href="http://www.eclipse.org/rcp" target="_blank"> Eclipse Rich
+Client Platform</a><br>
+<a href="http://www.eclipse.org/equinox" target="_blank">The Equinox
+project (OSGi in Eclipse)</a><br>
+<a href="../Article-Internationalization/how2I18n.html" target="_blank">
+How to Internationalize your Eclipse Plug-in</a><br>
+<a
+ href="http://www.eclipse.org/articles/Article-PDE-does-plugins/PDE-intro.html">PDE
+Does Plug-ins</a><br>
+<a
+ href="http://www.eclipse.org/articles/Article-Plug-in-architecture/plugin_architecture.html">Notes
+on the Eclipse Plug-in Architecture</a><br>
+<a
+ href="http://www.eclipse.org/articles/Article-Concurrency/jobs-api.html">On
+the Job: The Eclipse Jobs API</a><br>
+<a
+ href="http://www.fawcette.com/javapro/2002_06/online/servlets_06_11_02/"
+ target="_blank">Almost All Java Web Apps Need Model 2 (introduction to
+the Model 2 architecture)</a><br>
+<a
+ href="http://www.eclipse.org/eclipse/development/java-api-evolution.html"
+ target="_blank"> Evolving Java-based APIs</a><br>
+</p>
+
+
+<p>To discuss or report problems in this article see <a
+ href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=104170">bug 104170</a>.</p>
+
+<p><small>IBM is trademark of International Business Machines
+Corporation in the United States, other countries, or both.</small></p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or
+registered trademarks of Sun Microsystems, Inc. in the United States,
+other countries, or both.</small></p>
+<p><small>Microsoft and Windows are trademarks of Microsoft Corporation
+in the United States, other countries, or both.</small></p>
+<p><small>Other company, product, and service names may be trademarks or
+service marks of others.</small></p>
+
+</body>
+
+</html>
diff --git a/Article-RCP-3/images/Idea.jpg b/Article-RCP-3/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-RCP-3/images/Idea.jpg
Binary files differ
diff --git a/Article-RCP-3/images/complete.png b/Article-RCP-3/images/complete.png
new file mode 100644
index 0000000..3b33450
--- /dev/null
+++ b/Article-RCP-3/images/complete.png
Binary files differ
diff --git a/Article-RCP-3/images/help.png b/Article-RCP-3/images/help.png
new file mode 100644
index 0000000..3cb4fa6
--- /dev/null
+++ b/Article-RCP-3/images/help.png
Binary files differ
diff --git a/Article-RCP-3/images/note.gif b/Article-RCP-3/images/note.gif
new file mode 100644
index 0000000..f6260db
--- /dev/null
+++ b/Article-RCP-3/images/note.gif
Binary files differ
diff --git a/Article-RCP-3/images/tag_1.gif b/Article-RCP-3/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-RCP-3/images/tag_1.gif
Binary files differ
diff --git a/Article-RCP-3/images/tag_2.gif b/Article-RCP-3/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-RCP-3/images/tag_2.gif
Binary files differ
diff --git a/Article-RCP-3/images/tag_3.gif b/Article-RCP-3/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-RCP-3/images/tag_3.gif
Binary files differ
diff --git a/Article-RCP-3/images/tag_4.gif b/Article-RCP-3/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-RCP-3/images/tag_4.gif
Binary files differ
diff --git a/Article-RCP-3/images/tag_5.gif b/Article-RCP-3/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-RCP-3/images/tag_5.gif
Binary files differ
diff --git a/Article-RCP-3/images/tag_6.gif b/Article-RCP-3/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-RCP-3/images/tag_6.gif
Binary files differ
diff --git a/Article-RCP-3/images/tip.gif b/Article-RCP-3/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-RCP-3/images/tip.gif
Binary files differ
diff --git a/Article-RCP-3/tutorial3.html b/Article-RCP-3/tutorial3.html
new file mode 100644
index 0000000..daaf653
--- /dev/null
+++ b/Article-RCP-3/tutorial3.html
@@ -0,0 +1,518 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+<title>Rich Client Platform</title>
+<link href="../default_style.css" rel=stylesheet>
+</head>
+
+<body>
+
+<div align="right">
+ <font face="Times New Roman, Times, serif" size="2">Copyright © 2004 Ed
+ Burnette.</font>
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tbody>
+ <tr>
+ <td align="left" valign="top" colspan="2" bgcolor="#0080c0"><b><font face="Arial,Helvetica"><font color="#ffffff">Eclipse
+ Article</font></font></b></td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+<div align="left">
+ <h1 title="RCP Tutorial"><img src="images/Idea.jpg" align="middle" width="120" height="86"></h1>
+</div>
+<h1 align="center">Rich Client Tutorial Part 3</h1>
+<p class="summary">
+The Rich Client Platform (RCP)
+lets you pick and choose functionality from Eclipse
+for use in your own applications.
+Parts 1 and 2 of this tutorial introduced you to the platform
+and some of the configuration classes it provides.
+Part 3 discusses how to add
+functionality such as menus, views, and help files.
+</p>
+<p><b>By Ed Burnette, SAS</b><br>
+<font size="-1">July 28, 2004</font></p>
+<hr width="100%">
+
+<h2>Introduction</h2>
+<p>
+Much of our discussion in the previous
+two parts focused on taking things away from
+the platform - turning off toolbars, getting
+rid of menus, and so forth.
+For this installment we're going to look at putting things back in.
+All source code for the tutorial
+can be downloaded from the
+<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.ui.tutorials.rcp.part3">Eclipse project here</a>.
+</p>
+
+<h2>Views</h2>
+<p>
+Let's start with a view.
+Eclipse's Plug-in Development Environment
+provides a nice set of extension templates to get you started writing
+sample views, editors, menus,
+and other components.
+Unfortunately, as of this writing, they are almost useless for
+RCP development because the code produced introduces all
+sorts of dependencies on IDE and resource packages
+and plug-ins.
+</p>
+<p>
+<img src="images/tip.gif" alt="Tip: " width="62" height="13">
+The rule of thumb is that anything that references a resource is
+not intended for RCP developers because of the extra code
+and dependencies on workspaces it
+pulls in.
+So if you see the <code>org.eclipse.core.resources</code>
+plug-in in your dependency list, or see an import for
+some class from that package, you're probably doing something wrong.
+This is not a hard and fast rule though, so
+resources should be considered an <i>optional</i>
+part of the Rich Client Platform.
+</p>
+<p>
+To create a view without the templates, you can
+use the schema-based extension wizards from the
+Plug-in Manifest editor (Extensions pane > Add > Generic Wizards > Schema-based
+Extensions) or simply edit the XML in the Source pane.
+Either way, you want to end up with extension XML like this:
+</p>
+<pre>
+ &lt;extension
+ point="org.eclipse.ui.views"&gt;
+ &lt;category
+ name="SampleCategory"
+<img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1"> id="org.eclipse.ui.tutorials.rcp.part3.viewCategory"&gt;
+ &lt;/category&gt;
+ &lt;view
+ name="Sample"
+ icon="icons/sample.gif"
+ category="org.eclipse.ui.tutorials.rcp.part3.viewCategory"
+<img src="images/tag_2.gif" height="13" width="24" align="center" alt="#2"> class="org.eclipse.ui.tutorials.rcp.part3.views.SampleView"
+ id="org.eclipse.ui.tutorials.rcp.part3.views.SampleView"&gt;
+ &lt;/view&gt;
+ &lt;/extension&gt;
+</pre>
+<p>
+The view category (<img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1">)
+is a way to organize your views in the
+Show Views dialog.
+The class (<img src="images/tag_2.gif" height="13" width="24" align="center" alt="#2">)
+extends the <code>ViewPart</code> abstract class as shown below:
+</p>
+
+<pre>
+ public class SampleView extends ViewPart {
+<img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1"> public static final String ID_VIEW =
+ "org.eclipse.ui.tutorials.rcp.part3.views.SampleView"; //$NON-NLS-1$
+
+ private TableViewer viewer;
+
+ public SampleView() {
+ }
+
+<img src="images/tag_2.gif" height="13" width="24" align="center" alt="#2"> public void createPartControl(Composite parent) {
+ viewer =
+ new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ viewer.setContentProvider(new ViewContentProvider());
+ viewer.setLabelProvider(new ViewLabelProvider());
+ viewer.setInput(this);
+ }
+
+ public void setFocus() {
+ viewer.getControl().setFocus();
+ }
+ }
+</pre>
+<p>
+Defining constants that start with <code>ID_</code>
+(<img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1">)
+is a pattern you'll see
+used over and over again in the Eclipse source code.
+Here we use it to duplicate the same id used in the
+plug-in manifest.
+This will be used later when we need a reference to the view.
+</p>
+<p>
+The most important part of this class is the <code>createPartControl</code> method
+(<img src="images/tag_2.gif" height="13" width="24" align="center" alt="#2">).
+It's where you create your JFace or SWT controls that make
+up the view.
+The rest of the source was can be found in the example project.
+View programming is beyond the scope of this tutorial
+but you can see the reference section for more information.
+</p>
+
+<h2>Perspective additions</h2>
+<p>
+If you run the code now you won't actually see anything different.
+Why? Because your new view can't appear unless it is added
+to the current perspective.
+You can do this through code or though the org.eclipse.ui.perspectiveExtensions
+extension.
+We'll choose the former because it's a little more flexible.
+To do this, go back to the <code>RcpPerspective</code> class
+defined earlier and modify it to look like this:
+</p>
+
+<pre>
+ public class RcpPerspective implements IPerspectiveFactory {
+<img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1"> public static final String ID_PERSPECTIVE =
+ "org.eclipse.ui.tutorials.rcp.part3.RcpPerspective"; //$NON-NLS-1$
+
+ public RcpPerspective() {
+ }
+
+ public void createInitialLayout(IPageLayout layout) {
+<img src="images/tag_2.gif" height="13" width="24" align="center" alt="#2"> layout.setEditorAreaVisible(false);
+<img src="images/tag_3.gif" height="13" width="24" align="center" alt="#3"> layout.addView(
+ SampleView.ID_VIEW,
+ IPageLayout.TOP,
+ IPageLayout.RATIO_MAX,
+ IPageLayout.ID_EDITOR_AREA);
+<img src="images/tag_4.gif" height="13" width="24" align="center" alt="#4"> layout.addPerspectiveShortcut(ID_PERSPECTIVE);
+<img src="images/tag_5.gif" height="13" width="24" align="center" alt="#5"> layout.addShowViewShortcut(SampleView.ID_VIEW);
+ }
+ }
+</pre>
+<p>
+Notes:
+</p>
+<table border="0">
+<tr valign="top"><td><img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1">
+<td>Again, just get in the habit of
+defining a constant for all strings, especially ids.
+<tr valign="top"><td><img src="images/tag_2.gif" height="13" width="24" align="center" alt="#2">
+<td>The Platform supports editors but we're not using
+one for this example. Therefore you need to turn off the
+editor area so you won't have a big blank space in the middle
+of your Workbench Window.
+<tr valign="top"><td><img src="images/tag_3.gif" height="13" width="24" align="center" alt="#3">
+<td>This is the most important part of the class.
+It adds the view to the perspective so it will be visible by default.
+The positioning parameters say to place this view above the
+editor area and let it take 100% of the Workbench Window.
+This might be a little strange since we don't have an editor area but
+it's lurking around somewhere even if it's invisible.
+As you add more than one view to your application you can
+define the default stacking and layout of your views here.
+<tr valign="top"><td><img src="images/tag_4.gif" height="13" width="24" align="center" alt="#4">
+<td>This method causes the perspective to be
+on the short list if you implement the <code>PERSPECTIVES_SHORTLIST</code>
+menu item (see the sample code for an example).
+Without it, the perspective will only be on the long list seen
+when the user selects Window > Open Perspective > Other (or whatever
+the equivalent menu path is in your application).
+<tr valign="top"><td><img src="images/tag_5.gif" height="13" width="24" align="center" alt="#5">
+<td>Same thing, only for views.
+</table>
+<p>
+<img src="images/tip.gif" alt="Tip: " width="62" height="13">
+To remember the user's layout and window sizes
+for the next time they start your application, add
+<code>configurer.setSaveAndRestore(true);</code>
+to the <code>initialize</code> method of <code>WorkbenchAdvisor</code>.
+An example of this can be found in the sample project.
+</p>
+
+<h3>Fixed views</h3>
+<p>
+By default, views will be moveable, resizeable, and closable.
+Often you don't want that flexibility.
+For example, if you're writing an order entry application
+for unsophisticated users, you don't want to have to answer
+help desk questions about what to do if somebody accidentally closes
+the form view.
+For this reason Eclipse 3.0 introduces the notion of fixed
+perspectives and fixed views.
+</p>
+<p>
+A fixed view is a view that cannot be closed.
+The title bar of the view doesn't even have a close button.
+To create one of these you can use the <code>setFixed()</code>
+method on <code>IPageLayout</code>.
+</p>
+<p>
+A better way might be to use a fixed perspective.
+A fixed perspective makes all of the views it contains fixed,
+plus it prevents any of them from being moved or resized.
+To make a perspective fixed, simply add the <code>fixed="true"</code>
+attribute to its definition,
+for example:
+</p>
+<pre>
+ &lt;extension
+ point=&quot;org.eclipse.ui.perspectives&quot;&gt;
+ &lt;perspective
+ name=&quot;%perspectiveName&quot;
+ icon=&quot;icons/sample.gif&quot;
+ <b>fixed=&quot;true&quot;</b>
+ class=&quot;org.eclipse.ui.tutorials.rcp.part3.RcpPerspective&quot;
+ id=&quot;org.eclipse.ui.tutorials.rcp.part3.RcpPerspective&quot;&gt;
+ &lt;/perspective&gt;
+ &lt;/extension&gt;
+</pre>
+<p>
+By using a fixed perspective and turning off the shortcut bar, you
+can lock the user into one perspective and hide the concept of perspectives
+from them altogether.
+</p>
+
+<h2>Menus</h2>
+<p>
+Letting you configure all the menus was one of the first
+requirements of the RCP.
+There are two ways to add menus in an RCP application:
+</p>
+<ul>
+<li><code>WorkbenchAdvisor.fillActionBars</code>
+<li><code>org.eclipse.ui.actionSets</code> in the plug-in manifest
+</ul>
+<p>
+<code>fillActionBars</code> is the only way to reference built-in
+Workbench actions, so we'll use it for that purpose.
+Everything else can be contributed by the <code>actionSets</code> extension point.
+Both methods will be demonstrated here.
+Although the example application does not use
+toolbars, they are very similar to menus.
+</p>
+<p>
+First let's take a look at <code>fillActionBars</code>:
+</p>
+<pre>
+ public void fillActionBars(
+ IWorkbenchWindow window,
+ IActionBarConfigurer configurer,
+ int flags) {
+ super.fillActionBars(window, configurer, flags);
+<img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1"> if ((flags & FILL_MENU_BAR) != 0) {
+ fillMenuBar(window, configurer);
+ }
+ }
+</pre>
+<p>
+<code>fillActionBars</code> is takes a flags parameter
+(<img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1">)
+that indicates what
+the code should really do.
+There are flag bits for filling in the menu bar, the tool bar,
+the status line, and even a bit for whether or not this is a fake
+request for preference dialogs (<code>FILL_PROXY</code>).
+The author has had some bad experiences with flags like this,
+so the example code just calls a helper function called <code>fillMenuBar</code>
+to do the actual filling.
+Here's the code for <code>fillMenuBar</code>:
+</p>
+<pre>
+ private void fillMenuBar(
+ IWorkbenchWindow window,
+ IActionBarConfigurer configurer) {
+ IMenuManager menuBar = configurer.getMenuManager();
+ menuBar.add(createFileMenu(window));
+ menuBar.add(createEditMenu(window));
+ menuBar.add(createWindowMenu(window));
+ menuBar.add(createHelpMenu(window));
+ }
+</pre>
+<p>
+For this example we want to create four top-level
+menus: File, Edit, Window, and Help.
+These correspond to the menus of the same name
+in the Eclipse IDE.
+For a real application you may not want all these,
+or you might want to call them something different.
+See figure 1 for an example.
+</p>
+
+<img src="images/complete.png">
+<p><b>Figure 1. The Workbench menu bar is defined
+in the <code>fillActionBars</code> method of <code>WorkbenchAdvisor</code>,
+and then added to by the manifests of
+all plug-ins that extend <code>org.eclipse.ui.actionSets</code>.
+</b></p>
+
+<p>
+The code for all these methods can be found in the example project.
+Let's just take a closer look at one of of them, the File menu:
+</p>
+
+<pre>
+ private MenuManager createFileMenu(IWorkbenchWindow window) {
+<img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1"> MenuManager menu = new MenuManager(Messages.getString("File"), //$NON-NLS-1$
+ IWorkbenchActionConstants.M_FILE);
+<img src="images/tag_2.gif" height="13" width="24" align="center" alt="#2"> menu.add(new GroupMarker(IWorkbenchActionConstants.FILE_START));
+ menu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+<img src="images/tag_3.gif" height="13" width="24" align="center" alt="#3"> menu.add(ActionFactory.QUIT.create(window));
+ menu.add(new GroupMarker(IWorkbenchActionConstants.FILE_END));
+ return menu;
+ }
+</pre>
+<p>
+All these menus work the same way.
+First you create a MenuManager for the menu
+(<img src="images/tag_1.gif" height="13" width="24" align="center" alt="#1">)
+using the message file to lookup the actual human-readable title.
+Then you add all the menu items and return the manager.
+See the references section for more information about defining views and menus.
+Next, you create some placeholders
+(<img src="images/tag_2.gif" height="13" width="24" align="center" alt="#2">)
+where additional
+menu items can be added by plug-ins,
+and one real action supplied by the Workbench: the Quit action
+(<img src="images/tag_3.gif" height="13" width="24" align="center" alt="#3">).
+A list of supported Workbench actions can be found by
+looking at the Javadoc for <code>ActionFactory</code> and
+<code>ContributionItemFactory</code>.
+</p>
+<p>
+<img src="images/note.gif" alt="Note: " width="62" height="13">
+There are a number of standard placeholder names
+for menus and toolbars
+that you should use when trying to make yours work just
+like the ones in the IDE.
+By using these predefined groups, plug-ins that contribute menu
+and toolbar items to the Eclipse IDE can also contribute them
+to your RCP application.
+These aren't documented anywhere other than in the Javadoc for
+<code>IWorkbenchActionConstants</code>, and even there you won't find any guidance
+for their intended order.
+The sample code that accompanies this tutorial was created by looking at the
+<code>IDEWorkbenchAdvisor</code> class used by the Eclipse IDE.
+</p>
+
+<h2>Help</h2>
+<p>
+One of the coolest features of the RCP is its help system.
+Simply by providing the table of contents in
+XML format and the documents in HTML,
+you can give your users a searchable help
+system with no coding on your part.
+First, you add an extension to your plug-in manifest like this:
+</p>
+<pre>
+ &lt;extension
+ point="org.eclipse.help.toc"&gt;
+ &lt;toc
+ file="book.xml"
+ primary="true"&gt;
+ &lt;/toc&gt;
+ &lt;/extension&gt;
+</pre>
+
+<p>
+Then you create a table of contents file (book.xml in this example)
+to define a hierarchy of help topics.
+Not all the topics have to be in the contents but it is
+good practice to do so.
+Here's an example you can use to get started:
+</p>
+<pre>
+ &lt;toc label="RCP Help Sample" topic="html/book.html"&gt;
+ &lt;topic label="Overview" href="html/overview.html"/&gt;
+ &lt;/toc&gt;
+</pre>
+<p>
+See the references section for more information on writing
+and organizing help files, including internationalization.
+</p>
+<p>
+When you're debugging or deploying an RCP application
+that includes help you'll need to include
+several more help related plug-ins
+in addition to those listed in part 1 of the tutorial.
+Here's the current list (subject to change in future versions):
+</p>
+<ul>
+<li><code>org.apache.ant</code>
+<li><code>org.apache.lucene</code>
+<li><code>org.eclipse.help.appserver</code>
+<li><code>org.eclipse.help.base</code>
+<li><code>org.eclipse.help.ui</code>
+<li><code>org.eclipse.help.webapp</code>
+<li><code>org.eclipse.tomcat</code>
+</ul>
+<p>
+See <code>createHelpMenu()</code> in the example for code
+to add the Help Contents action to your Help menu.
+When you select it, this action will fire up a
+help browser like the one shown in figure 2.
+</p>
+
+<img src="images/help.png">
+<p><b>Figure 2. The Rich Client Platform provides a
+full featured online help framework so you don't have to.
+All you do is provide the content.
+</b></p>
+
+<h2>Build.properties</h2>
+<p>
+As you add more resources to your plug-in such as html files,
+icons, the help table of contents, and so forth,
+don't forget to update your build.properties file to
+include all the files and/or directories that need to be
+available to the plug-in at run time.
+Here is the updated build.properties XML file containing everything
+needed for the example in this section:
+</p>
+<pre>
+bin.includes = plugin.xml,\
+ *.jar,\
+ part3.jar,\
+ plugin.properties,\
+ <b>book.xml,\</b>
+ <b>html/,\</b>
+ <b>icons/</b>
+source.part3.jar = src/
+</pre>
+
+<h2>Conclusion</h2>
+<p>
+In this part of the tutorial, we
+added a simple view, some menus, and help files
+to a create a sample RCP application.
+Hopefully you can can use this example as a reference in
+your own projects.
+All the sample code for this part may be viewed at the
+<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.ui.tutorials.rcp.part3">Eclipse project here</a>.
+You can use
+<a href="http://dev.eclipse.org/cvshowto.html">Eclipse's built-in CVS client</a>
+to download the source to your workspace.
+</p>
+<p>
+Congratulations!
+If you made it this far, you are
+well on your way to developing your own
+Rich Client Platform applications.
+Take a look at the references below for more information
+and community sites and mailing lists where
+you can meet other people using RCP.
+</p>
+
+<h2>References</h2>
+<p> <a href="../Article-RCP-1/tutorial1.html"> RCP Tutorial Part 1</a><br>
+ <a href="../Article-RCP-2/tutorial2.html"> RCP Tutorial Part 2</a><br>
+<a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-ui-home/rcp/index.html">
+Eclipse Rich Client Platform</a><br>
+ <a href="../viewArticle/ViewArticle2.html"> Creating an Eclipse View</a><br>
+ <a href="../Online%20Help/help1.htm"> Contributing a Little Help</a><br>
+ <a href="http://www.eclipsepowered.org" target="_blank"> Eclipse Powered (rich
+ client plug-ins and resources)</a><br>
+</p>
+
+<p><small>IBM is trademark of International Business Machines Corporation in the
+United States, other countries, or both.</small></p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or
+registered trademarks of Sun Microsystems, Inc. in the United States, other
+countries, or both.</small></p>
+<p><small>Microsoft and Windows are trademarks of Microsoft Corporation in the
+United States, other countries, or both.</small></p>
+<p><small>Other company, product, and service names may be trademarks or service
+marks of others.</small></p>
+
+</body>
+
+</html>
diff --git a/Article-Resource-deltas/images/Idea.jpg b/Article-Resource-deltas/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Resource-deltas/images/Idea.jpg
Binary files differ
diff --git a/Article-Resource-deltas/images/tag_1.gif b/Article-Resource-deltas/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Resource-deltas/images/tag_1.gif
Binary files differ
diff --git a/Article-Resource-deltas/images/tag_2.gif b/Article-Resource-deltas/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Resource-deltas/images/tag_2.gif
Binary files differ
diff --git a/Article-Resource-deltas/images/tag_3.gif b/Article-Resource-deltas/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Resource-deltas/images/tag_3.gif
Binary files differ
diff --git a/Article-Resource-deltas/images/tag_4.gif b/Article-Resource-deltas/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Resource-deltas/images/tag_4.gif
Binary files differ
diff --git a/Article-Resource-deltas/images/tag_5.gif b/Article-Resource-deltas/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Resource-deltas/images/tag_5.gif
Binary files differ
diff --git a/Article-Resource-deltas/images/tag_6.gif b/Article-Resource-deltas/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Resource-deltas/images/tag_6.gif
Binary files differ
diff --git a/Article-Resource-deltas/images/tag_7.gif b/Article-Resource-deltas/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Resource-deltas/images/tag_7.gif
Binary files differ
diff --git a/Article-Resource-deltas/images/tip.gif b/Article-Resource-deltas/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Resource-deltas/images/tip.gif
Binary files differ
diff --git a/Article-Resource-deltas/images/tree-before.jpg b/Article-Resource-deltas/images/tree-before.jpg
new file mode 100644
index 0000000..77a4b20
--- /dev/null
+++ b/Article-Resource-deltas/images/tree-before.jpg
Binary files differ
diff --git a/Article-Resource-deltas/images/tree-delta.jpg b/Article-Resource-deltas/images/tree-delta.jpg
new file mode 100644
index 0000000..94c8a35
--- /dev/null
+++ b/Article-Resource-deltas/images/tree-delta.jpg
Binary files differ
diff --git a/Article-Resource-deltas/images/tryit.gif b/Article-Resource-deltas/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Resource-deltas/images/tryit.gif
Binary files differ
diff --git a/Article-Resource-deltas/resource-deltas.html b/Article-Resource-deltas/resource-deltas.html
new file mode 100644
index 0000000..3602f04
--- /dev/null
+++ b/Article-Resource-deltas/resource-deltas.html
@@ -0,0 +1,597 @@
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<title>How You've Changed!</title>
+<meta name="Author" content="John Arthorne">
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080" bgcolor="#FFFFFF">
+<div align="right"><font size="-2">Copyright &copy; 2002, 2004 International Business Machines, Inc.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">How You've Changed!</h1>
+<h3 ALIGN="CENTER">Responding to resource changes in the Eclipse workspace</h3>
+<blockquote>
+<b>Summary</b>
+
+<br>
+ Many tools and user interface elements are interested in processing resource
+ changes as they happen. For example, the task list wants to update new or changed
+ markers, the navigator wants to reflect added and deleted resources, and the
+ Java compiler wants to recompile modified Java files. Such notifications are
+ potentially costly to compute, manage and broadcast. The Eclipse Platform resource
+ model includes a series of mechanisms for efficiently notifying clients of resource
+ changes. This article outlines these facilities and gives some examples of their
+ use.<br>
+ <p><b> By John Arthorne, OTI</b> <br>
+ August 23, 2002<br>
+ Updated November 23, 2004 for Eclipse 3.0</p>
+</blockquote>
+<hr width="100%"/>
+
+<A NAME="1"/>
+<h2>Resource change listeners</h2>
+<div align=right><i>A good listener is not only popular everywhere,
+<br>but after a while, he knows something.</i>
+<br>&#8211; Wilson Mizner</div>
+<p>
+The primary method for Eclipse plug-ins to be notified of changes to resources
+is by installing a <i>resource change listener</i>. These listeners are given after-the-fact
+notification of what projects, folders and files changed during the last resource changing operation.
+This provides a powerful mechanism for plug-ins to keep their domain state synchronized
+with the state of the underlying workspace. Since listeners are told exactly what resources
+changed (and how they changed), they can update their model incrementally, which ensures that the time
+taken by the update is proportional to the size of the change, not the size of the workspace.
+</p>
+<p>
+Listeners must implement the
+<a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/IResourceChangeListener.html">
+<code>IResourceChangeListener</code></a> interface, and are registered using the method
+<code>addResourceChangeListener</code> on
+<a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/IWorkspace.html">
+<code>IWorkspace</code></a>. It is also important to remove your resource change listener when it is no longer
+needed, using <code>IWorkspace.removeResourceChangeListener</code>.
+</p><p>
+During a resource change notification, the workspace is locked to prevent further modification
+while the notifications are happening. This is necessary to ensure that all listeners are notified
+of all workspace changes. Otherwise, a change made by one listener would have to be broadcast
+to all other listeners, easily creating the possibility of an infinite loop. There is a special exception
+to this rule for the <code>PRE_BUILD</code> and <code>POST_BUILD</code>
+event types that will be discussed later on.
+</p><p>
+<image src="images/tryit.gif"/> Before we get into the details, let's start with a simple example
+that shows how to add and remove a resource change listener:
+</p>
+<font color='#4444CC'><pre>
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IResourceChangeListener listener = new IResourceChangeListener() {
+ public void resourceChanged(IResourceChangeEvent event) {
+ System.out.println("Something changed!");
+ }
+ };
+ workspace.addResourceChangeListener(listener);
+
+ //... some time later one ...
+ workspace.removeResourceChangeListener(listener);
+</pre></font>
+<A NAME="1a"/>
+<h3>When events are sent and batching changes</h3>
+<p> So when exactly are these change events broadcasted? In our preliminary sketch,
+ we said that they occur after a "resource changing operation". What does this
+ mean? Certain methods in the resources plug-in API directly modify resources
+ in the workspace. The most common examples are creating, copying, moving and
+ deleting files and folders, and modifying file contents. Methods that change
+ resources have the following key phrase in their API Javadoc: </p>
+<font color='#4444CC'><pre>
+ * This method changes resources; these changes will be reported
+ * in a subsequent resource change event.
+</pre></font>
+<p>
+Every method in the resources API that contains such a phrase will trigger the
+broadcast of a resource change event to all listeners. The only exception is when
+the operation doesn't actually change anything in the workspace, for example if
+the operation fails or is canceled before any real changes occur. In this case
+no change events are broadcast. It is important to note
+that the broadcast does not necessarily occur immediately after the method completes.
+This is because a resource changing operation may be <i>nested</i>
+inside of another operation. In this case, notification only occurs after the top-level
+operation completes. For example, calling <code>IFile.move</code> may trigger calls to
+<code>IFile.create</code> to create the new file, and then <code>IFile.delete</code>
+to remove the old file. Since the creation and deletion operations are nested inside
+the move operation, there will only be one notification.
+</p>
+<p>
+<image src = "images/tip.gif"/>
+Clients of the resources API are strongly encouraged to follow this nested operation behavior,
+also called <i>batched changes</i>, for their own high-level operations. This is achieved by wrapping
+the operation code inside an instance of
+<a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/IWorkspaceRunnable.html">
+<code>IWorkspaceRunnable</code></a>, and passing it to
+<code>IWorkspace.run(IWorkspaceRunnable)</code>. Wrapping high-level operations inside
+an <code>IWorkspaceRunnable</code> can lead to a substantial performance improvement,
+because it ensures that only one resource change broadcast occurs, instead of potentially thousands.
+</p>
+<p>
+<image src = "images/tryit.gif"/> Below is an example of an operation that is nested using the
+<code>IWorkspaceRunnable</code> mechanism. In this case, a single resource change event
+will be broadcast, indicating that one project and ten files have been created. To keep it simple,
+progress monitoring and exception handling have been omitted from this example.
+</p>
+<font color='#4444CC'><pre>
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ final IProject project = workspace.getRoot().getProject("My Project");
+ IWorkspaceRunnable operation = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ int fileCount = 10;
+ project.create(null);
+ project.open(null);
+ for (int i = 0; i < fileCount; i++) {
+ IFile file = project.getFile("File" + i);
+ file.create(null, IResource.NONE, null);
+ }
+ }
+ };
+ workspace.run(operation, null);
+</pre></font>
+<p>
+Since Eclipse 3.0, it is no longer <i>guaranteed</i> that an
+<tt>IWorkspaceRunnable</tt> will prevent notifications for the entire duration
+of an operation. The workspace can now decide to perform notifications during an operation
+to ensure UI responsiveness. This is particularly important when several workspace
+modifying operations are running simultaneously. The use of <tt>IWorkspaceRunnable</tt> is still strongly
+encouraged, functioning as a strong hint to the workspace that a set of changes
+is occurring that can be batched. Also in Eclipse 3.0, a background equivant to
+<tt>IWorkspaceRunnable</tt> was introduced.
+<a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/WorkspaceJob.html">
+<code>WorkspaceJob</code></a> will batch a set of workspace changes that occur
+inside a <tt>Job</tt> running in the background. Read the
+<a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/guide/runtime_jobs.htm">
+Concurrency infrastructure</a> documentation for more details on jobs.
+<p>
+A very powerful feature of the resource change infrastructure is that listeners will even
+be notified of changes that occur outside the workspace API. If some external editor
+or tool makes changes to resources in the workspace directly from the filesystem, resource
+change listeners will still receive the same notification describing exactly what changed and
+how they changed. The drawback is that since most operating systems don't have such
+a resource change mechanism of their own, the eclipse workspace may not
+&quot;discover&quot; the change until later on. Specifically, the workspace will not
+send the notification until someone performs a <code>IResource.refreshLocal</code>
+operation on a resource subtree that has changed in the filesystem. After the
+<code>refreshLocal</code> operation, the workspace will send resource change notification
+to all listeners, describing everything that has changed since the last local refresh.
+</p>
+<h3>The contents of a resource change event</h3>
+<div align=right><i>Know how to listen, and you will profit
+<br>even from those who talk badly.</i>
+<br>&#8211; Plutarch</div>
+
+<p>
+Now that we know how to add listeners and when to expect them to be called,
+let's take a closer look at what these change events look like. The object passed
+to a resource change listener is an instance of
+<a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/IResourceChangeEvent.html">
+<code>IResourceChangeEvent</code></a>. The most important bits of information in the event
+are the event <i>type</i>, and the <i>resource delta</i>. The event type is simply an integer that
+describes what kind of event occurred. Listeners are typically mainly interested in the
+<code>POST_CHANGE</code> event type, and that is the one we will focus on here.
+The resource delta is actually the root of a tree of <code>IResourceDelta</code> objects.
+The tree of deltas is structured much like the tree of <code>IResource</code> objects that
+makes up the workspace, so that each delta object corresponds to exactly one resource.
+The top-most delta object, provided by the event object, corresponds to
+the <code>IWorkspaceRoot</code> resource obtained by <code>IWorkspace.getRoot</code>.
+The resource delta hierarchy will include deltas for all affected resources that existed prior to the
+resource changing operation, <b>and</b> all affected resources that existed after the operation.
+Think of it as the union of the workspace contents before and after a particular operation,
+with all unchanged sub-trees pruned out. Each delta object provides the following information:
+<ul>
+<li>The resource it corresponds to.</li>
+<li>The <i>kind</i> of modification (added, removed, or changed).</li>
+<li>The precise nature of the change (the <i>change flags</i>).</li>
+<li>A summary of what markers changed on the resource.</li>
+<li>Deltas for any added, removed, or changed children.</li>
+</ul>
+ <p>
+In the case where a resource has moved, the delta for the destination also supplies the path it
+moved from, and the delta for the source supplies the path it moved to. This allows listeners to
+accurately track moved resources.
+</p>
+<p>
+To give an example of the structure of a resource delta, assume we begin with a workspace
+with the following contents:<br>
+<img src="images/tree-before.jpg"/>
+<p>
+Now, say we perform a workspace operation that does all of the following changes:
+<ul>
+<li>Delete &quot;Folder1&quot;, which causes deletion of &quot;File1&quot; as well.</li>
+<li>Modify the contents of &quot;File2&quot;</li>
+<li>Create a folder called &quot;NewFolder&quot; inside &quot;Project1&quot;</li>
+<li>Create a file called &quot;NewFile&quot; inside &quot;NewFolder&quot;</li>
+</ul>
+This operation will result in a resource delta tree with the following structure:<br>
+<img src="images/tree-delta.jpg"/><br>
+In this diagram, the symbol next to each resource delta represents the kind of
+modification, + for addition, - for removal, * for change. Note that all resources with
+affected children are marked as changed, and that unaffected resources (Project2),
+are not included in the tree.
+<p>
+It is worth giving a bit more detail about what the delta change flags (
+<code>IResourceDelta.getFlags()</code>), are all about. More than one flag
+may be applicable for a given resource, in which case the flag values are masked
+together to form a single flag integer. The following table summarizes the different
+flags and what they signify:
+</p>
+<table BORDER CELLSPACING=2 CELLPADDING=2 >
+<tr>
+<td><b>Constant (on IResourceDelta)</b></td>
+<td><b>Applicable resources</b></td>
+<td><b>What it means</b></td>
+</tr><tr>
+<td><code>CONTENT</code></td>
+<td><code>IFile</code>, <code>IFolder</code></td>
+<td>The filesystem modification timestamp has changed since the last notification.
+<code>IResource.touch()</code> will also trigger a content change notification, even though
+the content may not have changed in the file system.</td>
+</tr><tr>
+<td><code>ENCODING</code></td>
+<td><code>IFile</code>, <code>IFolder</code>, <code>IProject</code></td>
+<td>The character encoding for a file, or for the files inside a container, have changed.
+For listeners that care about the character content of the file, as opposed to the
+raw bytes, this should typically be treated the same as a content change.</td>
+</tr><tr>
+<td><code>MOVED_FROM</code></td>
+<td><code>IFile</code>, <code>IFolder</code>, <code>IProject</code></td>
+<td>The resource was moved from another location. You can find out
+the path it came from by calling <code>IResourceDelta.getMovedFromPath</code>.</td>
+</tr><tr>
+<td><code>MOVED_TO</code></td>
+<td><code>IFile</code>, <code>IFolder</code>, <code>IProject</code></td>
+<td>The resource was moved to another location. The location it was moved to is
+indicated by <code>IResourceDelta.getMovedToPath</code>.</td>
+</tr><tr>
+<td><code>OPEN</code></td>
+<td><code>IProject</code></td>
+<td>The project has either been opened or closed. If the project is now open, then it was
+previously closed, and vice-versa.</td>
+</tr><tr>
+<td><code>TYPE</code></td>
+<td><code>IFile</code>, <code>IFolder</code></td>
+<td>The resource has changed type. If the resource was previously a file then it is now
+a folder, and vice-versa.</td>
+</tr><tr>
+<td><code>MARKERS</code></td>
+<td>All</td>
+<td>The resource's markers have changed. Markers are annotations to resources such as
+breakpoints, bookmarks, to-do items, etc. The method <code>IResourceDelta.getMarkerDeltas()</code>
+is used to find out exactly which markers have changed.</td>
+</tr><tr>
+<td><code>REPLACED</code></td>
+<td><code>IFile</code>, <code>IFolder</code>, <code>IProject</code></td>
+<td>The resource has been replaced by a different resource at the same location
+(i.e., the resource has been deleted and then re-added).</td>
+</tr><tr>
+<td><code>DESCRIPTION</code></td>
+<td><code>IProject</code></td>
+<td>The project description has changed.</td>
+</tr><tr>
+<td><code>SYNC</code></td>
+<td>All</td>
+<td>The resource's synchronization information has changed. Sync info is used to determine
+if a resource is in sync with some remote server, and is not typically of interest to local tools.
+See the API interface
+<a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/ISynchronizer.html">
+<code>ISynchronizer</code></a>
+for more details.</td>
+</tr>
+</table>
+
+<A NAME="1c"/>
+<h3>Other types of events</h3>
+<p>Earlier on we said that the principal type of event is the <code>POST_CHANGE</code> event.
+However, there are some circumstances where listening to other event types is necessary. You can
+register for particular event types using the API method
+<code>IWorkspace.addResourceChangeListener(IResourceChangeListener, int)</code>,
+where the supplied integer is a bit-mask of all event types you want your listener to receive.
+</p>
+<p>The first category of special events are pre-change notifications. Since the <code>POST_CHANGE</code>
+event is broadcast after-the-fact, some valuable information that the listener needs may be missing. In these
+cases, use the <code>PRE_CLOSE</code> and <code>PRE_DELETE</code> events, broadcast before a
+project is closed or deleted. The project in question can be obtained from
+<code>IResourceChangeEvent.getResource</code>. There is no resource delta for these event types. These
+events allow listeners to do important cleanup work before a project is removed from memory. These
+events do not allow listeners to veto the impending operation.
+</p>
+<p>The other special event types are associated with the workspace build mechanism.
+Incremental project builders sometimes require special initialization code to be executed
+before all builds happen, and/or special post-processing after all builds are complete. For
+these reasons, there are <code>PRE_BUILD</code> and <code>POST_BUILD</code> event types.
+These events are similar to <code>POST_CHANGE</code>, as they also provide a resource delta tree
+describing what has changed since the start of the operation. These events are broadcast
+periodically even when autobuild is turned off. Since Eclipse 3.0, these build events no
+longer occur in the same thread that modified the workspace. Instead, they always
+occur in the same thread in which the actual build occurs. Since autobuild occurs in
+a background thread in Eclipse 3.0, so do the surrounding pre- and post-build events.
+Another special characteristic about these events is that listeners are allowed to
+modify resources during the notification. This feature should be used sparingly,
+however, as changing resources during the change event sequence will add extra
+overhead to every operation.
+</p>
+<p>The event types that include resource deltas (<code>POST_CHANGE</code>,
+<code>PRE_BUILD</code>, and <code>POST_BUILD</code>), notify
+listeners of all changes that have happened in the workspace between two discrete
+points in time. It is sometimes difficult to understand what time interval is covered by
+each of these three event types. Conceptually, you can think of the resources plug-in
+"remembering" what the workspace looked like at certain points in time, and a
+resource delta describes the differences between two of these points. The following
+outline of a workspace operation describes what time interval is covered by each of
+the event types:
+<ul>
+<li>Remember workspace state (<IMG SRC="images/tag_1.gif"/>).</li>
+<li>Run the operation.</li>
+<li>Remember workspace state (<IMG SRC="images/tag_2.gif"/>).</li>
+<li>Notify <code>POST_CHANGE</code> listeners of all changes between <IMG SRC="images/tag_1.gif"/>
+and <IMG SRC="images/tag_2.gif"/>.</li>
+</ul>
+If the operation is a build, either an autobuild or a manual build, the sequence looks
+like this:
+<ul>
+<li>Remember the state at the end of the last build operation (<IMG SRC="images/tag_1.gif"/>).</li>
+<li>Remember current workspace state (<IMG SRC="images/tag_2.gif"/>).</li>
+<li>Notify <code>PRE_BUILD</code> listeners of all changes between <IMG SRC="images/tag_1.gif"/>
+and <IMG SRC="images/tag_2.gif"/>.</li>
+<li>Run the build operation.</li>
+<li>Remember workspace state (<IMG SRC="images/tag_3.gif"/>).</li>
+<li>Notify <code>POST_BUILD</code> listeners of all changes between <IMG SRC="images/tag_1.gif"/>
+and <IMG SRC="images/tag_3.gif"/>.</li>
+<li>Remember workspace state (<IMG SRC="images/tag_4.gif"/>).</li>
+<li>Notify <code>POST_CHANGE</code> listeners of all changes between <IMG SRC="images/tag_2.gif"/>
+and <IMG SRC="images/tag_4.gif"/>.</li>
+<li>Close the circle by remembering the state at the end of this build operation (<IMG SRC="images/tag_1.gif"/>).</li>
+</ul>
+<p>
+It is important to note that the time intervals covered by the different event types are overlapping. It is generally
+not useful for a single listener to listen to more than one of these event types at once. Choose the event type
+that applies for your situation, and register for only that event type when adding your listener. If you do need
+to listen to more than one event type, keep in mind that the provided deltas will describe overlapping sets
+of changes. This is one of the reasons why <code>POST_CHANGE</code> is the most generally useful
+event type, because its delta will always describe <b>all</b> changes since the last <code>POST_CHANGE</code>
+event notification. <code>PRE_BUILD</code> and <code>POST_BUILD</code> events, on
+the other hand, will not always receive notification of every change.
+</p>
+
+<A NAME="1d"/>
+<h3>Tips and tricks for listener implementers</h3>
+<div align=right><i>Listen to everything, forget much, correct little.</i>
+<br>&#8211;Pope John XXIII </div>
+<p>
+<b>Performance.</b> Listeners should be lightweight and fast. Change notifications
+can occur quite frequently during typical use of the platform, so your listener must do its work
+in a timely fashion. This is not an appropriate place, for example, to be contacting servers
+or performing disk I/O. If you have expensive operations that can be triggered as a result
+of resource changes, consider posting the work to a background thread, or queuing the
+work until a time that is more convenient for your users. For example, the "Java Development
+Tools" (JDT) plug-ins provide a search engine that indexes Java source and JAR files to allow for more
+efficient searches. When these files change, the search engine must rebuild the indexes for
+these files. The JDT plug-ins use a resource change listener to collect the list of changed resources,
+and then posts that list to a background thread that rebuilds the indexes.
+</p>
+<p>
+In the interest of making resource change listeners faster, some convenience methods exist
+on <code>IResourceDelta</code> and <code>IResourceChangeEvent</code> that allow you to
+do your updates faster. If you are only interested in changes to a single resource (or a very small set
+of resources), you can use <code>IResourceDelta.findMember(IPath)</code> to quickly locate the
+resource you are interested in updating. The supplied path is considered as relative to the path
+of the resource delta that it is called on.
+Another common case is resource change listeners that are only interested in processing changes
+to markers (
+<a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/IMarker.html">
+<code>IMarker</code></a> objects). These listeners can use
+<code>IResourceChangeEvent.findMarkerDeltas</code> to quickly collect all changed markers
+of a given type.
+<p>
+There is also a visitor mechanism (<code>IResourceDelta.accept(IResourceDeltaVisitor)</code>)
+for easily processing all changed resources in a given sub-tree. However, visitors should only
+be used where appropriate. Using a visitor to process two or three resources doesn't
+make sense, as the overhead of visiting the entire delta tree is incurred for no good reason.
+Since it's so easy to write a visitor, there is a tendency for programmers to use them too
+liberally, even in cases where they only want to process a well-defined subset of a tree.
+The return value from the visitor's visit method is used to indicate if that resource's children should be
+traversed. This can be used to short-circuit the traversal to avoid visiting sub-trees that you know
+you are not interested in.
+</p>
+<p>
+<b>Thread safety.</b> There are some multi-threading issues to keep in mind when
+writing listeners. First, you have no control over what thread your listener will run in.
+Workspace operations can occur in any thread, and resource change listeners will
+run in whatever thread that triggered the operation. So, if some of your update code
+<b>must</b> be run in a particular thread, you'll have to make sure your code gets
+posted to that thread. The most common example of this is UI updates. With the
+Standard Widget Toolkit (SWT), the UI toolkit that is included with Eclipse, there is
+only a single UI thread per display. If your resource change
+listener needs to update the UI, you will need to use the methods <code>syncExec</code>
+or <code>asyncExec</code> in class <code>org.eclipse.swt.widgets.Display</code> to
+post the update code to the UI thread.
+</p>
+<p>
+If any of your update code runs asynchronously (i.e., you used <code>asyncExec</code> or some
+similar mechanism to post your code to another thread), there is another consideration to
+keep in mind. The resource delta objects supplied to your listener are designed to "expire"
+when the <code>resourceChanged</code> method returns. So, if you pass references
+to <code>IResourceDelta</code> objects to another thread, they may cause failures if
+they are accessed after the listener method has returned back in the other thread. The reason
+for this resource delta "expiry date", is to ensure that listeners don't hold onto resource delta
+references indefinitely. These delta structures are potentially quite large, and if a listener
+holds onto them, it essentially causes a memory leak because these structures can no longer
+be garbage collected.
+</p>
+
+<A NAME="1e"/>
+<h3>A sample resource change listener</h3>
+<p>
+<image src="images/tryit.gif"/>
+Let's tie together everything we've learned so far with a working example. This example shows a
+resource change listener that listens for changes to text files in a particular project's documentation
+directory. The list of changed files is collected, and then an update is posted to a JFace
+<code>TableViewer</code> that contains an index of text files. The listener would normally
+process added and removed text files in a similar way, but for the sake of space we'll just
+deal with changed files here.
+</p>
+<font color='#4444CC'><pre>
+ public class DocIndexUpdater implements IResourceChangeListener {
+ private TableViewer table; //assume this gets initialized somewhere
+ private static final IPath DOC_PATH = new Path("MyProject/doc");
+ public void resourceChanged(IResourceChangeEvent event) {
+ //we are only interested in POST_CHANGE events
+ if (event.getType() != IResourceChangeEvent.POST_CHANGE)
+ return;
+ IResourceDelta rootDelta = event.getDelta();
+ //get the delta, if any, for the documentation directory
+ IResourceDelta docDelta = rootDelta.findMember(DOC_PATH);
+ if (docDelta == null)
+ return;
+ final ArrayList changed = new ArrayList();
+ IResourceDeltaVisitor visitor = new IResourceDeltaVisitor() {
+ public boolean visit(IResourceDelta delta) {
+ //only interested in changed resources (not added or removed)
+ if (delta.getKind() != IResourceDelta.CHANGED)
+ return true;
+ //only interested in content changes
+ if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
+ return true;
+ IResource resource = delta.getResource();
+ //only interested in files with the "txt" extension
+ if (resource.getType() == IResource.FILE &&
+ "txt".equalsIgnoreCase(resource.getFileExtension())) {
+ changed.add(resource);
+ }
+ return true;
+ }
+ };
+ try {
+ docDelta.accept(visitor);
+ } catch (CoreException e) {
+ //open error dialog with syncExec or print to plugin log file
+ }
+ //nothing more to do if there were no changed text files
+ if (changed.size() == 0)
+ return;
+ //post this update to the table
+ Display display = table.getControl().getDisplay();
+ if (!display.isDisposed()) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ //make sure the table still exists
+ if (table.getControl().isDisposed())
+ return;
+ table.update(changed.toArray(), null);
+ }
+ });
+ }
+ }
+ }</pre></font>
+<p>
+Observe how the <code>findMember</code> convenience method is used to find the child
+delta for the documentation folder, and then a visitor is used to collect the changes in that sub-tree.
+It is safe to use <code>asyncExec</code> here, because we have
+already pulled the relevant information out of the resource deltas. You should always use
+the <code>isDisposed</code> check inside an <code>asyncExec</code>. Even if the table
+exists at the time the <code>asyncExec</code> is called, there may be another item in the event
+queue that will dispose the table before this event can be processed.
+</p>
+<br>
+<A NAME="2"/>
+<h2>Save participants</h2>
+<p>
+When plug-in writers implement their first resource change listener, they often encounter
+a dilemma caused by Eclipse's lazy plug-in loading behavior. Since plug-in activation
+may occur well after the workspace has started up, there is no opportunity add a resource
+change listener when the workspace is first started. This causes a "blind spot" for listeners,
+because they cannot process changes that occur between the time of workspace creation and
+the time when their plug-in is activated.
+</p>
+<p>The solution to this problem is to take advantage of the save participant mechanism.
+ Save participants implement the <a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/ISaveParticipant.html">
+ <code>ISaveParticipant</code></a> interface, and are installed using <code>IWorkspace.addSaveParticipant</code>.
+ The main purpose of save participants is to allow plug-ins to save their important
+ model state at the same time that the workspace saves its state. This ensures
+ that the persisted workspace state stays synchronized with any domain model
+ state that relies on it. Once a save participant is registered with the workspace,
+ subsequent calls to <code>addSaveParticipant</code> will return an <a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/ISavedState.html">
+ <code>ISavedState</code></a> object. By passing a resource change listener to
+ <code>ISavedState.processResourceChangeEvents</code>, participants are given
+ the opportunity to process the changes that have occurred since the last save
+ occurred. This fills in the "blind spot" between workspace startup and activation
+ of the plug-in that the listener belongs to. To find out about other facilities
+ provided by the save participant mechanism, read the API Javadoc for <a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/ISaveParticipant.html">
+ <code>ISaveParticipant</code></a>, <a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/ISavedState.html">
+ <code>ISavedState</code></a>, and <a href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/resources/ISaveContext.html">
+ <code>ISaveContext</code></a>. </p>
+<br>
+
+<A NAME="3"/>
+<h2>Incremental project builders</h2>
+<p> <i>Builders</i> are another mechanism provided by the platform core for processing
+ resource changes. Where change listeners are intended as a light-weight update
+ mechanism, builders are designed to be a more powerful and flexible way of processing
+ resource changes. Although builders are discussed in greater detail in a companion
+ <a href="../Article-Builders/builders.html">builder article</a>, it is useful
+ to know about the major differences between resource change listeners and builders:
+<ul>
+ <li>Builders are always allowed to modify the workspace.
+ </li>
+ <li>Builders have support for progress monitoring, cancellation, and error reporting.
+ </li>
+ <li>Listeners operate on the entire workspace; builders are installed on a per-project basis.
+ </li>
+ <li>Builders are run in a concrete order that can be specified individually
+ on each project. Builders can enforce dependency relationships with other
+ builders (my builder must run after the "Foo" builder). Projects are also built in a specified order.
+ With resource change listeners, there is no way to ensure or even discover the order in which listeners
+ receive the change events.
+ </li>
+ <li>There are different build policies: incremental build, full build, and auto-build.
+ </li>
+ <li>Builder lifecycle and persistence is managed by the platform. Once a builder is installed
+ on a project, it will remain on that project across sessions.
+ </li>
+ <li>Builder configurations can easily be shared with other users, since the information
+ is contained in the shareable project description file (called ".project").
+ </li>
+</ul>
+<p> These differences aside, the principle behind project builders and resource
+ change listeners is the same. Builders are provided with a similar <code>IResourceDelta</code>
+ hierarchy that describes what has changed since the last time that builder was
+ called. This gives builders a chance to incrementally update the resources they
+ operate on in response to changes made by others. For more details on builders,
+ see the eclipse.org article <a href="../Article-Builders/builders.html">Project
+ Natures and Builders</a>. </p>
+<br>
+<A NAME="4"/>
+<h2>Summary</h2>
+<p>
+The Eclipse workspace provides a powerful suite of tools to allow plug-ins to keep notified
+and up to date when resources change. By installing a resource change listener, plug-ins
+are incrementally notified after any set of changes to the workspace, and are supplied
+with a resource delta tree that describes all the changes that have happened. Resource
+change listeners can also be notified when projects are about to be deleted or closed,
+or before and after auto-builds happen. The save participant mechanism can be used for
+notification about what happened before your plug-in was activated. The builder framework,
+discussed in more detail in another article, provides a more powerful mechanism for
+processing changed resources in a project.
+</p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+</body>
+</html> \ No newline at end of file
diff --git a/Article-Rule Modeling With EMF/BallPlacementRuleModel.zip b/Article-Rule Modeling With EMF/BallPlacementRuleModel.zip
new file mode 100644
index 0000000..aa1ab6a
--- /dev/null
+++ b/Article-Rule Modeling With EMF/BallPlacementRuleModel.zip
Binary files differ
diff --git a/Article-Rule Modeling With EMF/RuleMetaModel.zip b/Article-Rule Modeling With EMF/RuleMetaModel.zip
new file mode 100644
index 0000000..2da5fe1
--- /dev/null
+++ b/Article-Rule Modeling With EMF/RuleMetaModel.zip
Binary files differ
diff --git a/Article-Rule Modeling With EMF/article.html b/Article-Rule Modeling With EMF/article.html
new file mode 100644
index 0000000..d6f57d0
--- /dev/null
+++ b/Article-Rule Modeling With EMF/article.html
@@ -0,0 +1,614 @@
+<html xmlns:o>
+ <head>
+ <title>Modeling Rule-Based Systems with EMF</title>
+ <meta content="True" name="vs_showGrid">
+ <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+ <LINK href="../default_style.css" rel="stylesheet"></head>
+ <body vLink="#800080" link="#0000ff">
+ <div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ © 2004&nbsp;Chaur G. Wu. All rights reserved.</font>&nbsp;
+ <table cellSpacing="0" cellPadding="2" width="100%" border="0">
+ <tr>
+ <td vAlign="top" align="left" bgColor="#0080c0" colSpan="2"><b><font face="Arial,Helvetica"><font color="#ffffff">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+ </div>
+ <div align="left">
+ <h1><IMG height="86" src="images/Idea.jpg" width="120" align="center"></h1>
+ </div>
+ <p>&nbsp;</p>
+ <h1 align="center">Modeling Rule-Based Systems with EMF</h1>
+ <blockquote>
+ <P><b>Summary</b></P>
+ <P>There are examples of meta-models defined in ECore for modeling objects and
+ relational data. However, not much has been said about how to model rules. This
+ article will define a meta-model in ECore for modeling rule-based systems. We
+ will then use the meta-model to model the solution of a logical problem. Then
+ we will compose some JET templates and generate code from the model, run the
+ generated code through a rule engine and see that the logical problem is
+ correctly solved.
+ </P>
+
+ <p><b>By Chaur G. Wu, Independent Consultant</b> (cha_urwu@hotmail.com)<br>
+ <font size="-1">November 30, 2004</font> </p>
+ </blockquote>
+ <hr width="100%">
+ <P>Before we look at this article’s example, let’s set the stage by going through
+ some&nbsp;background information and make clear some terms that we will use
+ throughout the&nbsp;article. In this part, we will give very brief introduction
+ of rule-based systems and meta-modeling.
+ </P>
+ <H2>Rule-Based Systems</H2>
+ <P>
+ So what do we mean by rule-based? In the evolution course of computing, a field
+ called artificial intelligence was developed in the 70s&nbsp;and 80s with an
+ aim to make computers reason like human beings. Rule-based programming paradigm
+ emerged at that time as&nbsp;ways to implement systems that appear to think and
+ reason like human beings. Examples of rule-based systems are expert systems
+ that have the knowledge of a doctor or a tax advisor and can answer complex
+ questions&nbsp;people would normally ask those professionals.
+ </P>
+ <P>The idea of rule-based programming is to represent a domain expert’s knowledge
+ in a form called rules. That’s why it’s called rule-based. Besides rules,
+ another important ingredient in a rule-based system is facts. Here’s an
+ example. Say John is a weather reporter who gives advice to people on TV
+ channels based on weather conditions. Here’s John’s knowledge about weather:
+ </P>
+ <ol>
+ <li>
+ If it’s a rainy day, advise people to bring umbrellas when they go out.
+ <li>
+ If it’s a rainy day, the road would be slippery because of the rain and hence
+ warn people to drive more carefully.
+ </li>
+ </ol>
+ <P>How do we represent the knowledge in a rule-based system? We represent it as
+ rules and facts like this:
+ </P>
+ <pre> Rule 1: If it’s a rainy day, advise people to bring umbrellas when they go out.
+ Rule 2: If the road is slippery, warn people to drive more carefully.
+ Rule 3: If it’s a rainy day, road is slippery.</pre>
+ <PRE> Fact 1: It’s a rainy day.
+ Fact 2: Road is slippery.</PRE>
+ <P>Here’s how our imaginary expert system mimics the reasoning capability of
+ weather reporter John. If by looking out of the window, we see it’s raining, we
+ tell our expert system that it’s raining by asserting fact number 1.
+ Immediately the expert system tries to match the asserted fact with its three
+ rules. Rules 1 and 3 are fired because the asserted fact satisfies their
+ conditions (the <EM>if</EM> clause). When rule one is fired (a more accurate
+ term is activated), the system advises people to bring umbrella as if it were a
+ real weather reporter. Firing rule 3 asserts fact 2. And because fact 2
+ satisfies the conditions of rule 2, rule 2 is fired and the system advises
+ people to drive more carefully. All these chain reactions happen in sequence as
+ the result of asserting fact number 1.
+ </P>
+ <P>Although the example is nowhere close to the complexity of a practical
+ rule-based system, it shows the following key points:
+ </P>
+ <ol>
+ <li>
+ A rule-based system consists mainly of&nbsp;three things: facts, rules and an
+ engine that acts on them.
+ <li>
+ Rules represent knowledge and facts represent data. A rule-based system solves
+ problems by applying rules on facts (i.e. matching facts with rules’ <EM>if</EM>
+ clauses).&nbsp;
+ <li>
+ A rule consists of two parts: conditions (<EM>if</EM>
+ clauses) and actions.&nbsp;
+ <li>
+ The action part of a rule might assert new facts that fire other rules.
+ </li>
+ </ol>
+ <P>Among the most popular rule engines, <STRONG>JESS (Java Expert System Shell)</STRONG>
+ is probably of the most interest to Java developers. It is&nbsp;the reference
+ implementation of JSR 094 Java Rule Engine API and it has&nbsp;plug-ins to
+ support development of rule systems in Eclipse. Therefore, the rule code we
+ will see&nbsp;in this article will be&nbsp;in JESS's&nbsp;syntax. Before we
+ leave this section, it’s helpful to introduce JESS&nbsp;and take a glimpse of
+ its programming syntax. JESS is software that interprets rules and facts
+ expressed in its programming language. Just as Java is a language for
+ expressing objects and Java compiler is software that interprets Java code,
+ JESS has a language for expressing rules and facts and a compiler to interpret
+ the code. JESS is developed in Java by Ernest Friedman-Hill at Sandia National
+ Laboratories. Here’s what the rules and facts in our weather example look like
+ in JESS code.</P>
+ <PRE>(defrule rule-1 (rainy-day) = &gt; (advise-people bring-umbrella))
+(defrule rule-2 (road-slippery) =&gt; (advise-people drive-carefully))
+(defrule rule-3 (rainy-day) =&gt; (assert road-slippery))
+(road-slippery)
+(rainy-day)</PRE>
+ <P>The last two lines in the list above are the two facts. The first three lines
+ are the three rules. Rules in&nbsp;JESS&nbsp;take this form: <b><CODE>(defrule
+ rule-name conditions =&gt; actions)</CODE></b> Rules are defined using
+ the <code>defrule</code> construct. <code>rule-1</code>, <code>rule-2</code>,
+ and <code>rule-3</code> are the names of the rules respectively. <code>rule-1</code>
+ has a condition: <code>(rainy-day)</code>. In this case, <code>(rainy-day)</code>
+ is also called a <b>pattern</b>.&nbsp;It&nbsp;is so called&nbsp;because the
+ rule engine&nbsp;treats it as a pattern for matching facts. The pattern <code>(rainy-day)</code>
+ in <code>rule-1</code> will match only one fact: the <code>(rainy-day)</code> fact
+ in the last line of the code list. When it's matched, the action <code>(advise-people
+ bring-umbrella)</code> of <code>rule-1</code> will be executed.</P>
+ <P>There are a lot more to the syntax of&nbsp;a rule&nbsp;language like JESS. We
+ will only explain those necessary for following along this article. For
+ more&nbsp;details, you can refer to the documentation that comes with JESS.</P>
+ <H2>Model, Meta-model, Meta-metamodel
+ </H2>
+ <P>Sometimes it’s helpful to the discussion if we categorize models into different
+ levels. We call a model a <b>meta-model</b> if it is used to define models. We
+ call a model a <b>meta-metamodel</b> if it is used to define meta-models.
+ </P>
+ <P>For example, ECore is a model. It can be a meta-model or a meta-metamodel
+ depending on how we use it. When we use ECore to define models of a purchase
+ order system, it plays the role of a meta-model. The Rule Meta Model we will
+ develop later in this article is another example of meta-model. It is a
+ meta-model because we will use it to define a model for a logical problem.
+ </P>
+ <P>The Rule Meta Model we will develop later is defined in ECore. In this sense,
+ ECore is a meta-metamodel because it is used to define a meta-model. Another
+ example of ECore as a meta-metamodel is EMF’s Gen Model. EMF’s Gen Model is a
+ meta-model that defines models concerning how code is generated. ECore is the
+ meta-metamodel that defines Gen Model.
+ </P>
+ <P>When we say model A defines model B, in a practical sense, we mean that all
+ model elements in B are instances of model elements in A. We will see this in
+ effect later when we reach the article’s example. For the purpose of this
+ article, the important facts to note are:
+ </P>
+ <ol>
+ <li>
+ Categorization of meta levels is not absolute.
+ <li>
+ We will use ECore as a meta-metamodel to define the Rule Meta Model.
+ <li>
+ Model elements in the Rule Meta Model will be instances of model elements in
+ ECore.
+ <li>
+ We will use the Rule Meta Model to define a model for a logical problem.
+ Elements in the model will be instances of model elements in the Rule Meta
+ Model.
+ <LI>
+ Meta-metamodels are also referred to as M3 models; meta-models as M2 models;
+ models like a bank application model as M1 models.
+ </LI>
+ </ol>
+ <H2>Problem Statement
+ </H2>
+ <P>The logical problem&nbsp;we will solve with this article’s Rule Meta Model is
+ this:
+ </P>
+ <P>There are four boxes, labeled from 1 to 4. We have four balls in four colors:
+ red, blue, green and yellow. Our task is to put one ball in each box according
+ to the following three constraints.
+ </P>
+ <ol>
+ <li>
+ If red ball is in box 1, blue ball must be in box 3.
+ <li>
+ If yellow ball is not in box 2, green ball must be in box 3.
+ <li>
+ Green ball cannot be in box 4 and Red ball cannot be in box 2.
+ </li>
+ </ol>
+ <H2>Set up Environment and Run the Example Code
+ </H2>
+
+<P>The solution to the problem is in <A href="RuleMetaModel.zip">RuleMetaModel.zip</A>
+ and <A href="BallPlacementRuleModel.zip">BallPlacementRuleModel.zip</A> that come
+ with this article. The code in the zip files requires the following software.
+</P>
+
+<PRE>Java Runtime or SDK (The one I use is Java SDK 1.4.2 from Sun Microsystems)
+Eclipse (The version I use is Eclipse SDK 3.0)
+EMF (The version I use is EMF SDK 2.0.1 RC2)
+JESS 7.0a1</PRE>
+
+<P>Installing JESS is simple.&nbsp;You can download JESS&nbsp;from <A href="http://herzberg.ca.sandia.gov/jess/download.shtml" target="_blank">
+ http://herzberg.ca.sandia.gov/jess/download.shtml</A>. Then unzip the downloaded&nbsp;file
+ to a folder, add jess.jar to your java classpath and you are ready to go. JESS
+ is not free software. After clicking the link above, you’ll be asked to enter
+ your name, company and email. After that, you’ll be taken to the page where
+ you can download various versions of JESS. The one to download for this article
+ is trial version 7.01a1. This version of JESS comes with some Eclipse plug-ins
+ for editing JESS code in the Eclipse IDE. Those plug-ins are not needed for
+ running the code of this article. Installing them is optional. </P>
+
+<P>To install and run the example for this article, unzip <A href="RuleMetaModel.zip">RuleMetaModel.zip</A>
+ into your <I>plugins/ </I>subdirectory. This zip&nbsp;file contains three plug-ins.
+ They are the model, edit, editor plug-ins EMF generates for our Rule Meta Model.
+ The other zip file, <A href="BallPlacementRuleModel.zip">BallPlacementRuleModel.zip</A>,
+ contains two files: <code>BallPlacement.rulemetamodel</code> and <code>BallPlacement.clp</code>.
+ <code>BallPlacement.rulemetamodel</code> is the model that models our logical
+ problem. It is defined using Rule Meta Model. The other file <code>BallPlacement.clp</code>
+ is JESS code generated from <code>BallPlacement.rulemetamodel</code>. Below
+ is a pictorial view of all the components in the two zip files and how they
+ relate to EMF and rule engine.</P>
+ <P><b>Figure 1. Overall picture of the example code.</b></P>
+ <P><IMG alt="" src="images/Overall.gif"></P>
+ <P>
+ </P>
+
+<P>We will explain each component as we go along. For now, since we already have
+ JESS rule engine set up, let's run <code>BallPlacement.clp</code> through the
+ JESS rule engine (the yellow part in Figure 1). Assume that you unzipped the
+ two files in <code>BallPlacementRuleModel.zip</code> to <code>C:\</code> and
+ that <code> jess.jar</code> is in your java classpath. Here is the command to
+ run <code>BallPlacement.clp</code> through the JESS rule engine: </P>
+ <P><IMG height="13" src="images/tryit.gif" width="61"> <code>java jess.Main
+ C:\BallPlacement.clp</code></P>
+ <P>The result you will see in the command console will look like the screenshot
+ below. Dumping the result to a console window like this is not pretty but it
+ serves our purpose just fine. The last four&nbsp;facts listed in the screenshot
+ are solutions to the logical problem. That is, out of the 24 possible
+ placements of the balls in the boxes, only&nbsp;four placements satisfy the
+ three constraints posed by our problem.&nbsp;&nbsp;</P>
+ <P><IMG alt="" src="images/BallPlacementResult.gif"></P>
+ <H2>BallPlacement.clp
+ </H2>
+ <P>Before we look more closely at the Rule Meta Model and Ball Placement Model,
+ let’s see what constitutes a rule language by taking a look at <code>BallPlacement.clp</code>
+ first. This knowledge will help us make sense of the meta-model and model
+ later. <code>BallPlacement.clp</code> defines two fact templates: <IMG height="13" src="images/tag_1.gif" width="24" align="center">&nbsp;<code>placement</code>
+ and <IMG height="13" src="images/tag_2.gif" width="24" align="center">&nbsp;<code>ball</code>.&nbsp;
+ </P>
+ <PRE><IMG height=13 src="images/tag_1.gif" width=24 align=center>(deftemplate placement
+ (slot box_one)
+ (slot box_two)
+ (slot box_three)
+ (slot box_four))
+
+<IMG height=13 src="images/tag_2.gif" width=24 align=center>(deftemplate ball (slot color))</PRE>
+ <P>A <b>fact template</b> as its name suggests is a template of facts and is
+ defined by the <code>deftemplate</code> construct in JESS. Earlier we wrote the
+ weather fact like this: <code>(rainy-day)</code>. If we want to specify
+ temperature in addition to weather, we’ll probably write a fact like this: <code>(rainy-day
+ 50F)</code>. Facts like these are called <b>ordered facts</b> because they
+ require their elements to be in a specific order. <code>(rainy-day 50F)</code> is
+ a different fact from <code>(50F rainy-day)</code> because the elements are in
+ a different order. Sometimes it’s desirable to have some structure in the way
+ we state facts so that we can express elements in a fact regardless of their
+ positions. This is where fact templates come into play. With fact templates, we
+ can state facts like this: <code>(weather-report (weather rainy-day) (temperature
+ 50F))</code>. We say that the <code>weather-report</code> fact has two <b>slots</b>:
+ <code>weather</code> and <code>temperature</code>. Slot <code>weather</code> has
+ a value of <code>rainy-day</code> and slot <code>temperature</code> has a value
+ of <code>50F</code>. It doesn’t matter if you put the <code>temperature</code> slot
+ before or after the <code>weather</code> slot. Facts like this are called <b>unordered
+ facts</b> because the order of their elements is not relevant.
+ </P>
+ <P>In our example, the <code>placement</code> fact template defines four slots, one
+ for each box. The <code>ball</code> fact template defines one slot: <code>color</code>.
+ With these two fact templates, we can state the fact that "green ball is in box
+ one"&nbsp;in JESS language like this: <code>(placement (box_one Green))</code>.
+ Besides fact templates, <code>BallPlacement.clp</code> has&nbsp;a
+ few&nbsp;rules. Here's the rule that describes the first constraint about ball
+ placement.</P>
+ <pre>(defrule placement_constraint1
+<IMG height=13 src="images/tag_1.gif" width=24 align=center> ?placement &lt;- (placement (box_one ?box_one) (box_two ?box_two) (box_three ?box_three) (box_four ?box_four))
+<IMG height=13 src="images/tag_2.gif" width=24 align=center> (and (placement (box_one ?box_one&amp;Red) (box_two ?box_two) (box_three ?box_three) (box_four ?box_four))
+ (placement (box_one ?box_one) (box_two ?box_two) (box_three ?box_three&amp;~Blue) (box_four ?box_four)))
+=&gt;
+<IMG height=13 src="images/tag_3.gif" width=24 align=center>
+ (retract ?placement))</pre>
+ <P>
+ We have seen rules in the weather report metaphor.&nbsp;We know <code>placement_constraint1</code>
+ is the name of the&nbsp;rule. <IMG height="13" src="images/tag_1.gif" width="24" align="center">&nbsp;<IMG height="13" src="images/tag_2.gif" width="24" align="center">&nbsp;are
+ the conditions of the rule and <IMG height="13" src="images/tag_3.gif" width="24" align="center">&nbsp;is
+ the action. Condition <IMG height="13" src="images/tag_1.gif" width="24" align="center">&nbsp;assigns&nbsp;what
+ looks like a&nbsp;pattern to the <code>?placement</code> variable. In fact,
+ what actually gets assigned to the <code>?placement</code> variable is a fact
+ that matches the pattern. In JESS, variable names start with <EM>?</EM> . <code>?box_one</code>,
+ <code>?box_two</code> in the code list above&nbsp;are all variables. Variables
+ are not typed. You can assign strings, integers, facts and values of other data
+ types to them. Assigning a value to a variable is usually done through the <code>bind</code>
+ function like this:
+ </P>
+ <P><code>(bind ?variable "some string value")</code></P>
+ <P>However, using <code>bind</code> function to assign a value to a variable is an
+ action not a condition.&nbsp;That's why in&nbsp;<IMG height="13" src="images/tag_1.gif" width="24" align="center">,&nbsp;instead
+ of using the <code>bind</code> function in the condition part of a rule, we
+ use&nbsp;a special form called <b>pattern binding</b> <code>&lt;-</code> to
+ assign a fact to the <code>?placement</code> variable.&nbsp;
+ </P>
+ <P>Condition <IMG height="13" src="images/tag_2.gif" width="24" align="center">&nbsp;has
+ two fact matching patterns enclosed in a logical <code>and</code>. The logical <code>
+ and</code> is called a <b>conditional element</b> in a rule
+ language.&nbsp;Don't worry if the two conditions&nbsp;still look cryptic. Let's
+ mimic the reasoning process of a rule engine and you will see how&nbsp;the
+ conditions&nbsp;function.&nbsp;Let's see what happens if we put&nbsp;the
+ following fact in the rule engine:</P>
+ <P><code>(placement (box_one Red) (box_two Blue) (box_three Green) (box_four Yellow))</code></P>
+ <P>The rule engine tries to see if the fact satisfies the two conditions of <code>placement_constraint1</code>.
+ It first tries to match the fact with the pattern in <IMG height="13" src="images/tag_1.gif" width="24" align="center">.&nbsp;The
+ pattern in <IMG height="13" src="images/tag_1.gif" width="24" align="center">&nbsp;has
+ one variable in each of the four slots of&nbsp;the <code>placement</code> fact.&nbsp;That
+ means the pattern matches any value in those four slots.&nbsp;So the fact
+ satisfies the first condition and <code>Red</code> is assigned to <code>?box_one</code>,
+ <code>Blue</code> to <code>?box_two</code>, <code>Green</code> to <code>?box_three</code>
+ and <code>Yellow</code> to <code>?box_four</code>.
+ </P>
+ <P>But this is not enough to trigger the execution of <code>placement_constraint1</code>'s
+ action. The rule engine sees that there's a second condition in the rule. So it
+ tries to see if the same fact matches the second condition's patterns. The
+ first pattern in&nbsp;<IMG height="13" src="images/tag_2.gif" width="24" align="center">&nbsp;says
+ that <code>box_one</code> must be&nbsp;<code>?box_one</code> and <code>Red</code>
+ (<code>?box_one&amp;Red</code>) and the other three slots can have any values
+ that are assigned to the three variables <code>?box_two</code>, <code>?box_three</code>
+ and <code>?box_four</code> respectively. The rule engine already knows from the
+ first condition that <code>?box_one</code> is <code>Red</code>. So <code>(?box_one&amp;Red)</code>
+ is no contradiction (Red is Red). The fact satisfies the first pattern of <IMG height="13" src="images/tag_2.gif" width="24" align="center">.
+ Because of the <code>and</code> conditional element, the&nbsp;second pattern
+ in&nbsp;<IMG height="13" src="images/tag_2.gif" width="24" align="center">&nbsp;needs
+ to&nbsp;match the fact&nbsp;too for the whole condition to be considered
+ satisfied. The second pattern in <IMG height="13" src="images/tag_2.gif" width="24" align="center">&nbsp;says
+ that <code>box_three</code> must be&nbsp;<code>?box_three</code> and not <code>Blue</code>
+ (<code>?box_three&amp;~Blue</code>) and the other three slots can have any
+ values that are assigned to&nbsp;the three variables <code>?box_one</code>, <code>?box_two</code>
+ and <code>?box_four</code> respectively. The rule engine already know from the
+ first condition that <code>?box_three</code> is <code>Green</code>. So <code>(?box_three&amp;~Blue)</code>
+ is no contradiction (Green is not Blue). The fact satisfies the&nbsp;second
+ pattern of <IMG height="13" src="images/tag_2.gif" width="24" align="center">&nbsp;as
+ well.</P>
+ <P>So all conditions are satisfied. The action of <code>placement_constraint1</code>
+ will execute because of the assertion of the fact. What the action does is
+ remove the matching fact from the rule engine. Why? Because all placement facts
+ that satisfy the conditions of any one of the three constraint rules in <code>BallPlacement.clp</code>
+ are not solutions to our logical problem. We remove them from the rule engine's
+ fact list so that the ones remaining will be our solutions.</P>
+ <H2>Rule Meta Model
+ </H2>
+ <P>Now that we know the basic constructs such as <EM>patterns</EM>, <EM>actions</EM>,
+ <EM>rules</EM>, <EM>facts</EM> of a rule language, it's time to see how we
+ model them in a meta-model; that is, the blue part in Figure 1. Our Rule Meta
+ Model consists of a package, a few data types, enumerations and classes. As we
+ said earlier,&nbsp;Rule Meta Model is defined in ECore and by that we mean all
+ model elements in&nbsp;Rule Meta Model are instances of model elements in
+ ECore. The one and only package in the Rule Meta Model is an instance of
+ ECore’s <code>EPackage</code>; the data types instances of ECore’s <code>EDataType</code>;
+ the enumerations instances of ECore’s <code>EEnum</code> and the classes
+ instances of ECore’s <code>EClass</code>.
+ </P>
+ <P>Below is a screenshot of how Rule Meta Model looks like in Eclipse. In the
+ following sections, we'll go through the data types, enumerations and classes
+ one by one.&nbsp;
+ </P>
+ <P><b>Figure 2. Rule Meta Model.</b></P>
+ <P><IMG alt="" src="images/RuleMetaModel.gif"></P>
+ <H4>Data Types
+ </H4>
+ <P>
+ Unlike Java, a rule language is untyped. In the code&nbsp;excerpt of <code>BallPlacement.clp</code>
+ in previous section, we don’t see the types of <code>ball</code>, <code>color</code>,
+ and <code>placement</code>. Although the language itself is untyped, underneath
+ the language in the rule engine, things are still typed. For example, <code>ball</code>,
+ <code>color</code>, <code>placement</code> are of a type called <code>Symbol</code>.
+ Values like <code>"something"</code> are of type <code>String</code> and values
+ like <code>2.3</code> are of type <code>Float</code>. Types like <code>Symbol</code>,
+ <code>String</code>, and <code>Float</code> are called <b>primitive types</b> or
+ <b>data types</b>. Most rule languages support a common set of primitive types.
+ However, there are types available in one language but you don’t see them in
+ others. It's&nbsp;important&nbsp;not to confuse data types like <code>String</code>
+ and <code>Float</code> in a rule language&nbsp;with similar data types <code>java.lang.String</code>
+ and <code>java.lang.Float</code> in java. They are totally different types used
+ in different languages interpreted by different virtual machines. Types in a
+ rule language are interpreted by a rule engine whereas java types are
+ interpreted by a Java virtual machine. This is why when we model these data
+ types in the Rule Meta model, we cannot simply use <code>java.lang.String</code>
+ or <code>java.lang.Float</code> but need to implement our own types.
+ </P>
+ <P>
+ There are six data types in Rule Meta Model. Each of them corresponds to a java
+ class. You can tell which java class a data type corresponds to by
+ looking&nbsp;at the screenshot in Figure 2 or at the <code>Instance Class Name</code>
+ property of the <code>EDataType</code> instance that defines the data type. The
+ table below summarizes the correspondences.
+ </P>
+ <P>
+ <TABLE id="Table1" height="66" cellSpacing="1" cellPadding="1" width="646" border="1">
+ <TR>
+ <TD width="111"><b>data type</b></TD>
+ <TD><b>implementing java class</b></TD>
+ </TR>
+ <TR>
+ <TD width="111">RSymbol</TD>
+ <TD>com.example.rule.ecore.rulemetamodel.RSymbol</TD>
+ </TR>
+ <TR>
+ <TD width="111">RFactAddress</TD>
+ <TD>com.example.rule.ecore.rulemetamodel.RFactAddress</TD>
+ </TR>
+ <TR>
+ <TD width="111">RInteger</TD>
+ <TD>com.example.rule.ecore.rulemetamodel.RInteger</TD>
+ </TR>
+ <TR>
+ <TD width="111">RFloat</TD>
+ <TD>com.example.rule.ecore.rulemetamodel.RFloat</TD>
+ </TR>
+ <TR>
+ <TD width="111">RDataType</TD>
+ <TD>com.example.rule.ecore.rulemetamodel.RDataType</TD>
+ </TR>
+ <TR>
+ <TD width="111">RMultiField</TD>
+ <TD>com.example.rule.ecore.rulemetamodel.RMultiField</TD>
+ </TR>
+ </TABLE>
+ </P>
+ <P>When defining&nbsp;data types, besides implementing corresponding java classes,
+ it's often appropriate and necessary to&nbsp;overwrite the generated code
+ for&nbsp;converting strings&nbsp;to and from&nbsp;instances of the data types.
+ In our example, we overwrite <code>createRSymbolFromString()</code> in <code>com.example.rule.ecore.rulemetamodel.impl.RulemetamodelFactoryImpl.java</code>
+ for <code>RSymbol</code> and other five similar methods in the same file for
+ the other five data types.
+ </P>
+ <P>A meta model like ours should be as platform independent as possible. We don't
+ want&nbsp;to tailor &nbsp;Rule Meta Model too much to a rule language that
+ models conforming to the Rule Meta Model can only generate code for&nbsp;that
+ specific language.&nbsp;A complete Rule Meta Model should&nbsp;model data
+ types&nbsp;common to most popular rule languages. Data types proprietary to a
+ specific rule language can be modeled at M1 level. Because the example code for
+ this article is more a demonstration than a full-fledged product, the set of
+ data types we model here is&nbsp;by no means&nbsp;complete for a rule language,
+ nor are the&nbsp;java classes implementing those data types.
+ </P>
+ <H4>Enumerations,&nbsp;Classes
+ </H4>
+ <P>There are three enumerations in the Rule Meta Model: <code>RRuleType</code>, <code>RFunctionType</code>,
+ <code>RCondElemEnum</code>. The&nbsp;three enumerations and six data types are
+ used in the definition of classes in Rule Meta Model. For example, the
+ following diagram shows that class <code>RFactTemplate</code> has one attribute <code>
+ factName</code> whose type is <code>RSymbol</code>, one of the data types
+ we just defined. Besides attribute <code>factName</code>, <code>RFactTemplate</code>
+ also has a containment reference to zero or multiple instances of <code>RFactSlot</code>.
+ <code>RFactTemplate</code> models fact templates in a rule language. The class
+ definition we see here is in line with our previous knowledge of fact
+ templates: a fact template has a name&nbsp;and defines zero or multiple slots.
+ As to <code>RFactSlot</code>, it models slots in fact templates. It has an
+ attribute <code>slotName</code> of type <code>RSymbol</code> and an attribute <code>
+ slotValueRange</code> of type <code>RMultiField</code>. We know from
+ previous section that a slot has a name. What we didn't mention is that some
+ rule languages allow you to specify the legitimate values&nbsp;of a slot, which
+ is what <code>slotValueRange</code> is for.
+ </P>
+ <P><IMG alt="" src="images/ClassDiagram2.gif"></P>
+ <p>The diagram below shows some more classes and their relations to&nbsp;each
+ other. Class <code>RRule</code> models rules. It has an attribute <code>ruleName</code>
+ that represents the name of a rule; a containment reference <code>condition</code>
+ that represents conditional elements in a rule's condition part; a containment
+ reference <code>ceMatchPattern</code> that represents patterns in a rule's
+ condition part but not enclosed in conditional elements; and a reference <code>actions</code>
+ that represents a rule's action part.</p>
+ <P>Class <code>RCondElem</code> models conditional elements. A conditional element
+ can contain match patterns or more conditional elements. That's why&nbsp;our
+ definition of <code>RCondElem</code> has one containment reference to itself
+ and one containment reference to <code>RPattern</code>. The <code>ceName</code>
+ attribute of <code>RCondElem</code> denotes what conditional element (<code>and</code>,
+ <code>or</code>, <code>not</code>, etc) an instance of <code>RCondElem</code> is.
+ If you look at <code>RCondElemEnum</code>, the type of the <code>ceName</code> attribute,
+ you will see that there are three enumeration literals there: <code>and</code>, <code>
+ or</code>, <code>not</code>. For the same reason we don't define a complete
+ set of data types, the list of conditional elements in <code>RCondElemEnum</code>
+ is not complete and in a more complete meta-model,&nbsp;<code>RCondElemEnum</code>
+ should include conditional elements&nbsp;common in most popular rule languages.</P>
+ <P>Class <code>RFunction</code> models functions.&nbsp;A function like <code>(retract
+ (?placement))</code> we saw earlier has a name and takes zero or
+ multiple&nbsp;instances of primitive data types as parameters. In this case, <code>retract</code>
+ is the name of the function and <code>?placement</code> is a parameter.
+ Although not visible, the <code>retract</code> function returns a value. In
+ JESS, it returns the symbol <code>TRUE</code> if it successfully removes a
+ fact. In our definition of <code>RFunction</code>, we have an attribute <code>functionName</code>
+ to represent the name of a function; an attribute <code>returnValue</code> of
+ type <code>RDataType</code> to represent a function's return value; a reference
+ to instances of <code>RDataType</code> to represent a function's parameters.
+ The <code>functionType</code> attribute in <code>RFunction</code> denotes
+ whether the function is provided by the rule engine or defined by users.</P>
+ <P><IMG alt="" src="images/ClassDiagram1.gif"></P>
+ <H2>Ball Placement Rule Model</H2>
+ <P>
+ With the three plug-ins of Rule Meta Model&nbsp;in place,&nbsp;we can now use
+ it to model our logical problem. Let's&nbsp;launch Eclipse and create a new
+ project. Select <code>File -&gt; New -&gt; Project</code> and in the popup
+ dialog, select <code>Simple -&gt; Project</code> Click <code>Next</code> button
+ and name the project <code>Test</code> or anything you like. With a project in
+ place, we can now create a rule model or import <code>BallPlacement.rulemetamodel</code>
+ that comes with this article's example code.</P>
+ <P>To creat the model from scratch, right click on the project we just created and
+ in the popup context menu, select <code>New -&gt; Other</code>. And then in the
+ popup window, select <code>Example EMF Model Creation Wizards -&gt; Rulemetamodel
+ Model</code> and click the <code>Next</code> button. In the next screen,
+ name the model whatever you like&nbsp;but keep&nbsp;the file extension&nbsp;as <code>
+ .rulemetamodel</code>.&nbsp;Click the <code>Next</code> button to go to the
+ next screen, and select <code>RModule</code> from the top dropdown box. Then
+ click the <code>Finish</code> button.</P>
+ <P>To import <code>BallPlacement.rulemetamodel</code>,&nbsp;right click on&nbsp;the
+ project we just created and in the popup context menu, select <code>Import</code>.
+ In the popup dialog window, select <code>File System</code> and click <code>Next</code>
+ button. The <code>Import</code> dialog window will show up. Use the <code>browse</code>
+ button in the dialog window to select the folder where
+ you&nbsp;unzipped&nbsp;the files in <code>BallPlacementRuleModel.zip</code>. A
+ list of files in that folder will show up in the <code>Import</code> dialog
+ window. Check <code>BallPlacement.rulemetamodel</code> in the list and click
+ the <code>Finish</code> button.
+ </P>
+ <P>If you create the model from scratch, you can refer to <code>BallPlacement.rulemetamodel</code>
+ for details of&nbsp;the model's elements. Below is a screenshot of how the
+ model looks like in Eclipse. It has two fact templates: <code>placement</code> and
+ <code>ball</code>. It has three&nbsp;rules for the three&nbsp;constraints posed
+ in the logical problem. It&nbsp;has two&nbsp;other rules for putting initial
+ facts into rule engine. Without facts,&nbsp;the rule engine will have nothing
+ to apply the three constraint rules to. The model also has some&nbsp;functions.
+ They are used in&nbsp;the action part of the rules.&nbsp;</P>
+ <P><IMG alt="" src="images/RuleModel.gif"></P>
+ <P><STRONG><FONT size="3"><STRONG><FONT size="3">Code Generation with JET Template</FONT></STRONG></FONT></STRONG></P>
+ <P>If you select the <code>RModule</code> node in <code>BallPlacement.rulemetamodel</code> and
+ see its property view, you'll see that there's property called <code>Output File
+ Path</code>. The value of this property is where the model puts the
+ generated code. Please change its value to an appropriate location on your
+ computer and then right click on the <code>RModule</code> node. In the popup
+ context menu, select <code>Generate</code> and check your file system to see if
+ a file by the name you specified in the <code>Output File Path</code> property
+ is generated. The generated file should be the same as <code>BallPlacement.clp</code>
+ in <code>BallPlacementRuleModel.zip</code>.</P>
+ <P>The logic for generating rule language code from a rule model is in a JET (Java
+ Emitter Templates) template and a java helper class. The JET template file is <code>
+ Module.clpjet</code> in the <code>templates</code> folder of <code>com.example.rule.ecore</code>
+ project, which can be&nbsp;unzipped from <code>RuleMetaModel.zip</code>. The
+ java helper class is <code>com.example.rule.ecore.templates.ModuleHelper.java</code>.
+ Readers unfamiliar with JET can refer to <A href="../Article-JET/jet_tutorial1.html">
+ JET Tutorial Part 1 (Introduction to JET)</A> and <A href="../Article-JET2/jet_tutorial2.html">
+ JET Tutorial Part 2 (Write Code that Writes Code)</A> for an excellent and
+ very readable guide.</P>
+ <P>Practically, a generation model might be necessary for storing complex settings
+ that govern the generation of rule language code from a rule model just like
+ EMF's Gen Model for generating code from ECore models. For simplicity, we
+ modified the editor plug-in EMF generated from our Rule Meta Model and provide
+ a menu option in the context menu that pops up when you right click&nbsp;the <code>RModule</code>
+ node.
+ </P>
+ <H2>Conclusion</H2>
+ <P>We have demonstrated how to define a meta-model with EMF, use the meta-model to
+ define a model for a logical problem and use JET to generate rule language code
+ from the model. We have also seen that the generated code correctly solves the
+ non-trivial logical problem. The flexibility of EMF as well as Eclipse makes
+ all the work a breeze. The EMF framework has all modeling foundation there and
+ thanks to that, most of our time is spent in understanding&nbsp;rule languages
+ and how rule engine works.&nbsp;</P>
+ <P>The example code for this article is a demonstration. There are many things to
+ improve. Modeling rule-based systems is still a field in progress. There are
+ standards bodies working on specifications. In the Reference section at the end
+ of this article, we provide some pointers to relevant OMG&nbsp;standards in
+ progress&nbsp;such as Production Rule Representation RFP and Sridhar Iyengar's
+ response to OMG's Business Rules in Models RFI. Also listed in the Reference
+ section is a very popular rule engine called CLIPS, of which JESS and many
+ other rule engines are variations.</P>
+ <H2>Reference</H2>
+ <p>Frank Budinsky, David Steinberg, Ed Merks, Raymond Ellersick, Timothy J. Grose, "Eclipse Modeling Framework", Addison Wesley, ISBN 0-1314-2542-0</p>
+
+<P>Production Rule Representation RFP <A href="http://www.omg.org/cgi-bin/doc?br/2003-9-3" target="_blank">
+ http://www.omg.org/cgi-bin/doc?br/2003-9-3</A></P>
+
+<P>Business Semantics of Business Rules RFP <A href="http://www.omg.org/cgi-bin/doc?br/2003-6-3" target="_blank">
+ http://www.omg.org/cgi-bin/doc?br/2003-6-3</A></P>
+
+<P>Business Rules Management RFI <A href="http://www.omg.org/cgi-bin/doc?bei/2004-6-3" target="_blank">http://www.omg.org/cgi-bin/doc?bei/2004-6-3</A></P>
+
+<P>Java Specification Request 94, Java Rule Engine API <A href="http://www.jcp.org/jsr/detail/94.jsp" target="_blank">
+ http://www.jcp.org/jsr/detail/94.jsp</A></P>
+
+<P>Business Rules in Models <A href="http://www.omg.org/technology/documents/Business_Rules_in_Models_RFI.htm" target="_blank">
+ http://www.omg.org/technology/documents/Business_Rules_in_Models_RFI.htm</A>
+</P>
+
+<P>Sridhar Iyengar's response to&nbsp;OMG's Business Rules in Models RFI <A href="http://www.omg.org/cgi-bin/doc?ad/03-01-25" target="_blank">
+ http://www.omg.org/cgi-bin/doc?ad/03-01-25</A></P>
+
+<P>CLIPS 6.2 <A href="http://www.ghg.net/clips/CLIPS.html" target="_blank">http://www.ghg.net/clips/CLIPS.html</A></P>
+ <P>&nbsp;</P>
+ <h3></h3>
+ <dl>
+ <dt></dt>
+ </dl>
+ </body>
+</html>
diff --git a/Article-Rule Modeling With EMF/images/BallPlacementResult.gif b/Article-Rule Modeling With EMF/images/BallPlacementResult.gif
new file mode 100644
index 0000000..9488939
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/BallPlacementResult.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/ClassDiagram1.gif b/Article-Rule Modeling With EMF/images/ClassDiagram1.gif
new file mode 100644
index 0000000..b3d258d
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/ClassDiagram1.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/ClassDiagram2.gif b/Article-Rule Modeling With EMF/images/ClassDiagram2.gif
new file mode 100644
index 0000000..6f315fa
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/ClassDiagram2.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/Idea.jpg b/Article-Rule Modeling With EMF/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/Idea.jpg
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/Overall.gif b/Article-Rule Modeling With EMF/images/Overall.gif
new file mode 100644
index 0000000..7d6fca7
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/Overall.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/RuleMetaModel.gif b/Article-Rule Modeling With EMF/images/RuleMetaModel.gif
new file mode 100644
index 0000000..4f470d4
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/RuleMetaModel.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/RuleModel.gif b/Article-Rule Modeling With EMF/images/RuleModel.gif
new file mode 100644
index 0000000..3b440f4
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/RuleModel.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/linux_only.gif b/Article-Rule Modeling With EMF/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/linux_only.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/tag_1.gif b/Article-Rule Modeling With EMF/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/tag_1.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/tag_2.gif b/Article-Rule Modeling With EMF/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/tag_2.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/tag_3.gif b/Article-Rule Modeling With EMF/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/tag_3.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/tag_4.gif b/Article-Rule Modeling With EMF/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/tag_4.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/tag_5.gif b/Article-Rule Modeling With EMF/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/tag_5.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/tag_6.gif b/Article-Rule Modeling With EMF/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/tag_6.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/tag_7.gif b/Article-Rule Modeling With EMF/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/tag_7.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/tip.gif b/Article-Rule Modeling With EMF/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/tip.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/tryit.gif b/Article-Rule Modeling With EMF/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/tryit.gif
Binary files differ
diff --git a/Article-Rule Modeling With EMF/images/win_only.gif b/Article-Rule Modeling With EMF/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Rule Modeling With EMF/images/win_only.gif
Binary files differ
diff --git a/Article-SWT-Color-Model/Idea.jpg b/Article-SWT-Color-Model/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-SWT-Color-Model/Idea.jpg
Binary files differ
diff --git a/Article-SWT-Color-Model/about.xml b/Article-SWT-Color-Model/about.xml
new file mode 100644
index 0000000..4c00495
--- /dev/null
+++ b/Article-SWT-Color-Model/about.xml
@@ -0,0 +1,24 @@
+<article link="swt-color-model.htm">
+ <title>SWT Color Model</title>
+ <date>April 24, 2001</date>
+ <category>rcp</category>
+ <category>swt</category>
+ <author>
+ <name>James Moody</name>
+ <company>IBM</company>
+ </author>
+ <author>
+ <name>Carolyn MacLeod</name>
+ <company>IBM</company>
+ </author>
+ <description>
+ <![CDATA[
+ The combination of platforms, display devices and color depth
+ makes providing an easy to use yet powerful and portable color
+ model an interesting challenge. In this article we will examine
+ the color management models of Windows&reg;
+ and X/Motif and then dig into the makings of the SWT color model
+ and its implications for client code.
+ ]]>
+ </description>
+</article>
diff --git a/Article-SWT-Color-Model/swt-color-model.htm b/Article-SWT-Color-Model/swt-color-model.htm
new file mode 100644
index 0000000..b481db5
--- /dev/null
+++ b/Article-SWT-Color-Model/swt-color-model.htm
@@ -0,0 +1,346 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.73 [en] (Win98; U) [Netscape]">
+ <meta name="Author" content="James Moody">
+ <title>SWT Color Model</title>
+<!-- saved from url=(0063)http://www.eclipsecorner.org/community/articleHTMLTemplate.html -->
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+<body>
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2001 Object Technology International, Inc.</font> </div>
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table>
+
+<h1>
+<img SRC="Idea.jpg" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+SWT Color Model</h1></center>
+
+<blockquote><b>Summary</b>
+<br>The combination of platforms, display devices and color depth makes
+providing an easy to use yet powerful and portable color model an interesting
+challenge. In this article we will examine the color management models
+of Windows&reg; and X/Motif and then dig into the makings of the SWT color model
+and its implications for client code.
+<p><b>By James Moody &amp; Carolyn MacLeod OTI</b>
+<br><font size=-1>April 24, 2001</font></blockquote>
+
+<hr width="100%">
+<h2>
+<br>
+Background</h2>
+
+<div class="MsoNormal">Before diving into the SWT color model, let’s examine
+the color management support provided by some of the target platforms.</div>
+
+<h3>
+Windows</h3>
+
+<p>Color management on Windows depends on the depth
+of the display, which can be either low-color (usually 8 bits per pixel
+or less) or high-color (typically 15 bits per pixel or higher).
+On low-color displays, the concept of a <i>Palette</i> is important. A
+palette is simply a logical grouping of colors. When a color is requested,
+the system can either put the color in the palette, or, if the palette
+is full, do a closest match of the colors in the palette to find a reasonable
+facsimile.</p>
+<p>Windows allows the user to define and use one palette per graphics
+context (GC), or to use the default system palette that is on the display.
+The advantage of defining your own palette is space: it is initialized
+as empty, and you have the entire capacity to fill with your own colors.
+On the other hand, the system palette undoubtedly already has many colors
+in it, especially if other applications are using it; the user may not
+be able to use the entire capacity for his or her own application. Using
+the system palette has its advantages, however. For one, it is easier to
+use: simply use your colors normally, and the system will take care of
+mapping them to the system palette. Secondly, switching between two applications
+that are both using the system palette will be smooth. Switching between
+two applications that use different palettes will result in a visible flash
+as Windows maps the appropriate palette and takes colors away from the
+application that no longer has control.</p>
+<p>On high-color displays, colors are effectively free: one can simply
+use RGB values without any regard to palettes or color availability.
+<h3>
+X/Motif</h3>
+
+<div class="MsoNormal">On X, the color model also depends on whether the
+display is palette-based or high-color. X has a palette-based system similar
+to that of Windows, using the term colormap instead of palette. The primary
+difference between Windows and X, however, is that colors on X must be
+allocated with <b>XAllocColor</b> prior to use, and freed with <b>XFreeColor</b>
+when no longer required. As well, switching between two applications that
+define their own palettes (private colormaps) on X results in all other
+applications having their colors altered in such a way that the switch
+is visibly more noticeable than on Windows. For this reason, most X applications
+do not define a private colormap, but rather share the default colormap.
+A limitation of X as compared to Windows is that it will not perform a
+closest-match if a color cannot be allocated, but will answer black instead.
+Thus if a closest match is desired, it must be performed by your code.
+
+<p class="MsoNormal">On high-color displays, where the pixel value encodes
+the RGB value of the color, colors are free as they are on Windows. Although
+the surest way to use colors on a high-color display is still to use <b>XAllocColor</b>,
+one can simply encode the RGB values into pixel values and use the pixels
+directly, without having to allocate or free the colors.
+<h2>
+Options</h2>
+
+<div class="MsoNormal">After taking into account the above platform features
+and limitations, a variety of options presented themselves as possible
+solutions to SWT's color management story.
+<br>&nbsp;</div>
+
+ <div class="MsoNormal"><i>1) expose <code>Palette</code> as a class to the SWT
+ user:</i></div>
+
+ <div class="MsoNormal" style="margin-left:.5in">Both Windows and X support the
+ notion of palettes on low-color displays. One option is to expose <code>Palette</code>
+ as a class to the SWT user, and allow the <i>Palette</i> to be set into a
+ <i>GC</i>. One problem with this approach is that X's palette solution is
+ undesirable due to its flashy behavior. This approach maps better to Windows
+ due to the platform’s improved palette switching capabilities. On X, however,
+ given the above limitation, SWT would want to give the illusion of palettes
+ to the developer, while mapping colors to the default colormap underneath.
+ Another problem is that of managing the palettes of multiple <i>GC</i>s in
+ the same window; on Windows, the colors from these palettes would need to
+ be somehow combined into a single palette when the window is given focus.
+ Providing user palettes would also require SWT to implement a default palette,
+ which would add complexity to the palette management code. <br>
+ &nbsp;</div>
+
+<div class="MsoNormal"><i>2) support only high-color displays:</i></div>
+
+<div class="MsoNormal" style="margin-left:.5in">Windows and X make it very
+easy to use high-color displays, and more difficult to use low-color displays.
+Another option is simply to support only high-color displays, and make
+colors free from the SWT user's perspective, meaning they do not need to
+be allocated or disposed. The obvious disadvantage of this approach is
+that many low-color displays exist and would be excluded from running SWT-based
+applications. (Of course, over time the number of systems that still run
+in low-color mode is decreasing, but there are still a significant number
+of real-world applications that require this.)
+<br>&nbsp;</div>
+
+<div class="MsoNormal"><i>3) allocate a color cube:</i></div>
+
+<div class="MsoNormal" style="margin-left:.5in">A common approach to color
+management is to allocate a fixed range of diverse colors, called a <i>color
+cube</i>, when the application starts. All requested colors are mapped
+to the closest color in the cube. This approach could be used in SWT for
+low-color displays, making it very easy for the user to manage colors.
+The advantage of this approach is that it is very simple for the user;
+the disadvantage is that the user is constrained to a very limited set
+of colors defined in the color cube, and will never be able to get an exact
+match of the color he or she desires, unless it happens to be in the color
+cube. This approach would not be ideal for high-color displays. Colors
+in SWT would not be resources in this approach, and thus would not need
+to be freed; SWT would take care of allocating the cube on startup and
+freeing it on shutdown.
+<br>&nbsp;</div>
+
+<div class="MsoNormal"><i>4) allocate colors:</i></div>
+
+<div class="MsoNormal" style="margin-left:.5in">The last option is to make
+the user allocate and free colors as if they were platform resources. (i.e.
+create with a constructor and free with <b>dispose</b>). This maps well
+to X, where colors are a resource, but not well to Windows, where colors
+are not a resource. This option is discussed in detail in the next section.</div>
+
+<h2>
+The SWT Color Model</h2>
+
+<h3>
+Goals</h3>
+
+<div class="MsoNormal">After examining the platform behavior and possible
+solutions, the following three goals for SWT's color model were decided
+upon:</div>
+
+<ol start=1 type=1>
+<li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
+ mso-list:l0 level1 lfo3;tab-stops:list .5in">
+SWT must support both palette-based and direct color devices (high-color
+displays). Palette-based devices are usually those containing 8 bits per
+pixel or less, while direct color devices are typically 15 bits per pixel
+and higher. In palette-based devices, the OS maintains a mapping of RGB
+values to pixel values, while in direct color devices the RGB values are
+encoded into the pixel value.</li>
+
+<li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
+ mso-list:l0 level1 lfo3;tab-stops:list .5in">
+The model must be portable. The color model supported by Windows, for example,
+is fundamentally different than the model supported by X. The SWT model
+must accommodate those differences in a way that is transparent to the
+SWT user.</li>
+
+<li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
+ mso-list:l0 level1 lfo3;tab-stops:list .5in">
+It is important that, under normal circumstances, the user be given exactly
+the color that was requested. Any scheme that limits the available colors
+to those contained in a small, pre-allocated palette will fail to offer
+the user exact colors.</li>
+</ol>
+
+<div class="MsoNormal">
+<h3>
+Decisions</h3>
+Our requirement of supporting palette-based displays rules out the second
+of the above options (“support only high-color displays”). The requirement
+to provide exact colors upon request means that allocating a color-cube
+and matching all requests to that cube (the third option – “allocate a
+color cube”) is also not acceptable.
+ <p>Providing the user with palettes that they can manage (as described in
+ the first option – “expose palette as a class”) sounds like a good solution,
+ but in practice, it makes client code very complex and hard to manage. Given
+ the simple color requirements of typical applications, this option was ruled
+ out.
+ <p>Thus, the only remaining option (the last one listed above), allocating
+ and disposing of colors independently, forms the basis of SWT's color model.
+ </div>
+
+<h3>
+Palette Per Display using Allocate &amp; Dispose</h3>
+On palette-based displays under Windows, SWT creates and manages one palette
+per <i>Display</i>. Colors used in a <i>GC</i> are taken from this palette.
+When the user allocates a <i>Color</i>, SWT checks if the palette is full.
+If it is not, the color is added to the palette and the user will get the
+exact color requested. If it is, the <i>Color</i> is allocated to be the
+closest match in the palette. In both cases, the reference count for that
+color is incremented. When a <i>Color</i> is disposed on Windows, SWT decrements
+the reference count. When the reference count reaches zero, SWT will remove
+the color from the palette. As with other SWT resources, clients must allocate
+colors, and free them only when the color is no longer needed.
+<p>On palette-based displays under X, SWT does not create a private colormap
+(palette), but instead uses the default colormap to avoid flashing and
+undesirable behavior. When the user allocates a <i>Color</i>, SWT tries
+to allocate the color with <b>XAllocColor</b>. If this succeeds, the user
+gets exactly the color they asked for, and that color is remembered by
+the <i>Display</i>. If it does not succeed, SWT finds the closest available
+color and uses that instead. In both cases, the reference count for that
+<i>Color</i>
+is incremented.
+<p>When a <i>Color</i> is disposed on X, SWT will call <b>XFreeColor</b>,
+which decrements the reference count on the X Server. As well, SWT will
+decrement its internal reference count for that <i>Color</i>, and remove
+it from the <i>Display</i> if the reference count is zero.
+ <p>On high-color displays on both Windows and X, the SWT display does not maintain
+ a palette. <i>Color</i>s are still allocated and freed on X, but this operation
+ simply calculates the pixel value and nothing else. On 24-bit and higher displays,
+ the user is guaranteed to get exactly the color requested. On 16-bit displays,
+ the user will get a very close approximation, but not necessarily the exact
+ color, due to the fact that 16-bit pixel values cannot encode 8-bit red, green
+ and blue values with 100% accuracy. Low-color displays that use a lot of colors
+ may still flash.&nbsp;
+ <h3>
+Standard Colors</h3>
+ <p>SWT provides access to the standard colors through Display.getSystemColor(int).
+ The following snipet returns the standard color for green.</p>
+<pre> display.getSystemColor(SWT.COLOR_GREEN)</pre>
+ <p>The creator of an SWT Color is responsible for disposing of
+ the color when it is no longer required. In the above snipet we did not actually
+ create the color, consequently we must <b>not</b> dispose of the color. </p>
+ <h3>
+Image Loading</h3>
+<p>When an SWT image is loaded, code similar to the following is usually used:</p>
+<pre> Image image = new Image(display, "filename");</pre>
+<p>Image loading is actually a two-step process. In the first
+step, SWT loads the image into a device-independent, format-independent
+object, called
+<i>ImageData</i>. The second step involves creating the
+actual device-dependent
+<i>Image</i> from the <i>ImageData</i>. Before
+this can happen, the colors that the image desires must be mapped to colors
+that are actually available on the device. On a true-color display (high-color
+display with at least 24-bit color), the colors are always available.
+ <p>On a low-color display the RGB values contained in the <i>ImageData</i>'s
+ palette are mapped to the closest match available in the SWT palette. The
+ colors that are available depend on which colors the user has already allocated.
+ If the user has not allocated many colors, then there may not be many colors
+ in the SWT palette for SWT to do a closest match to. SWT does not allocate
+ application colors. For this reason, it may be desirable to pre-allocate the
+ colors needed for the image. In the example above, however, there is no place
+ to allocate the colors; the user doesn't know what colors the image needs
+ before it is created. In situations like these, code such as the following
+ may be useful:</p>
+ <pre> ImageDate imageData = new ImageData("filename");
+ rgbs = imageData.getRGBs();
+ colors = new Color[rgbs.length];
+ for (int i = 0; i &lt; colors.length; i++) {
+ colors[i] = new Color(display, rgbs[i]);
+ }
+ image = new Image(display, imageData);
+ ...
+ // dispose the image and colors when no longer needed
+</pre>
+
+<p>In this example, the two-step process is revealed to the user, giving
+an opportunity to construct colors before the image is created, resulting
+in a more realistic image. In practice, this is not needed, since most
+displays are high-color.
+ <p>The way SWT does image loading presents one possible difficulty. What if
+ the user allocates some colors, loads an image, and subsequently frees some
+ colors? There is a possibility that the image has chosen some of the colors
+ that the user freed. In this case, unpredictable results can occur after the
+ colors have been freed. Fortunately, this is very easy to work around: always
+ allocate your colors in a static fashion, and free them when you are finished
+ with them. This model is described in the section "Tips for Color Management
+ in SWT".&nbsp;
+ <h2>
+Tips for Color Management in SWT</h2>
+
+<div class="MsoNormal">Color management in SWT is very simple from the
+user's perspective. There are 3 basic rules to help you manage your application's
+color needs:</div>
+
+<ol start=1 type=1>
+<li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
+ mso-list:l1 level1 lfo6;tab-stops:list .5in">
+Colors contain OS resources that must be allocated and freed. For this
+reason, it is necessary to <b>dispose</b> every color that you have created.</li>
+
+<li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
+ mso-list:l1 level1 lfo6;tab-stops:list .5in">
+On high-color displays (16 bpp and higher), every <i>Color</i> allocation
+is guaranteed to succeed. On low-color displays (8 bpp and lower), you
+will either receive a <i>Color</i> with the exact RGB values that you asked
+for or a reasonable facsimile (in other words, the closest match that could
+be made). In this case, if you query the new <i>Color</i>, it will report
+the actual RGB values, which are not necessarily the RGB values that you
+asked for.</li>
+
+ <li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
+ mso-list:l1 level1 lfo6;tab-stops:list .5in"> The envisioned usage of the
+ color model in SWT is fairly typical among plug-ins: a certain number of
+ fixed colors are decided upon for usage in the plug-in. The user allocates
+ these colors on plug-in startup, by creating <i>Color</i> objects. The plug-in
+ runs, and on shutdown, the user will call the <b>dispose</b> method for
+ these colors. This leads to a solution with minimal hassles in terms of
+ palettes being full and other color contention problems associated with
+ dynamically allocating and freeing colors while the plug-in is running.</li>
+</ol>
+
+<h2 class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
+ mso-list:l1 level1 lfo6;tab-stops:list .5in">
+Summary</h2>
+
+<div class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
+ mso-list:l1 level1 lfo6;tab-stops:list .5in">We
+have seen that SWT's portable color model supports a color palette per
+display. Clients of SWT must explicitly create their color resources and
+dispose of them when they are no longer required. SWT also provides access
+to standard colors through Display.getSystemColor(int).</div>
+</div>
+
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+
+</body>
+</html>
diff --git a/Article-SWT-DND/DND-in-SWT.html b/Article-SWT-DND/DND-in-SWT.html
new file mode 100644
index 0000000..7d8ca9d
--- /dev/null
+++ b/Article-SWT-DND/DND-in-SWT.html
@@ -0,0 +1,1739 @@
+
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="Author" content="Veronika Irvine">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<link rel="stylesheet" href="../default_style.css" >
+<title>DND in SWT</title>
+</head>
+
+<body bgcolor="white" lang="EN-US" link="blue" vlink="purple" style="tab-interval:.5in">
+
+<div align="right"><font size="-2">Copyright &copy; 2003 International Business Machines
+ Corp.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></b></td>
+ </tr>
+ </table>
+</div>
+<h1> <img src="images/idea.jpg" align=CENTER></h1>
+ <h1 align="center">Drag and Drop</h1>
+ <h3 align="center">Adding Drag and Drop to an SWT Application</h3>
+ <p align="justify"><b>Summary</b><br>
+ Drag and drop provides a quick and easy mechanism for users to re-order and
+ transfer data within an application and between applications. This article is
+ an overview of how to implement Drag and Drop and Clipboard data transfers
+ within an SWT application.</p>
+ <p><b>By Veronika Irvine, IBM OTI Labs</b><br>
+ <span style="font-size:10.0pt">August 25, 2003 (revised November 2, 2005)</span></p>
+ <div align="center" style="text-align:center">
+ <hr size="2" width="100%" align="center">
+ </div>
+ <h2>Drag and Drop Overview</h2>
+ <p>Consider the simple example of dragging an item from one table to another
+ as shown in Figure 1:</p>
+ <p align="center"><img border="0" src="images/image002.jpg"><br>
+ Figure 1: Shopping Cart example</p>
+ <p align="justify">On the right there is a list of items that I can purchase
+ and on the left is my shopping cart. To buy something, I select it from the
+ list on the right (I have selected “Truffle Assortment” in Figure 1), drag
+ it over to my shopping cart and drop it. When I let go of the mouse over my
+ shopping cart, the item will be added to the list of items I wish to purchase.
+ In this data transfer, the list of assorted chocolates on the right is the
+ drag source and my shopping cart is the drop target. A drag source is the
+ source of the data being transferred and a drop target is the receiver. As I
+ drag the mouse over a drop target, I get feedback in various forms. First, the
+ cursor changes to let me know that I am over a valid drop target by changing
+ from a “do not enter” sign to an arrow (this is called a “drag over
+ effect”). The cursor also tells me what kind of operation will be performed
+ when the data is transferred – the data may be copied or moved or a link may
+ be made to the data. Secondly, if I am dragging over a widget that has
+ sub-items like a tree or table, the sub-item may be highlighted to indicate
+ that the data will be dropped on a specific sub-item (this is called a “drag
+ under effect”). This is useful when you are organizing data into folders or
+ rearranging items. In this article, I will explain in more detail the terms I
+ have introduced above and how SWT allows an application to define and
+ manipulate these components.</p>
+ <ul>
+ <li><a href="#_Drag_Source">DragSource</a></li>
+ <li><a href="#_Drop_Target">DropTarget</a></li>
+ <li><a href="#_Using_the_Clipboard">Clipboard</a></li>
+ <li><a href="#_Transfer">Transfer</a></li>
+ </ul>
+ <h2><a name="_Drag_Source"></a>Drag Source</h2>
+ <p align="justify">A drag source is the provider of data in a Drag and Drop
+ data transfer as well as the originator of the Drag and Drop operation. The
+ data provided by the drag source may be transferred to another location in the
+ same widget, to a different widget within the same application, or to a
+ different application altogether. For example, you can drag text from your
+ application and drop it on an email application, or you could drag an item in
+ a tree and drop it below a different node in the same tree.</p>
+ <p align="justify">Let us walk through a simple example showing how to define
+ a drag source. The example in Listing 1 shows how to drag text from a label
+ widget.</p>
+ <table border="1" cellspacing="0" cellpadding="0" style="width:650">
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border-top:solid windowtext .5pt;
+ border-left:solid windowtext .5pt;border-bottom:none;border-right:none;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_ds1C" href="#_ds1D">1</a></td>
+ <td valign="top" style="width:788;border-top:.5pt solid windowtext;
+ border-left:medium none;border-bottom:medium none;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>import
+ org.eclipse.swt.dnd.*;</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">2</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code></code>&nbsp;</td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_ds4C" href="#_ds4D">3</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code><font color="#0080C0">//
+ Enable a label as a Drag Source</font></code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds4D">4</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>final
+ Label dragLabel = new Label(shell, SWT.BORDER);</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds4D">5</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>dragLabel.setText(&quot;text
+ to be transferred&quot;);</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">6</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code></code>&nbsp;</td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_ds8C" href="#_ds8D">7</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code><font color="#0080C0">//
+ Allow data to be copied or moved from the drag source</font></code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds8D">8</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>int
+ operations = DND.DROP_MOVE | DND.DROP_COPY;</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds8D">9</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>DragSource
+ source = new DragSource(dragLabel, operations);</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">10</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code></code>&nbsp;</td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_ds12C" href="#_ds12D">11</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code><font color="#0080C0">//
+ Provide data in Text format</font></code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds12D">12</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>Transfer[]
+ types = new Transfer[] {TextTransfer.getInstance()};</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds12D">13</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>source.setTransfer(types);</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">14</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code></code>&nbsp;</td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_ds15C" href="#_ds15D">15</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>source.addDragListener(new
+ DragSourceListener() {</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_ds16C" href="#_ds16D">16</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;
+ public void dragStart(DragSourceEvent event) {</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds16D">17</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <font color="#0080C0">// Only start the drag if there is actually text
+ in the</font></code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds16D">18</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <font color="#0080C0">// label - this text will be what is dropped on the target.</font></code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds16D">19</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if
+ (dragLabel.getText().length() == 0) {</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds16D">20</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.doit
+ = false;</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds16D">21</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds16D">22</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_ds23C" href="#_ds23D">23</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;
+ public void dragSetData(DragSourceEvent event) {</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds23D">24</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code><font color="#0080C0">&nbsp;&nbsp;&nbsp;&nbsp;
+ // Provide the data of the requested type.</font></code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds23D">25</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if
+ (TextTransfer.getInstance().isSupportedType(event.dataType)) {</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds23D">26</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.data
+ = dragLabel.getText();</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds23D">27</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds23D">28</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_ds29C" href="#_ds29D">29</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;
+ public void dragFinished(DragSourceEvent event) {</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds29D">30</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0080C0">//
+ If a move operation has been performed, remove the data</font></code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds29D">31</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0080C0">//
+ from the source</font></code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds29D">32</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if
+ (event.detail == DND.DROP_MOVE)</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds29D">33</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dragLabel.setText(&quot;&quot;);</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_ds29D">34</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">35</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="43" valign="top" style="width:.45in;border-top:none;border-left:solid windowtext .5pt;
+ border-bottom:solid windowtext .5pt;border-right:none;padding:0in 5.4pt 0in 5.4pt">36</td>
+ <td valign="top" style="width:788;border-top:medium none;border-left:medium none;
+ border-bottom:.5pt solid windowtext;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>});</code></td>
+ </tr>
+ </table>
+ <p align="left">Listing 1: Dragging text from a Label widget.
+ <p align="justify"><a name="_ds1D" href="#_ds1C"><b>Line 1:</b></a><br>
+ All the SWT drag and drop classes are defined in the package
+ org.eclipse.swt.dnd.</p>
+ <p align="justify"><a name="_ds4D" href="#_ds4C"><b>Lines 3 to 5:</b></a><br>
+ Create a widget. In order to start a drag, the user holds the mouse button
+ down in a widget and drags the mouse. In our example, the user starts the drag
+ in the label. Note that you cannot have multiple drag sources on one widget.
+ If you try to create a second drag source, an SWTError will be thrown.</p>
+ <p align="justify"><a name="_ds8D" href="#_ds8C"><b>Lines 7 to 9:</b></a><br>
+ To make a widget into a drag source, we must create an
+ org.eclipse.swt.dnd.DragSource object. The DragSource constructor takes two
+ arguments, the widget that will be the location of the drag source and the
+ operations that are allowed. The allowed operations determine what kind of
+ actions the drop target can do with the data being transferred. The allowed
+ values are any bitwise OR combination of DND.DROP_COPY, DND.DROP_MOVE or
+ DND.DROP_LINK. In the example, we are allowing the data to be copied or moved.</p>
+ <p align="justify"><a name="_ds12D" href="#_ds12C"><b>Lines 11 to 13:</b></a><br>
+ To complete the definition of a drag source, you must specify the types of
+ data that can be transferred. A data type is defined by a subclass
+ org.eclipse.swt.dnd.Transfer such as TextTransfer or FileTransfer. For a
+ detailed description of Transfer types see <a href="#_Transfer">Transfer</a>.
+ A drag source can provide more than one format of the data, however, it is
+ required to provide the data in any of the specified formats when requested.
+ In this example, the user can drag text from the label.</p>
+ <p align="justify"><a name="_ds15D" href="#_ds15C"><b>Line 15:</b></a><br>
+ Once the drag source is defined, a mechanism is required for it to interact
+ with the Drag and Drop operation. Adding a DragSourceListener does this.</p>
+ <p align="justify">The following event sequences may occur:</p>
+ <ol>
+ <li>dragStart</li>
+ <li>dragStart, one or more dragSetData, dragFinished</li>
+ <li>dragStart, dragFinished</li>
+ </ol>
+ <p align="justify"><a name="_ds16D" href="#_ds16C"><b>Lines 16 to 22:</b></a><br>
+ The dragStart event signals that the user has performed the action that
+ initiates a Drag and Drop operation. The exact action taken by the user
+ depends on the platform – on Windows for example, the user presses down with
+ the left mouse button and drags for a certain number of pixels (the exact
+ distance is configurable by the user in the Mouse control panel). On Motif,
+ the user presses down the middle mouse button. The application does not need
+ to be concerned about the exact conditions that started the operation because
+ SWT handles these platform differences. When the dragStart event is received,
+ the application has the choice to start a Drag and Drop operation or not. For
+ example, if no valid items are currently selected in the drag source widget,
+ the application may choose to cancel the operation. The operation is cancelled
+ by setting the event.doit field to ‘false’.</p>
+ <p align="justify">Note: the application is not required to specify the type
+ of data that will be transferred until the dragStart event has been received.
+ That is, the application can defer the call to DragSource.setTransfer until
+ the dragStart event. However, once the dragStart event has been processed, if
+ no transfer types have been specified for the drag source, the Drag and Drop
+ operation will be cancelled.</p>
+ <p align="justify">By allowing the Drag and Drop operation, the application is
+ making a promise to provide data of the specified type when requested. Failure
+ to do so is a violation of the DND contract and could result in unexpected
+ behavior.</p>
+ <p align="justify"><a name="_ds23D" href="#_ds23C"><b>Lines 23 to 28:</b></a><br>
+ The dragSetData event is a request for the data promised in the dragStart
+ event. This event may be called multiple times either repeatedly for the same
+ data type or for any of the data types promised. On some platforms, a
+ potential drop target can request data when the mouse is moving over the drop
+ target (e.g. Windows) and on some platforms the data may only be requested
+ when a drop is performed (the mouse is released over a valid drop site) (e.g.
+ Motif). Therefore, do not make any assumptions that the drag and drop
+ operation is completed when receiving this event. There is no way to know
+ where the data is being dropped – it could be dropped on the same
+ application, even on the same widget or on another application.</p>
+ <p align="justify">The type of data being requested is specified in the
+ event.dataType field. The event.dataType field contains a TransferData object.
+ While the fields of the TransferData object are public, they are platform
+ dependant. Therefore, you should not access the fields directly but rather
+ pass the TransferData to a Transfer object to determine the type of data. This
+ is done in the example by calling TextTransfer.getInstance().isSupportedType
+ (line 25).</p>
+ <p align="justify">The drag source must fill in the event.data field. The
+ exact form of the data depends on the Transfer type. For example, TextTransfer
+ expects a String object containing the entire text whereas a FileTransfer
+ expects a String array where each entry in the array is the absolute path of a
+ File. The javadoc for each transfer type should describe the expected value
+ for the Java object being transferred. More information on Transfer and
+ TransferData is available in the <a href="#_Transfer">Transfer</a> section of
+ this document.</p>
+ <p align="justify"><a name="_ds29D" href="#_ds29C"><b>Lines 29 to 34:</b></a><br>
+ The dragFinished event indicates that the drag and drop operation is complete.
+ The user may have dropped the data on a valid location, dropped the data on an
+ invalid location or hit Escape. If the user dropped the data on an invalid
+ location or hit Escape, the event.doit field will be false and the
+ event.detail field will be DND.DROP_NONE. If the user dropped the data on a
+ valid location, the event.doit field will be true and the event.detail field
+ will indicate the kind of operation performed by the drop target. This will be
+ one of values specified in table 1.</p>
+ <table border="1" cellspacing="0" cellpadding="2" width="90%">
+ <tr>
+ <th width="30%" valign="top" height="19">dragFinished event.detail value</th>
+ <th width="70%" valign="top" height="19">Description</th>
+ </tr>
+ <tr>
+ <td width="30%" valign="top" height="19">DND.DROP_COPY</td>
+ <td width="70%" valign="top" height="19">The drop target made a copy of
+ the data.</td>
+ </tr>
+ <tr>
+ <td width="30%" valign="top" height="20">DND.DROP_LINK</td>
+ <td width="70%" valign="top" height="20">The drop target made a link to
+ the data – usually only used for files.</td>
+ </tr>
+ <tr>
+ <td width="30%" valign="top" height="38">DND.DROP_MOVE</td>
+ <td width="70%" valign="top" height="38">The drop target made a copy of
+ the data and the drag source should now delete the original and update
+ its display.</td>
+ </tr>
+ <tr>
+ <td width="30%" valign="top" height="57">DND.DROP_TARGET_MOVE</td>
+ <td width="70%" valign="top" height="57">The drop target moved the data
+ from its original location to a new location. This is usually only used
+ with files. In this case, the drag source does not need to delete the
+ original; it just needs to update its display information.</td>
+ </tr>
+ </table>
+ <p align="left">Table 1: Valid dragFinished event.detail values
+ <h2><a name="_Drop_Target"></a>Drop Target</h2>
+ <p align="justify">A drop target receives data in a Drag and Drop operation.
+ The data received by the drop target may have come from the same widget, from
+ a different widget within the same application, or from a different
+ application altogether. For example, you can drag text from an email
+ application and drop it on your application, or you could drag an item in a
+ tree and drop it below a different node in the same tree.</p>
+ <p align="justify">Let us walk through a simple example showing how to define
+ a drop target. The example in Listing 2 shows how to drop files or text on a
+ table widget.</p>
+ <table border="1" cellspacing="0" cellpadding="0" style="width:680;
+ border-collapse:collapse;border:medium none;">
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border-top:solid windowtext .5pt;
+ border-left:solid windowtext .5pt;border-bottom:none;border-right:none;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt1C" href="#_dt1D">1</a></td>
+ <td valign="top" style="width:1060;border-top:.5pt solid windowtext;
+ border-left:medium none;border-bottom:medium none;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>import
+ org.eclipse.swt.dnd.*;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">2</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">&nbsp;</td>
+ <code></code>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt3C" href="#_dt3D">3</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code><font color="#0080C0">//
+ Enable a table as a Drop Target</font></code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt3D">4</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>final
+ Table dropTable = new Table(shell, SWT.BORDER);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt3D">5</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>for
+ (int i = 0; i &lt; 10; i++) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt3D">6</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ TableItem item = new TableItem(dropTable, SWT.NONE);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt3D">7</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ item.setText(&quot;item&quot; + I);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt3D">8</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">9</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code></code>&nbsp;</td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt10C" href="#_dt10D">10</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code><font color="#0080C0">//
+ Allow data to be copied or moved to the drop target</font></code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt10D">11</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>operations
+ = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt10D">12</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>DropTarget
+ target = new DropTarget(dropTable, operations);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">13</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code></code>&nbsp;</td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt14C" href="#_dt14D">14</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code><font color="#0080C0">//
+ Receive data in Text or File format</font></code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt14D">15</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>final
+ TextTransfer textTransfer = TextTransfer.getInstance();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt14D">16</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>final
+ FileTransfer fileTransfer = FileTransfer.getInstance();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt14D">17</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>types
+ = new Transfer[] {fileTransfer, textTransfer};</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt14D">18</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>target.setTransfer(types);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">19</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code></code>&nbsp;</td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt20C" href="#_dt20D">20</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>target.addDropListener(new
+ DropTargetListener() {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt21C" href="#_dt21D">21</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;
+ public void dragEnter(DropTargetEvent event) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt22C" href="#_dt22D">22</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;
+ if (event.detail == DND.DROP_DEFAULT) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt22D">23</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ if ((event.operations &amp; DND.DROP_COPY) != 0) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt22D">24</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ event.detail = DND.DROP_COPY;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt22D">25</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ } else {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt22D">26</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ event.detail = DND.DROP_NONE;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt22D">27</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ &nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt22D">28</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt29C" href="#_dt29D">29</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code><font color="#0080C0">&nbsp;&nbsp;&nbsp;&nbsp;
+ // will accept text but prefer to have files dropped</font></code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">30</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;for (int i = 0; i &lt; event.dataTypes.length; i++) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">31</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ &nbsp;if (fileTransfer.isSupportedType(event.dataTypes[i])){</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">32</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ &nbsp;event.currentDataType = event.dataTypes[i];</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">33</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ &nbsp;<font color="#0080C0">// files should only be copied</font></code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">34</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ if (event.detail != DND.DROP_COPY) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">35</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ event.detail = DND.DROP_NONE;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">36</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ &nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">37</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ break;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">38</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt29D">39</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">40</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt41C" href="#_dt41D">41</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;
+ public void dragOver(DropTargetEvent event) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt42C" href="#_dt42D">42</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt43C" href="#_dt43D">43</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;if
+ (textTransfer.isSupportedType(event.currentDataType)) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt43D">44</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <font color="#0080C0">// NOTE: on unsupported platforms this will return null</font></code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt43D">45</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ Object o = textTransfer.nativeToJava(event.currentDataType);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt43D">46</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ String t = (String)o;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt43D">47</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (t != null) System.out.println(t);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt43D">48</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">50</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt51C" href="#_dt51D">51</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ public void dragOperationChanged(DropTargetEvent event) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">52</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ if (event.detail == DND.DROP_DEFAULT) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">53</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ event.detail = (event.operations &amp; DND.DROP_COPY) != 0) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">54</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ event.detail = DND.DROP_COPY;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">55</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ } else {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">56</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ event.detail = DND.DROP_NONE;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">57</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">58</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">59</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;<font color="#0080C0">// allow text to be moved
+ but files should only be copied</font></code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">60</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;if
+ (fileTransfer.isSupportedType(event.currentDataType)){</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">61</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (event.detail !=
+ DND.DROP_COPY) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">62</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.detail
+ = DND.DROP_NONE;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">63</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">64</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt51D">65</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt66C" href="#_dt66D">66</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ public void dragLeave(DropTargetEvent event) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt66D">67</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt68C" href="#_dt68D">68</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ public void dropAccept(DropTargetEvent event) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt68D">69</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_dt70C" href="#_dt70D">70</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ public void drop(DropTargetEvent event) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">71</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;if
+ (textTransfer.isSupportedType(event.currentDataType)) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">72</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String text =
+ (String)event.data;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">73</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TableItem item = new
+ TableItem(dropTable, SWT.NONE);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">74</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item.setText(text);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">75</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">76</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;if
+ (fileTransfer.isSupportedType(event.currentDataType)){</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">77</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[] files =
+ (String[])event.data;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">78</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt;
+ files.length; i++) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">79</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TableItem
+ item = new TableItem(dropTable, SWT.NONE);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">80</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item.setText(files[i]);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">81</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">82</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_dt70D">83</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:1060;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>&nbsp;&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border-top:none;border-left:solid windowtext .5pt;
+ border-bottom:solid windowtext .5pt;border-right:none;padding:0in 5.4pt 0in 5.4pt">84</td>
+ <td valign="top" style="width:1060;border-top:medium none;border-left:
+ medium none;border-bottom:.5pt solid windowtext;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>});</code></td>
+ </tr>
+ </table>
+ <p align="left">Listing 2: Drop text or files on a table widget
+ <p align="justify"><a name="_dt1D" href="#_dt1C"><b>Line 1:</b></a><br>
+ All the related drag and drop classes are defined in the package
+ org.eclipse.swt.dnd.</p>
+ <p align="justify"><a name="_dt3D" href="#_dt3C"><b>Lines 3 to 8:</b></a><br>
+ Create a widget. The user drags the data over a target, which in user
+ interface terms is some visible widget. In our example, the user can drop the
+ data on a table. Note that you cannot have multiple drop targets on one
+ widget. If you try to create a second drop target, an SWTError will be thrown.</p>
+ <p align="justify"><a name="_dt10D" href="#_dt10C"><b>Lines 10 to 12:</b></a><br>
+ Define the types of operations that this drop target is likely to perform on
+ any data dropped on it. This is a bitwise OR combination of any of
+ DND.DROP_COPY, DND.DROP_MOVE, or DND.DROP_LINK. By default, if no operations
+ are defined, the DND.DROP_MOVE operation is assumed.</p>
+ <p align="justify">The operation may also include DND.DROP_DEFAULT (Note: the
+ DND.DROP_DEFAULT style must be combined with one or more of the other
+ DND.DROP_* styles). The DND.DROP_DEFAULT style allows the drop target to
+ determine the default operation – the default operation is what happens when
+ no modifier keys are pressed. If the DND.DROP_DEFAULT style is NOT specified,
+ the default operation will be DND.DROP_MOVE. See also dragEnter and
+ dragOperationChanged below.</p>
+ <p align="justify"><a name="_dt14D" href="#_dt14C"><b>Lines 14 to 18:</b></a><br>
+ Define the types of data that this drop target will accept. A data type is
+ defined by a subclass org.eclipse.swt.dnd.Transfer such as TextTransfer or
+ FileTransfer. For a detailed description of Transfer types see <a href="#_Transfer">Transfer</a>.
+ A drop target can be receptive to more than one type of data. The current 2.1
+ implementation will, however, only allow one format to be retrieved in the
+ final drop. That is to say, the drop target can indicate that it is interested
+ in both text and RTF text, but only one of these is provided in the drop event
+ – either text or RTF text. The advantage of registering for both formats is
+ that some applications may only provide text and some may only provide RTF
+ text. If an application provides both, you can choose which format you would
+ prefer to receive. See dragEnter below.</p>
+ <p align="justify"><a name="_dt20D" href="#_dt20C"><b>Line 20:</b></a><br>
+ Once the drop target is defined, a mechanism is required for it to interact
+ with the Drag and Drop operation. Adding a DropTargetListener does this.</p>
+ <p align="justify">The following event sequences may occur:</p>
+ <ul>
+ <li>dragEnter, dragLeave</li>
+ <li>dragEnter, one or more dragOver *, dragLeave</li>
+ <li>dragEnter, one or more dragOver *, dragLeave, dropAccept</li>
+ <li>dragEnter, one or more dragOver *, dragLeave, dropAccept, drop</li>
+ </ul>
+ <p>*may be a mixture of dragOver and dragOperationChanged</p>
+ <p align="justify"><a name="_dt21D" href="#_dt21C"><b>Line 21 to 40:</b></a><br>
+ The dragEnter event occurs when a drag and drop operation is in progress and
+ the cursor enters the bounds of the drop target widget. If the cursor leaves
+ the bounds of the widget and re-enters, another dragEnter is issued.</p>
+ <p align="justify"><a name="_dt22D" href="#_dt22C"><b>Lines 22 to 28:</b></a><br>
+ A drag over effect is a visual cue to the user about what kind of operation
+ will be performed when the drop occurs. The exact appearance of the visual cue
+ is platform dependant – some examples are shown in Figure 2. The drop target
+ can update this drag over effect by setting the event.detail field to one of
+ DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK or DND.DROP_NONE. The value set in
+ the event.detail field must be one of the values defined in the
+ event.operations field, which is a bitwise OR of the operations supported by
+ the DragSource. If a value is chosen that is not allowed by the DragSource,
+ the operation would be set to DND.DROP_NONE. The event.detail field can also
+ be updated in the dragOver, dragOperationChanged, dropAccept and drop events.</p>
+ <p align="justify">In dragEnter, the application can define the default
+ operation. As discussed above, if the drop target is created with the style
+ DND.DROP_DEFAULT, it will be notified when there are no user modifier keys
+ pressed. In this case, the event.detail field in the dragEnter event is set to
+ DND.DROP_DEFAULT. The application can specify the default operation by
+ changing the event.detail field to the desired operation. If the application
+ does not change the event.detail field from DND.DROP_DEFAULT to some
+ operation, it will by default be changed to DND.DROP_MOVE. The
+ DND.DROP_DEFAULT value is also set in the dragOperationChanged event.</p>
+ <p align="justify">In our example, we make Copy the default operation if it is
+ allowed by the drag source.</p>
+ <table border="1" cellspacing="0" cellpadding="2" style="border-collapse:collapse;
+ border:none;" width="30%">
+ <tr>
+ <th valign="top" width="50%">
+ <p>Operation</p>
+ </th>
+ <th valign="top" width="50%">Win32 cursor</th>
+ </tr>
+ <tr>
+ <td valign="top" width="50%" align="center">Move</td>
+ <td valign="top" width="50%" align="center"><img border="0" width="21" height="31" src="images/image004.jpg"></td>
+ </tr>
+ <tr>
+ <td valign="top" width="50%" align="center">Copy</td>
+ <td valign="top" width="50%" align="center"><img border="0" width="26" height="38" src="images/image006.jpg"></td>
+ </tr>
+ <tr>
+ <td valign="top" width="50%" align="center">Link</td>
+ <td valign="top" width="50%" align="center"><img border="0" width="27" height="38" src="images/image008.jpg"></td>
+ </tr>
+ <tr>
+ <td valign="top" width="50%" align="center">None</td>
+ <td valign="top" width="50%" align="center"><img border="0" width="22" height="22" src="images/image010.jpg"></td>
+ </tr>
+ </table>
+ <p align="left">Figure 2: Cursors for the allowed transfer operations
+ <p align="justify"><a name="_dt29D" href="#_dt29C"><b>Lines 29 to 39:</b></a><br>
+ The drop target can choose what type of data it would prefer to receive. The
+ dragEnter event has two fields for this, event.currentType, which is the type
+ of data preferred by the application (represented by a TransferData object),
+ and event.dataTypes, which is the list of types provided by the drag source
+ (represented by an array of TransferData objects). You can set the
+ event.currentType to any value in the event.dataTypes. These fields can also
+ be modified in the dragOver, dragOperationChanged, and dropAccept events.</p>
+ <p align="justify">In the example, we are allowing Text or Files to be dropped
+ on the table, but if both are available, we prefer to get the Files. If a file
+ is being transferred, we also have restricted the operation to allow only copy
+ (we don’t want you to delete files from your operating system when you play
+ with this example :-)).</p>
+ <p align="justify"><a name="_dt41D" href="#_dt41C"><b>Lines 41 to 50:</b></a><br>
+ The dragOver event occurs repeatedly as the user drags the cursor over the
+ drop target widget. If the cursor is motionless, the dragOver event will
+ continue to be received at regular intervals. In addition to what is shown in
+ the example, you can modify the event.detail or event.currentType fields. This
+ is most often done with a table or tree when the operation changes based on
+ what item you are over. For example, you may have a tree representing the file
+ system and you may allow files to be dropped on folders but not on other
+ files. The event.item field will indicate what item you are over in a table or
+ tree.</p>
+ <p align="justify"><a name="_dt42D" href="#_dt42C"><b>Line 42:</b></a><br>
+ A drag under effect is some visual cue or action in the drop target widget
+ that gives the user more detailed feedback about where the drop may occur. The
+ application can control the drag under effect by setting the event.feedback
+ field as shown in Table 2.</p>
+ <table border="1" cellspacing="0" width="90%" cellpadding="2">
+ <tr>
+ <th align="center" valign="top">dragOver event.feedback values</th>
+ <th align="center" valign="top">Description</th>
+ </tr>
+ <tr>
+
+ <td height="24" align="left" valign="top">DND.FEEDBACK_SELECT</td>
+ <td align="left" valign="top">The item under the cursor is selected;
+ applies to table and trees.</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">DND.FEEDBACK_SCROLL</td>
+ <td align="left" valign="top">The widget is scrolled up or down to allow
+ the user to drop on items that are not currently visible; applies to
+ tables and trees.</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">DND.FEEDBACK_EXPAND</td>
+ <td align="left" valign="top">The item currently under the cursor is
+ expanded to allow the user to select a drop target from a sub item;
+ applies to trees.</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">DND.FEEDBACK_INSERT_BEFORE</td>
+ <td align="left" valign="top">An insertion mark is shown before the item
+ under the cursor; applies to trees.</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">DND.FEEDBACK_INSERT_AFTER</td>
+ <td align="left" valign="top">An insertion mark is shown after the item
+ under the cursor; applies to trees.</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">DND.FEEDBACK_NONE</td>
+ <td align="left" valign="top">No effect is shown.</td>
+ </tr>
+ </table>
+ <p align="left">Table 2: drag under effect types
+ <p align="justify"><a name="_dt43D" href="#_dt43C"><b>Lines 43 to 49:</b></a><br>
+ When dragging data over the target, the information provided in the event
+ tells you what type of data is being dragged but does not give the content of
+ the data. For example, the event.currentType may indicate that a file is being
+ dragged but the event does not indicate the name of the file or the extension
+ of the file. If your application will perform a different operation for a Java
+ file versus a text file, then you might want to get the data in the dragOver
+ event. Unfortunately this is not supported on all platforms. As of 2.1, it is
+ only possible to access the data in the dragOver event on Windows. The data
+ can be accessed by passing the event.currentType TransferData object to the
+ nativeToJava method of the corresponding Transfer object. On all platforms
+ except Windows, this will return null. In the future, this capability may be
+ extended to other platforms where supported.</p>
+ <p align="justify">(Note: in 1.0 through 2.1, you can only get the data for
+ event.currentType but in 3.0, you can get the data for any type in
+ event.dataTypes).</p>
+ <p align="justify"><a name="_dt51D" href="#_dt51C"><b>Lines 51 to 65:</b></a><br>
+ The dragOperationChanged event occurs when the user presses or releases a
+ modifier key (such as Ctrl, Shift, Command, Option). The modifier keys are
+ used to switch the operation to be performed. For example, on Windows when
+ just the Ctrl key is down, a copy is requested, when the Ctrl and Shift keys
+ are both down, a link is requested and when just the Shift key is down, a move
+ is requested. When no modifier keys are pressed, the default operation is
+ requested. See the dragEnter event for more details.</p>
+ <p align="justify"><a name="_dt66D" href="#_dt66C"><b>Lines 66 to 67:</b></a><br>
+ The dragLeave event occurs when the cursor moves outside of the drop target
+ widget. If you allocated any resources in dragEnter, you should free them in
+ dragLeave. The dragLeave event also occurs if the user cancels the Drag and
+ Drop operation by hitting Escape, and just before a drop is performed.</p>
+ <p align="justify"><a name="_dt68D" href="#_dt68C"><b>Lines 68 to 69:</b></a><br>
+ The dropAccept event provides the application with one last chance to define
+ the type of data that will be returned in the drop event. This is done by
+ setting the event.currentDataType to one of the values defined in
+ event.dataTypes.</p>
+ <p align="justify"><a name="_dt70D" href="#_dt70C"><b>Lines 70 to 83:</b></a><br>
+ The drop event occurs when the user releases the mouse over the drop target if
+ a valid operation and currentDataType were requested in the previous events.
+ The event.data field contains the data requested. The object type contained in
+ the event.data field depends on what Transfer type was requested. The data is
+ of the type defined in the event.currentDataType field.</p>
+ <p align="justify">When the drop operation is completed, update the
+ event.detail field with the operation performed.</p>
+ <h2><a name="_Using_the_Clipboard"></a>Clipboard</h2>
+ <p align="justify">Drag and drop allows the simultaneous transfer of data
+ between a source and a target but sometimes the user may wish to copy data to
+ be transferred at a later point in time. The Clipboard acts like a temporary
+ holder for the data. In addition, the same data may be copied to multiple
+ targets using the clipboard.</p>
+ <p align="justify">In the following example, we will copy data in two
+ different formats onto the clipboard and retrieve one of the formats from the
+ clipboard.</p>
+ <table border="1" cellspacing="0" cellpadding="0" style="width:650" width="650">
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border-top:solid windowtext .5pt;
+ border-left:solid windowtext .5pt;border-bottom:none;border-right:none;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_cb1C" href="#_cb1D">1</a></td>
+ <td valign="top" style="width:850;border-top:.5pt solid windowtext;
+ border-left:medium none;border-bottom:medium none;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in"><code>import
+ org.eclipse.swt.dnd.*;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">2</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>. . .</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">3</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>public static void main(String[] args) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">4</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;Display display = new Display();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_cb5C" href="#_cb5D">5</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;final Clipboard cb = new Clipboard(display);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">6</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;Shell shell = new Shell(display);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">7</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;final Text text = new Text(shell, SWT.BORDER | SWT.MULTI);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">8</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;text.setBounds(10, 10, 300, 300);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">9</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;Button button = new Button(shell, SWT.PUSH);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">10</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;button.setText(&quot;Copy&quot;);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">11</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;button.setBounds(320, 10, 100, 40);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">12</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;button.addListener(SWT.Selection, new Listener() {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">13</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void handleEvent(Event e) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_cb14C" href="#_cb14D">14</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String textData = text.getSelectionText();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb14D">15</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (textData == null) return;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb14D">16</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0080C0">// to show the rtf formatting, make the text bold and italic</font></code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb14D">17</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String rtfData = &quot;{\\rtf1\\b\\i &quot; + textData + &quot;}&quot;;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb14D">18</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TextTransfer textTransfer = TextTransfer.getInstance();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb14D">19</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RTFTransfer rtfTransfer = RTFTransfer.getInstance();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb14D">20</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Transfer[] types = new Transfer[]{textTransfer, rtfTransfer};</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb14D">21</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cb.setContents(new Object[]{textData, rtfData}, types);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">22</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">23</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;});</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">24</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;button = new Button(shell, SWT.PUSH);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">25</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;button.setText(&quot;Paste&quot;);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">26</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;button.setBounds(320, 60, 100, 40);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">27</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;button.addListener(SWT.Selection, new Listener() {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">28</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void handleEvent(Event e) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_cb29C" href="#_cb29D">29</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TextTransfer transfer = TextTransfer.getInstance();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb29D">30</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String data = (String)cb.getContents(transfer);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb29D">31</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (data == null) return;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a href="#_cb29D">32</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text.insert(data);</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">33</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">34</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;});</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">35</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;shell.open();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">36</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;while (!shell.isDisposed()) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">37</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!display.readAndDispatch())</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">38</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display.sleep();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">39</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code></code>&nbsp;</td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">40</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt"><a name="_cb41C" href="#_cb41D">41</a></td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;cb.dispose();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border:none;border-left:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt">42</td>
+ <td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:850;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>&nbsp;&nbsp;display.dispose();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width:23.4pt;border-top:none;border-left:solid windowtext .5pt;
+ border-bottom:solid windowtext .5pt;border-right:none;padding:0in 5.4pt 0in 5.4pt">43</td>
+ <td valign="top" style="width:850;border-top:medium none;border-left:medium none;
+ border-bottom:.5pt solid windowtext;border-right:.5pt solid windowtext;
+ padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
+ <code>}</code></td>
+ </tr>
+ </table>
+ <p align="left">Listing 3: Using the clipboard to copy text
+ <p align="justify"><a name="_cb1D" href="#_cb1C"><b>Line 1:</b></a><br>
+ All the related drag and drop classes are defined in the package
+ org.eclipse.swt.dnd.</p>
+ <p align="justify"><a name="_cb5D" href="#_cb5C"><b>Line 5:</b></a><br>
+ Create a clipboard object. A Clipboard object gives you access to the
+ operating system clipboard. It will allow you to exchange data within your
+ application or with other applications. Note: A Clipboard object uses system
+ resources and must be released when you are finished (see line 41). You can
+ choose to create a new clipboard object each time you want to access the data
+ on the clipboard or you can keep an instance around for your application.</p>
+ <p align="justify"><a name="_cb14D" href="#_cb14C"><b>Lines 14 to 21:</b></a><br>
+ Copy the text selected in the Text widget onto the clipboard. If no text is
+ selected, do nothing.</p>
+ <p>When placing data on the clipboard, it is possible to make the data
+ available in more than one format. In our example, we are using both Text and
+ RTF Text formats. This makes it possible for our application to interact with
+ a larger variety of applications. That is, if we only place RTF text on the
+ clipboard, then we cannot interact with an application such as Notepad that
+ does not understand RTF text. To better integrate your application into the
+ environment, make your data available in as many useful forms as possible.</p>
+ <p>Each successful call to Clipboard.setContents will clear any previous
+ content from the clipboard. This applies not only to the data formats you are
+ placing on the clipboard but to all data formats. For example, if the
+ clipboard contains File data placed there by some other application and you
+ call Clipboard.setContents with Text data, the File data will no longer be
+ available. If you want to have multiple kinds of data available on the
+ clipboard at the same time, you must pass them to the clipboard in the same
+ Clipboard.setContents call. The Clipboard.setContents API takes an array of
+ data objects and an array of data types. The values for the data objects must
+ be in the same order as the data types and must be valid for the corresponding
+ data type (that is, a TextTransfer expects a String, a File Transfer expects a
+ String[] - the javadoc for each type should specify the expected format of the
+ data).</p>
+ <p>The data that you place on the clipboard will be available even after your
+ application is closed. (Note: GTK is an exception to this. Currently, there is
+ no mechanism in GTK to persist the data beyond the life time of the
+ application.)</p>
+ <p>On some platforms, there are actually multiple clipboards available. On
+ Unix/Linux there is a PRIMARY clipboard which is supposed to contain the data
+ that was most recently selected (implicitly set by the act of selection) and
+ there is a CLIPBOARD clipboard which is supposed to contain data that was
+ explicitly set through a keyboard accelerator (such as CTRL+Insert) or through
+ a menu item (there are also other clipboards but these are used infrequently).
+ On GTK and Motif, you can use <code>DND.CLIPBOARD</code> and
+ <code>DND.SELECTION_CLIPBOARD</code> when setting and getting clipboard data
+ to target a specific one. On Mac OS X, SWT supports the default Scrap.</p>
+ <p><a name="_cb29D" href="#_cb29C"><b>Lines 29 to 32:</b></a><br>
+ If there is Text available on the clipboard, insert it into the text widget.</p>
+ <p>To request data of a certain type, call Clipboard.getContents with a
+ Transfer subclass of the appropriate type. In our example, we are pasting Text
+ and have used the TextTransfer class. If there is no data of this type
+ available, null will be returned. The type of object returned by
+ Clipboard.getContents will depend on the Transfer class used. The javadoc for
+ the Transfer subclass should specify the Java object type.</p>
+ <p><a name="_cb41D" href="#_cb41C"><b>Line 41:</b></a><br>
+ Dispose of the clipboard. As mentioned above, failure to dispose the clipboard
+ will result in system resources being leaked.</p>
+ <h3>NEW for 3.0 – How to query data types on the Clipboard</h3>
+ <p>In 2.1 and earlier releases of SWT, the only mechanism available to
+ determine if a specific data type is available on the clipboard is to use
+ Clipboard.getContents and actually transfer the data. In addition to being
+ slow, this mechanism can cause problems when a &quot;Cut&quot; operation is
+ being performed. In a &quot;Cut&quot; operation, one application puts data on
+ the clipboard and when that data is transferred from the clipboard, the
+ original copy of the data is deleted. In 3.0, there will be new API to query
+ what types of data are on the clipboard without actually transferring the data
+ to your application. An example of how to use it is shown in Listing 4.</p>
+ <table border="1" cellpadding="0" cellspacing="0" width="650">
+ <tr>
+ <td width="31" valign="top" style="width: 23.4pt; border-left: .5pt solid windowtext; border-right-style: none; border-right-width: medium; border-top-style: none; border-top-width: medium; border-bottom: .5pt none windowtext; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17">1</td>
+ <td valign="top" style="width: 658; border-left-style: none; border-left-width: medium; border-right: .5pt solid windowtext; border-top-style: none; border-top-width: medium; border-bottom-style: none; border-bottom-width: medium; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17"><code>TransferData[]
+ available = cb.getAvailableTypes();</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width: 23.4pt; border-left: .5pt solid windowtext; border-right-style: none; border-right-width: medium; border-top-style: none; border-top-width: medium; border-bottom: .5pt none windowtext; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17">2</td>
+ <td valign="top" style="width: 658; border-left-style: none; border-left-width: medium; border-right: .5pt solid windowtext; border-top-style: none; border-top-width: medium; border-bottom-style: none; border-bottom-width: medium; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17"><code>boolean
+ enabled = false;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width: 23.4pt; border-left: .5pt solid windowtext; border-right-style: none; border-right-width: medium; border-top-style: none; border-top-width: medium; border-bottom: .5pt none windowtext; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17">3</td>
+ <td valign="top" style="width: 658; border-left-style: none; border-left-width: medium; border-right: .5pt solid windowtext; border-top-style: none; border-top-width: medium; border-bottom-style: none; border-bottom-width: medium; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17"><code>for
+ (int i = 0; i &lt; available.length; i++) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width: 23.4pt; border-left: .5pt solid windowtext; border-right-style: none; border-right-width: medium; border-top-style: none; border-top-width: medium; border-bottom: .5pt none windowtext; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17">4</td>
+ <td valign="top" style="width: 658; border-left-style: none; border-left-width: medium; border-right: .5pt solid windowtext; border-top-style: none; border-top-width: medium; border-bottom-style: none; border-bottom-width: medium; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17"><code>&nbsp;&nbsp;&nbsp;
+ if (TextTransfer.getInstance().isSupportedType(available[i])) {</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width: 23.4pt; border-left: .5pt solid windowtext; border-right-style: none; border-right-width: medium; border-top-style: none; border-top-width: medium; border-bottom: .5pt none windowtext; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17">5</td>
+ <td valign="top" style="width: 658; border-left-style: none; border-left-width: medium; border-right: .5pt solid windowtext; border-top-style: none; border-top-width: medium; border-bottom-style: none; border-bottom-width: medium; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ enabled = true;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width: 23.4pt; border-left: .5pt solid windowtext; border-right-style: none; border-right-width: medium; border-top-style: none; border-top-width: medium; border-bottom: .5pt none windowtext; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17">6</td>
+ <td valign="top" style="width: 658; border-left-style: none; border-left-width: medium; border-right: .5pt solid windowtext; border-top-style: none; border-top-width: medium; border-bottom-style: none; border-bottom-width: medium; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ break;</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width: 23.4pt; border-left: .5pt solid windowtext; border-right-style: none; border-right-width: medium; border-top-style: none; border-top-width: medium; border-bottom: .5pt none windowtext; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17">7</td>
+ <td valign="top" style="width: 658; border-left-style: none; border-left-width: medium; border-right: .5pt solid windowtext; border-top-style: none; border-top-width: medium; border-bottom-style: none; border-bottom-width: medium; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17"><code>&nbsp;&nbsp;&nbsp;
+ }</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width: 23.4pt; border-left: .5pt solid windowtext; border-right-style: none; border-right-width: medium; border-top-style: none; border-top-width: medium; border-bottom: .5pt none windowtext; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17">8</td>
+ <td valign="top" style="width: 658; border-left-style: none; border-left-width: medium; border-right: .5pt solid windowtext; border-top-style: none; border-top-width: medium; border-bottom-style: none; border-bottom-width: medium; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="17"><code>}</code></td>
+ </tr>
+ <tr>
+ <td width="31" valign="top" style="width: 23.4pt; border-left: .5pt solid windowtext; border-right-style: none; border-right-width: medium; border-top-style: none; border-top-width: medium; border-bottom: .5pt solid windowtext; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="18">9</td>
+ <td valign="top" style="width: 658; border-left-style: none; border-left-width: medium; border-right: .5pt solid windowtext; border-top-style: none; border-top-width: medium; border-bottom-style: none; border-bottom-width: medium; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0in; padding-bottom: 0in" height="18"><code>pasteMenuItem.setEnabled(enabled);</code></td>
+ </tr>
+ </table>
+ <p align="left">Listing 4: Query the data types available on the clipboard.
+ <p>Clipboard.getAvailableTypes returns an array of TransferData objects. A
+ TransferData object contains platform specific information that represents a
+ data type. While the fields of the TransferData object are public, do not
+ attempt to interpret them directly. Instead use the
+ &quot;isSupportedType&quot; method of any subclass of Transfer as shown in
+ line 4.</p>
+ <h2><a name="_Transfer"></a>Transfer</h2>
+ <p>Transfer is an abstract class that provides a mechanism for converting
+ between a Java representation of data and a platform specific representation
+ of data and vice versa. The Java representation of the data is the currency
+ the application uses. For example, text is represented by a String object. The
+ platform specific representation is the currency of the operating system and
+ is represented in SWT by the TransferData object. Table 3 shows the subclasses
+ of Transfer provided in org.eclipse.swt.dnd.</p>
+ <table border="1" cellpadding="2" cellspacing="0" width="90%">
+ <tr>
+ <th width="15%" align="center">Transfer</th>
+ <th width="20%" align="center">Java format</th>
+ <th width="60%" align="center">Example</th>
+ </tr>
+ <tr>
+ <td width="15%"><code>TextTransfer</code></td>
+ <td width="20%"><code>String</code></td>
+ <td width="60%"><code>&quot;hello world&quot;</code></td>
+ </tr>
+ <tr>
+ <td width="15%"><code>RTFTransfer</code></td>
+ <td width="20%"><code>String</code></td>
+ <td width="60%"><code>&quot;{\\rtf1\\b\\i hello world}&quot;</code></td>
+ </tr>
+ <tr>
+ <td width="15%"><code>FileTransfer</code></td>
+ <td width="20%"><code>String[]</code></td>
+ <td width="60%"><code>new String[] {file1.getAbsolutePath(),
+ file2.getAbsolutePath()}</code></td>
+ </tr>
+ </table>
+ <p align="left">Table 3: Transfer types provided by SWT
+ <p>The TransferData class contains public fields that are platform-specific.
+ Because the fields in TransferData vary from platform to platform,
+ applications should not access them. The purpose of making the fields public
+ is to allow developers to extend the Transfer class and provide additional
+ platform specific types for data transfer (e.g., bitmap images or wave files).</p>
+ <h2>Summary</h2>
+ <p>This article describes the SWT mechanism for transferring data either via
+ Drag and Drop or using the Clipboard. SWT uses the underlying operating system
+ mechanism which allows data transfer across applications for maximum system
+ integration. SWT provides standard data transfer types as well as an
+ infrastructure for defining your own transfer types or supporting additional
+ platform-defined data types.</p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the United States, other countries, or both.</small></p>
+</body>
diff --git a/Article-SWT-DND/about.xml b/Article-SWT-DND/about.xml
new file mode 100644
index 0000000..0be6632
--- /dev/null
+++ b/Article-SWT-DND/about.xml
@@ -0,0 +1,26 @@
+<!DOCTYPE doc [
+ <!ENTITY trade "&#153;">
+ <!ENTITY reg "&#174;">
+]>
+
+<article link="DND-in-SWT.html">
+ <title>Adding Drag and Drop to an SWT Application</title>
+ <date>August 25, 2003</date>
+ <update>
+ <date>November 2, 2005</date>
+ </update>
+ <category>rcp</category>
+ <category>swt</category>
+ <author>
+ <name>Veronika Irvine</name>
+ <company>IBM</company>
+ </author>
+ <description>
+ Drag and drop provides a quick and easy mechanism for users to
+ re-order and transfer data within an application and between
+ applications. This article is an overview of how to implement
+ Drag and Drop and Clipboard data transfers within an SWT
+ application.
+ </description>
+</article>
+
diff --git a/Article-SWT-DND/images/dnd1.gif b/Article-SWT-DND/images/dnd1.gif
new file mode 100644
index 0000000..04adf89
--- /dev/null
+++ b/Article-SWT-DND/images/dnd1.gif
Binary files differ
diff --git a/Article-SWT-DND/images/idea.jpg b/Article-SWT-DND/images/idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-SWT-DND/images/idea.jpg
Binary files differ
diff --git a/Article-SWT-DND/images/image001.gif b/Article-SWT-DND/images/image001.gif
new file mode 100644
index 0000000..04adf89
--- /dev/null
+++ b/Article-SWT-DND/images/image001.gif
Binary files differ
diff --git a/Article-SWT-DND/images/image002.gif b/Article-SWT-DND/images/image002.gif
new file mode 100644
index 0000000..67f710d
--- /dev/null
+++ b/Article-SWT-DND/images/image002.gif
Binary files differ
diff --git a/Article-SWT-DND/images/image002.jpg b/Article-SWT-DND/images/image002.jpg
new file mode 100644
index 0000000..314d495
--- /dev/null
+++ b/Article-SWT-DND/images/image002.jpg
Binary files differ
diff --git a/Article-SWT-DND/images/image003.png b/Article-SWT-DND/images/image003.png
new file mode 100644
index 0000000..d7e9986
--- /dev/null
+++ b/Article-SWT-DND/images/image003.png
Binary files differ
diff --git a/Article-SWT-DND/images/image004.jpg b/Article-SWT-DND/images/image004.jpg
new file mode 100644
index 0000000..19520b0
--- /dev/null
+++ b/Article-SWT-DND/images/image004.jpg
Binary files differ
diff --git a/Article-SWT-DND/images/image005.GIF b/Article-SWT-DND/images/image005.GIF
new file mode 100644
index 0000000..fc2ab60
--- /dev/null
+++ b/Article-SWT-DND/images/image005.GIF
Binary files differ
diff --git a/Article-SWT-DND/images/image005.png b/Article-SWT-DND/images/image005.png
new file mode 100644
index 0000000..427195f
--- /dev/null
+++ b/Article-SWT-DND/images/image005.png
Binary files differ
diff --git a/Article-SWT-DND/images/image006.jpg b/Article-SWT-DND/images/image006.jpg
new file mode 100644
index 0000000..20b71de
--- /dev/null
+++ b/Article-SWT-DND/images/image006.jpg
Binary files differ
diff --git a/Article-SWT-DND/images/image007.png b/Article-SWT-DND/images/image007.png
new file mode 100644
index 0000000..87c09cd
--- /dev/null
+++ b/Article-SWT-DND/images/image007.png
Binary files differ
diff --git a/Article-SWT-DND/images/image008.jpg b/Article-SWT-DND/images/image008.jpg
new file mode 100644
index 0000000..5a44da0
--- /dev/null
+++ b/Article-SWT-DND/images/image008.jpg
Binary files differ
diff --git a/Article-SWT-DND/images/image009.png b/Article-SWT-DND/images/image009.png
new file mode 100644
index 0000000..9f81a12
--- /dev/null
+++ b/Article-SWT-DND/images/image009.png
Binary files differ
diff --git a/Article-SWT-DND/images/image010.jpg b/Article-SWT-DND/images/image010.jpg
new file mode 100644
index 0000000..e339b8b
--- /dev/null
+++ b/Article-SWT-DND/images/image010.jpg
Binary files differ
diff --git a/Article-SWT-Design-1/SWT-Design-1.html b/Article-SWT-Design-1/SWT-Design-1.html
new file mode 100644
index 0000000..a8f5d7c
--- /dev/null
+++ b/Article-SWT-Design-1/SWT-Design-1.html
@@ -0,0 +1,310 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>SWT: The Standard Widget Toolkit</title>
+<link rel="stylesheet" href="default_style.css">
+</head>
+<body>
+ <div align="right">
+ <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2001 Object Technology International, Inc.</font>
+&nbsp;
+
+ <table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+ </tr>
+ </table>
+ </div>
+ <h1>
+<img SRC="idea.jpg" height=86 width=120 align=CENTER></h1>
+ <center>
+<h1>
+SWT: The Standard Widget Toolkit</h1></center>
+
+<center>
+<h3>
+PART 1: Implementation Strategy for Java&trade; Natives</h3></center>
+
+<center><i>The first in a series of articles about the design ideas behind
+SWT.</i></center>
+
+<blockquote><b>Summary</b>
+<br>SWT is the software component that delivers native widget functionality
+for the Eclipse platform in an operating system independent manner.&nbsp;
+It is analogous to AWT/Swing in Java with a difference - SWT uses a rich set of native
+widgets.&nbsp; Even in an ideal situation, industrial strength cross platform
+widget libraries are very difficult to write and maintain.&nbsp; This is
+due to the inherent complexity of widget systems and the many subtle differences
+between platforms.&nbsp; There are several basic approaches that have helped
+significantly to reduce the complexity of the problem and deliver high
+quality libraries.&nbsp; This article discusses one of them, the low level
+implementation techniques used to implement SWT on different platforms.&nbsp;
+Examples are drawn from the Windows&reg; and Motif implementations.
+
+<p><b>By Steve Northover, OTI</b>
+<br>
+ <font size="-1">March 22, 2001</font> </p>
+
+</blockquote>
+
+<p>
+<hr WIDTH="100%">
+<h3>
+Portable and Native - It Can't Be Done!</h3>
+Developers demand portable graphics and widgets to allow them to build
+user interfaces that are competitive with shrink-wrapped applications built
+using platform specific tools.&nbsp; They need access to platform specific
+features, with well defined API boundaries. SWT delivers this functionality
+using a small and consistent API.&nbsp; This API is implemented on different
+platforms using a combination of Java code and JNI natives specific to
+each platform.
+<p>SWT is implemented entirely in one language: Java.&nbsp; How can this
+be true when SWT uses native widgets that provide an API in C?&nbsp; The
+answer is that Java provides a native interface to C (JNI) that is used
+by SWT to invoke the operating system from Java code.&nbsp; JNI is the
+standard mechanism used by all Java programs to invoke code written in
+C. SWT goes one step further by enforcing a<i> one-to-one mapping</i> between
+Java native methods and operating system calls.&nbsp; The fact that this
+mapping is strictly enforced is one of the most critical factors in the
+success of SWT.
+<h3>
+A Tale of Two Implementations</h3>
+Let's take a look at the implementation of SWT <i>Text</i> widget on two
+different platforms.&nbsp; The <i>Text</i> widget provides the ability
+to set the selection.&nbsp; SWT application code that uses this API might
+look something like this:
+<p><tt>&nbsp;&nbsp;&nbsp; /* Select positions 2 to 5 */</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; text.setText ("0123456780");</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; text.setSelection (2, 5);</tt>
+<p>The method signature for <b>setSelection</b> in class <i>Text</i> looks
+like this:
+<p><tt>&nbsp;&nbsp;&nbsp; /**</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; * Sets the selection.</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; * &lt;p></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; * Indexing is zero based.&nbsp; The range of
+a selection is from 0..N</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; * where N is the number of characters in the
+widget.</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; */</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; public void setSelection (int start, int end)</tt>
+<p>Here is the Windows implementation of <b>setSelection</b>:
+<p><tt>&nbsp;&nbsp;&nbsp; public void setSelection (int start, int end)
+{</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OS.SendMessage (handle,
+OS.EM_SETSEL, start, end);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<p>What are <b>SendMessage</b> and <b>EM_SETSEL</b>?&nbsp; Windows programmers
+recognize this right away.&nbsp; It's <b>SendMessage</b>, the mechanism
+that is used to talk to Windows controls. <b>EM_SETSEL</b> is the message
+that tells the text control to set the selection.&nbsp; It's not easy reading,
+but it is familiar to a Windows programmer.&nbsp; The rest of us get to
+read the Microsoft&reg; Developer Network (MSDN) Library!
+<p>Here is the Java code for the SWT class <i>OS</i> on Windows:
+<p><tt>&nbsp;&nbsp;&nbsp; class OS {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final
+int EM_SETSEL = 0xB1;</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final
+native int SendMessage (int hWnd, int Msg, int wParam, int lParam);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<p>How is the <b>SendMessage</b> native implemented?&nbsp; Here is the
+C code on Windows:
+<p><tt>&nbsp;&nbsp;&nbsp; JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_win32_OS_SendMessage__IIII</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JNIEnv *env, jclass that, jint
+hWnd, jint Msg, jint wParam, jint lParam)</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (jint) SendMessage((HWND)hWnd,
+Msg, wParam, lParam);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<p>Notice that <i>the only thing this native does</i> is pass the Java
+call straight on through to the Windows API. But what about other operating
+systems?&nbsp; Does the fact that <b>setSelection</b> is implemented in
+terms of the Windows API mean that SWT is not portable?&nbsp; While it
+is true that the Windows implementation of <i>Text</i> is not portable,
+application code that uses <i>Text</i> is.&nbsp; How is this achieved?&nbsp;
+SWT provides a different <i>Text</i> class for each platform, but the signature
+of every public method is the same.&nbsp; Java code that calls SWT does
+not know or care which <i>Text</i> class is referenced at run time.
+<b>SendMessage</b>
+is not SWT API.
+<p>Here is the implementation of <b>setSelection</b> on Motif (Java and
+JNI C):
+<p><tt>&nbsp;&nbsp;&nbsp; public void setSelection (int start, int end)
+{</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int xDisplay = OS.XtDisplay
+(handle);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (xDisplay == 0) return;</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OS.XmTextSetSelection
+(handle, start, end, OS.XtLastTimestampProcessed (xDisplay));</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OS.XmTextSetInsertionPosition
+(handle, end);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; class OS {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final
+native void XmTextSetSelection (int widget, int first, int last, int time);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final
+native int XtLastTimestampProcessed (int display);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final
+native void XmTextSetInsertionPosition (int widget, int position);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final
+native int XtDisplay (int widget);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_motif_OS_XmTextSetSelection</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JNIEnv *env, jclass that, jint
+widget, jint first, jint last, jint time)</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmTextSetSelection((Widget)widget,
+first, last, time);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; ...</tt>
+<p>What are <b>XtDisplay</b>, <b>XmTextSetSelection</b>, <b>XtLastTimestampProcessed</b>
+and <b>XmTextSetInsertionPosition</b>?&nbsp; They don't mean much to a
+Windows programmer, but they are familiar to anyone who has ever programmed
+Motif.&nbsp; Now it's the Windows programmer's turn to consult the Motif
+man pages!
+<p>The example code above was taken directly from SWT but has been simplified
+by removing range and error checking code for the sake of the example.&nbsp;
+However, the code that is doing the real work - setting the selection -
+is identical to that found in the product.
+<h3>
+One to One Mapping - No Custom Natives</h3>
+Take a moment to review the Java and C code for <b>setSelection</b> in
+the previous section.&nbsp; Wouldn't it be easier to implement one <i>Text</i>
+class for all SWT platforms and hide the platform differences in the natives?&nbsp;
+Such an implementation might look like this:
+<p><tt>&nbsp;&nbsp;&nbsp; public void setSelection (int start, int end)
+{</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nativeSetSelection (start,
+end)</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; static final native void nativeSetSelection (int
+start, int end);</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; JNIEXPORT void JNICALL Java_org_eclipse_swt_widgets_text_nativeSetSelection</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JNIEnv *env, jclass that, jobject
+widget, jint first, jint last)</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; #ifdef WINDOWS</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HWND hWnd = SWTGetHandleFromJavaWidget
+(widget);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SendMessage(hWnd, Msg,
+wParam, lParam);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; #endif</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; #ifdef MOTIF</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Widget *w = SWTGetHandleFromJavaWidget
+(widget);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Display xDisplay = XtDisplay
+(w);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (xDisplay == NULL)
+return;</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmTextSetSelection (w,
+start, end, XtLastTimestampProcessed (xDisplay));</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmTextSetInsertionPosition
+(w, end);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; #endif</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<p>Isn't this easier than having a different <i>Text</i> class on each
+platform?&nbsp; The answer is a resounding "<i>No</i>".&nbsp; Why?&nbsp;
+In the case of the <i>Text</i> widget, the code to set the selection is
+pretty simple but even this causes problems.&nbsp; Before we get into the
+discussion, consider this:
+<ul>
+<li>
+The non-public native interface must be identical on all platforms.&nbsp;
+This means there needs to be an implementation of <b>nativeSetSelection</b>
+everywhere.&nbsp; We also still need to provide the public SWT API.&nbsp;
+So we need to implement <b>setSelection</b> everywhere. Why would we want
+to write two portable APIs instead of just one?&nbsp; One API is hard enough
+to specify and maintain!</li>
+
+<li>
+Java is a powerful high level language with features that promote robust
+code and program stability.&nbsp; It contains reusable class libraries
+for high level data types such as hash tables and vectors as well as efficient
+primitive types. Why use C?</li>
+</ul>
+Calling the operating system directly from Java helps with debugging. The
+following problem occurred in an early version of SWT for Windows:&nbsp;
+when the selection was set in the text widget, sometimes the widget did
+not scroll to show the i-beam.&nbsp; Where was the problem?&nbsp; The code
+that demonstrated the problem was complicated, but it was clear from stepping
+through the Java code and consulting the MSDN Library that the Java implementation
+of <b>setSelection</b> was correct.&nbsp; In fact, because of the <i>one-to-one
+mapping</i> between our Java natives and C, it was possible to write a
+simple C example to help isolate the problem and submit a bug report to
+Microsoft.&nbsp; Why was this so easy?&nbsp; Because, as we have said before,
+nothing extra ever happens in an SWT native. The Java call is passed right
+on through to the operating system.&nbsp; This means that C code is guaranteed
+to exhibit the same behavior.&nbsp; This is great news for debugging and
+maintenance.
+<p>Performance problems are legendary in widget toolkits and finding them
+is a black art.&nbsp; Where is the performance problem?&nbsp; Is it in
+the Java code or the natives?&nbsp; Fortunately, SWT natives can't be the
+problem. We are guaranteed that once we are in a native, the limiting factor
+is the speed of the operating system - something beyond our control.&nbsp;
+This is great news for performance tuning: look at the Java code.&nbsp;
+In fact, one quickly develops a sense of which operating system operations
+are expensive and which are cheap. Best of all, this knowledge is accurate.&nbsp;
+A C program that makes the same sequence of operating system calls will
+exhibit the same performance characteristics.&nbsp; This is a feature of
+the one-to-one mapping.
+<p>What happens when you try to debug a segment fault (or GP)?&nbsp; It's
+easy enough to step into a Java method and examine arguments but not possible
+to step into a native.&nbsp; Fortunately, nothing special happens in SWT
+natives so it's easy enough to isolate the code that is causing the problem.&nbsp;
+While on the subject of GPs, wouldn't it make sense for SWT natives to
+check their parameters before making the operating system call?&nbsp; It's
+tempting to check for NULL or -1 to avoid the crash.&nbsp; On the surface,
+this seems to make sense - after all, who wants to GP?&nbsp; The answer,
+of course, is that this would violate the one-to-one mapping and would
+mean that an equivalent C program would not crash in the same place.&nbsp;
+That's bad news for debugging and isolating a problem.
+<p>For someone implementing and maintaining SWT, the one-to-one mapping
+is extremely valuable.&nbsp; For example, a Windows programmer knows right
+away how <b>setSelection</b> works, just by looking at the Java code.&nbsp;
+Everyone else needs to read the MSDN Library.&nbsp; It's not light reading,
+but the information is there.&nbsp; The same thing is true for a Motif
+programmer for SWT on Motif, and for the other supported operating systems.&nbsp;
+In fact, it's clear exactly how existing features work and new features
+are to be implemented.&nbsp; The critial point here is that the documentation
+for the operating system applies to all SWT natives because they are a
+one-to-one mapping.
+<p>Adding new native features to SWT is a straightforward and well defined
+process. For example, implementing drag and drop and integrating it with
+the widgets was not difficult, despite the fact that these are two independent
+services.&nbsp; Why was this so easy?&nbsp; Nothing is hidden in the C
+code.&nbsp; All of the operating system resources needed to implement SWT
+are manifested as simple Java objects making it easy to understand how
+SWT works and to make changes.&nbsp; This allows SWT to be customized to
+support new platform dependent widgets and operating system services as
+they become available.
+<p>One last point: JNI is rich and powerful.&nbsp; It allows you to allocate
+Java objects in C, get and set Java fields, invoke new VMs and throw exceptions.&nbsp;
+The operating system, on the other hand, is typically more primitive.&nbsp;
+For example, most operating system calls that access memory require you
+to allocate the buffer and pass in the size.&nbsp; Java arrays know their
+size, so why do we need to pass it in?&nbsp; JNI allows us to allocate
+objects in C, so why not allocate buffers in the C code?&nbsp; Wouldn't
+it be better to try and "fix" the operating system API to make it more
+Java friendly?&nbsp; The answer again is "<i>No</i>".&nbsp; Any deviation
+from the one-to-one rule means that our Java code no longer behaves the
+same as the equivalent C code.&nbsp; For example, allocating objects in
+JNI could introduce a hidden performance problem for Java code inside a
+tight loop.&nbsp; Also, it may make sense to allocate one large buffer
+and pass in a smaller size, or reuse a buffer.&nbsp; It's tempting to use
+JNI
+features to attempt to "fix" the operating system API but this is a huge
+mistake.
+<h3>
+Conclusion</h3>All of the natives in SWT are implemented using this simple and consistent strategy.&nbsp; There is no C code to hide the low level details of the operating system such as the event loop, callbacks or the thread model.&nbsp; No code reaches back into Java from C to get a field or invoke a method.&nbsp; Nothing is magic - everything is coded in Java using the terminology and documentation of the operating system.&nbsp; Why is this such a big deal?&nbsp; Some might claim that all SWT&nbsp;does is use JNI to invoke the operating system - nothing fancy. But that's the whole point.&nbsp; Without a simple set of rules and a sense of restraint - a characteristic of SWT - it's just too easy for a widget toolkit to collapse under its own weight.<br>&nbsp;
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/Article-SWT-Design-1/about.xml b/Article-SWT-Design-1/about.xml
new file mode 100644
index 0000000..1282994
--- /dev/null
+++ b/Article-SWT-Design-1/about.xml
@@ -0,0 +1,38 @@
+<!DOCTYPE doc [
+ <!ENTITY trade "&#153;">
+ <!ENTITY reg "&#174;">
+]>
+
+<article link="SWT-Design-1.html">
+ <title>
+ SWT: The Standard Widget Toolkit PART 1: Implementation Strategy
+ for Java
+ &trade;
+ Natives
+ </title>
+ <date>March 22, 2001</date>
+ <category>rcp</category>
+ <category>swt</category>
+ <author>
+ <name>Steve Northover</name>
+ <company>IBM</company>
+ </author>
+ <description>
+ The first in a series of articles about the design ideas behind
+ SWT. SWT is the software component that delivers native widget
+ functionality for the Eclipse platform in an operating system
+ independent manner. It is analogous to AWT/Swing in Java with a
+ difference - SWT uses a rich set of native widgets. Even in an
+ ideal situation, industrial strength cross platform widget
+ libraries are very difficult to write and maintain. This is due
+ to the inherent complexity of widget systems and the many subtle
+ differences between platforms. There are several basic
+ approaches that have helped significantly to reduce the
+ complexity of the problem and deliver high quality libraries.
+ This article discusses one of them, the low level implementation
+ techniques used to implement SWT on different platforms.
+ Examples are drawn from the Windows
+ &reg;
+ and Motif implementations.
+ </description>
+</article>
diff --git a/Article-SWT-Design-1/default_style.css b/Article-SWT-Design-1/default_style.css
new file mode 100644
index 0000000..85e4e07
--- /dev/null
+++ b/Article-SWT-Design-1/default_style.css
@@ -0,0 +1,11 @@
+p { font-family: arial, helvetica, geneva; font-size: 10pt}
+td { font-family: arial,helvetica,geneva; font-size: -1}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 11px}
+th { font-family: arial,helvetica,geneva; font-size: 11px; font-weight: bold}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
diff --git a/Article-SWT-Design-1/idea.jpg b/Article-SWT-Design-1/idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-SWT-Design-1/idea.jpg
Binary files differ
diff --git a/Article-SWT-OpenGL/images/1W08-2.png b/Article-SWT-OpenGL/images/1W08-2.png
new file mode 100644
index 0000000..11f3f0b
--- /dev/null
+++ b/Article-SWT-OpenGL/images/1W08-2.png
Binary files differ
diff --git a/Article-SWT-OpenGL/images/3dchart4.png b/Article-SWT-OpenGL/images/3dchart4.png
new file mode 100644
index 0000000..9b5336c
--- /dev/null
+++ b/Article-SWT-OpenGL/images/3dchart4.png
Binary files differ
diff --git a/Article-SWT-OpenGL/images/Idea.jpg b/Article-SWT-OpenGL/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-SWT-OpenGL/images/Idea.jpg
Binary files differ
diff --git a/Article-SWT-OpenGL/images/cylinder.png b/Article-SWT-OpenGL/images/cylinder.png
new file mode 100644
index 0000000..71554e3
--- /dev/null
+++ b/Article-SWT-OpenGL/images/cylinder.png
Binary files differ
diff --git a/Article-SWT-OpenGL/images/gl_command.png b/Article-SWT-OpenGL/images/gl_command.png
new file mode 100644
index 0000000..7570c7d
--- /dev/null
+++ b/Article-SWT-OpenGL/images/gl_command.png
Binary files differ
diff --git a/Article-SWT-OpenGL/images/linux_only.gif b/Article-SWT-OpenGL/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-SWT-OpenGL/images/linux_only.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/rotation.xcf b/Article-SWT-OpenGL/images/rotation.xcf
new file mode 100644
index 0000000..bba05ba
--- /dev/null
+++ b/Article-SWT-OpenGL/images/rotation.xcf
Binary files differ
diff --git a/Article-SWT-OpenGL/images/rotation3.png b/Article-SWT-OpenGL/images/rotation3.png
new file mode 100644
index 0000000..6ed7d16
--- /dev/null
+++ b/Article-SWT-OpenGL/images/rotation3.png
Binary files differ
diff --git a/Article-SWT-OpenGL/images/rotation4.png b/Article-SWT-OpenGL/images/rotation4.png
new file mode 100644
index 0000000..a666c4d
--- /dev/null
+++ b/Article-SWT-OpenGL/images/rotation4.png
Binary files differ
diff --git a/Article-SWT-OpenGL/images/rotation5.png b/Article-SWT-OpenGL/images/rotation5.png
new file mode 100644
index 0000000..881653b
--- /dev/null
+++ b/Article-SWT-OpenGL/images/rotation5.png
Binary files differ
diff --git a/Article-SWT-OpenGL/images/tag_1.gif b/Article-SWT-OpenGL/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-SWT-OpenGL/images/tag_1.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/tag_2.gif b/Article-SWT-OpenGL/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-SWT-OpenGL/images/tag_2.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/tag_3.gif b/Article-SWT-OpenGL/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-SWT-OpenGL/images/tag_3.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/tag_4.gif b/Article-SWT-OpenGL/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-SWT-OpenGL/images/tag_4.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/tag_5.gif b/Article-SWT-OpenGL/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-SWT-OpenGL/images/tag_5.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/tag_6.gif b/Article-SWT-OpenGL/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-SWT-OpenGL/images/tag_6.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/tag_7.gif b/Article-SWT-OpenGL/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-SWT-OpenGL/images/tag_7.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/tip.gif b/Article-SWT-OpenGL/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-SWT-OpenGL/images/tip.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/tryit.gif b/Article-SWT-OpenGL/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-SWT-OpenGL/images/tryit.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/win_only.gif b/Article-SWT-OpenGL/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-SWT-OpenGL/images/win_only.gif
Binary files differ
diff --git a/Article-SWT-OpenGL/images/workbench2.png b/Article-SWT-OpenGL/images/workbench2.png
new file mode 100644
index 0000000..56d625a
--- /dev/null
+++ b/Article-SWT-OpenGL/images/workbench2.png
Binary files differ
diff --git a/Article-SWT-OpenGL/images/workbench3.png b/Article-SWT-OpenGL/images/workbench3.png
new file mode 100644
index 0000000..0a9a3cb
--- /dev/null
+++ b/Article-SWT-OpenGL/images/workbench3.png
Binary files differ
diff --git a/Article-SWT-OpenGL/lib/demo_plugin.zip b/Article-SWT-OpenGL/lib/demo_plugin.zip
new file mode 100644
index 0000000..5803243
--- /dev/null
+++ b/Article-SWT-OpenGL/lib/demo_plugin.zip
Binary files differ
diff --git a/Article-SWT-OpenGL/opengl.css b/Article-SWT-OpenGL/opengl.css
new file mode 100644
index 0000000..0d0599d
--- /dev/null
+++ b/Article-SWT-OpenGL/opengl.css
@@ -0,0 +1,201 @@
+div.figure {
+ text-align: center;
+}
+
+span.copy {
+ font-family: Times New Roman,Times,serif;
+ font-size: small;
+}
+
+span.corner {
+ font-family: Arial,Helvetica;
+ font-weight: bold;
+ color: rgb(255, 255, 255);
+}
+
+div.figure-caption {
+ text-align: center;
+}
+
+span.figure-number {
+ font-weight: bold;
+}
+
+p {
+ text-align: justify;
+}
+
+dt {
+ font-weight: bold;
+ padding-left: 1ex;
+ margin-bottom: 3px;
+}
+
+dd {
+ margin-bottom: 1ex;
+}
+
+pre.code {
+ background-color: #f8f8f8;
+ color: #000000;
+ padding: 2px 4px;
+}
+
+span.c2h_comment {
+ color: #444444;
+}
+
+span.c2h_doc_comment {
+ color: #008000;
+ font-style: italic;
+}
+
+span.c2h_string {
+ color: #640000;
+}
+
+span.c2h_esc_string {
+ color: #77dd77;
+}
+
+span.c2h_character {
+ color: #008000;
+}
+
+span.c2h_esc_character {
+ color: #77dd77;
+}
+
+span.c2h_numeric {
+ color: #000000;
+ font-style: plain;
+}
+
+span.c2h_identifier {
+ color: #000000;
+}
+
+span.c2h_predefined_identifier {
+ color: #2040a0;
+ font-weight: bold;
+}
+
+span.c2h_predefined_type {
+ color: #2040a0;
+ font-weight: bold;
+}
+
+span.c2h_reserved_word {
+ color: #7f0055;
+ font-weight: bold;
+}
+
+span.c2h_library_function {
+ color: #a52a2a;
+ font-weight: bold;
+}
+
+span.c2h_include {
+ color: ##0000ff;
+ font-weight: bold;
+}
+
+span.c2h_preprocessor {
+ color: #0000ff;
+ font-weight: bold;
+}
+
+span.c2h_braces {
+ color: #000000;
+ font-weight: normal;
+}
+
+span.c2h_symbol {
+ color: #404080;
+}
+
+span.c2h_function_header {
+ color: #000000;
+ font-weight: bold;
+}
+
+span.c2h_function_header_name {
+ color: #ff0000;
+}
+
+span.c2h_function_header_args {
+ color: #2040a0;
+}
+
+span.c2h_regex {
+ color: #b000d0;
+}
+
+span.c2h_text {
+ color: #000000;
+ font-style: italic;
+}
+
+span.c2h_entity {
+ color: #ff0000;
+}
+
+span.c2h_assignment {
+ color: #2040a0;
+}
+
+span.c2h_dependecy_line {
+ color: #8b2252;
+}
+
+span.c2h_dependency_target {
+ color: #000000;
+ font-weight: bold;
+}
+
+span.c2h_dependency_continuation {
+ color: #000000;
+ font-weight: bold;
+}
+
+span.c2h_continuation {
+ color: #000000;
+ font-weight: bold;
+}
+
+span.c2h_macro {
+ color: #2040a0;
+}
+
+span.c2h_int_macro {
+ color: #4080ff;
+}
+
+span.c2h_esc_dollars {
+ color: #444444;
+}
+
+span.c2h_separator {
+ color: #00A040;
+ font-weight: bold;
+}
+
+span.c2h_line_spec {
+ color: #A0A000;
+ font-weight: bold;
+}
+
+span.c2h_deletion {
+ color: #FF0000;
+ font-weight: bold;
+}
+
+span.c2h_insertion {
+ color: #0000FF;
+ font-weight: bold;
+}
+
+body.c2h {
+ color: #000000;
+ background-color: #ffffff;
+}
diff --git a/Article-SWT-OpenGL/opengl.html b/Article-SWT-OpenGL/opengl.html
new file mode 100644
index 0000000..d72f481
--- /dev/null
+++ b/Article-SWT-OpenGL/opengl.html
@@ -0,0 +1,1248 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html lang="en">
+<head>
+ <title>Using OpenGL with SWT</title>
+ <link rel="stylesheet" href="../default_style.css" type="text/css">
+ <link rel="stylesheet" href="opengl.css" type="text/css">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+ <meta name="author" content="Bo Majewski">
+</head>
+
+<body>
+ <div align="right">
+ &nbsp; <span class="copy">Copyright &copy; 2005 Cisco Systems Inc.</span>
+
+ <table border="0" cellpadding="2" cellspacing="0" width="100%">
+ <tbody>
+ <tr>
+ <td colspan="2" align="left" bgcolor="#0080C0" valign="top">
+ <span class="corner">&nbsp;Eclipse Corner Article</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div align="left">
+ <h1><img src="images/Idea.jpg" alt="tag" align="middle" height=
+ "86" width="120"></h1>
+ </div>
+
+ <p>&nbsp;</p>
+
+ <h1 align="center">Using OpenGL with SWT</h1>
+
+ <blockquote>
+ <p><b>Summary</b></p>
+
+ <p>
+ OpenGL is a vendor-neutral, multi-platform standard for creating
+ high-performance 2D and 3D graphics. Hardware and software implementations
+ exist on various operating systems, including Windows, Linux and
+ MacOS. OpenGL may be used to render simple 2D charts or complex 3D games. This
+ article describes an experimental Eclipse plug-in that facilitates the use
+ of OpenGL for drawing onto SWT widgets. A short history and overview of
+ OpenGL is presented, followed by an example application.
+ </p>
+
+ <p><b>By Bo Majewski, Cisco Systems, Inc.</b><br>
+ <font size="-1">April 15, 2005</font></p>
+ </blockquote>
+ <hr width="100%">
+
+ <h2>Introduction</h2>
+ <p>
+ As the common saying goes, a picture is worth a thousand words. Or
+ a thousand database records. In a world flush with terabytes of data, gaining
+ an understanding of information often requires an effective way to visualize
+ it. A field of molecular biology, specifically proteomics, is a good
+ example. The raw data, in the form of an amino acid sequence, is insufficient
+ to understand the function of a given protein. Only knowing a full 3D
+ structure of it can one gain a deeper comprehension of the protein's purpose and
+ the way that it fulfills its tasks (see Figure 1).
+ </p>
+
+ <div class="figure">
+ <table align="center">
+ <tbody>
+ <tr>
+ <td style="font-size: 8pt; font-family: monospace;">
+KVFERCELARTLKRLGMDGYRGISLANWMCLAKWESGYNTRATNY<br>
+NAGDRSTDYGIFQINSRYWCNDGKNPGAVNACHLSCSALLQDNIA<br>
+DAVACAKRVVRDPQGIRAWVAWRNRCQNRDVRQYVQGCGV<br>
+<br>
+ATOM 1 N LYS A 1 19.534 32.582 38.371 1.00 25.04 N<br>
+ATOM 2 CA LYS A 1 18.911 32.387 37.062 1.00 25.51 C<br>
+ATOM 3 C LYS A 1 17.908 33.472 36.753 1.00 27.65 C<br>
+ATOM 4 O LYS A 1 17.251 33.988 37.643 1.00 29.70 O<br>
+ATOM 5 CB LYS A 1 18.184 31.056 37.123 1.00 27.48 C<br>
+ATOM 6 CG LYS A 1 17.069 30.921 36.093 1.00 24.63 C<br>
+ATOM 7 CD LYS A 1 16.059 29.845 36.488 1.00 20.32 C<br>
+ATOM 8 CE LYS A 1 14.972 29.702 35.432 1.00 17.75 C<br>
+ATOM 9 NZ LYS A 1 14.270 28.408 35.603 1.00 22.15 N<br>
+ATOM 10 N VAL A 2 17.863 33.900 35.497 1.00 28.50 N<br>
+ATOM 11 CA VAL A 2 16.885 34.898 35.083 1.00 30.21 C<br>
+ATOM 12 C VAL A 2 15.664 34.300 34.397 1.00 28.35 C<br>
+<span style="font-size: large; font-weight: bold;">&hellip;</span>
+ </td>
+ <td valign="top">
+ <img src="images/1W08-2.png" width="300" height="211" border="0" alt="T70N">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="figure-caption">
+ <span class="figure-number">Figure 1</span>. Structure Of T70N Human Lysozyme without side chains<br>
+ (source: <a href="http://www.rcsb.org/">The
+ RSCB Protein Data Bank</a>; 3D rendering done by
+ <a href="http://www.ncbi.nlm.nih.gov/">NCBI</a>'s
+ <a href="http://www.ncbi.nlm.nih.gov/Structure/CN3D/cn3d.shtml">Cn3D 4.1</a>)
+ </div>
+ </div>
+
+ <p>
+ Eclipse ships with the Standard Widget Toolkit (SWT) which provides access to
+ native widget functionality through a platform-independent API. While the toolkit
+ provides a rich selection of widgets, graphics support was somewhat limited.
+ The SWT Graphics <a href="#winchester">[1]</a> package provided
+ basic functionality needed to do 2D drawings, from rendering 2D primitives such
+ as lines, arcs, rectangles and ovals, through clipping, text drawing
+ and image display.
+ </p>
+ <p>
+ The Draw2D plug-in that builds on top of SWT
+ provides lightweight rendering and layout capabilities.
+ The lightweight term means that you need only one native widget (i.e. heavy widget),
+ such as a <code>Canvas</code> to draw multiple figures. Layout functionality
+ allows you to automatically position multiple <code>IFigures</code>. If your goal was
+ to develop a charting package for Eclipse, Draw2D would provide a good
+ start.
+ </p>
+
+ <p>
+ Until recently, in order to utilize advanced 2D graphics, one possible approach
+ was to use Java2D. By relying on a <code>BufferedImage</code> a developer could
+ use Java2D APIs to draw in memory, transfer the image to an SWT image, and
+ then render it on any SWT component (see <a href="#saillet">[2]</a>
+ for details). However, the drawback of this technique was added storage
+ and processing time requirements. These limitations were overcome
+ in milestone 5 of the 3.1 release through a new SWT API that utilizes native
+ <a href="http://www.cairographics.org/">Cairo</a> or <a href="http://msdn.microsoft.com/library/en-us/gdicpp/gdiplus/gdiplus.asp">GDI+</a> graphics
+ libraries. Developers now can use
+ transparency, rotation, shearing, brushes, pens and many more techniques
+ for enhancing graphical output, directly in SWT. Unfortunately, even with these additions,
+ the realm of high-performance 3D graphics is still out of reach.
+ </p>
+
+ <p>
+ To address this need, a
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/opengl/opengl.html">plug-in</a> was developed that
+ enabled OpenGL rendering onto an SWT <code>Drawable</code>. While the
+ plug-in is still experimental, it can be used to create high-impact,
+ high-performance graphics in Eclipse plug-ins and SWT applications. The goal of this article is to give
+ the reader a gentle introduction to the world of OpenGL and its use in SWT.
+ Immediately I am going to provide caveat lector. The subjects of 3D
+ rendering and OpenGL are so vast that they are well beyond the scope
+ of this short writeup. Readers interested in either of the topics
+ are encouraged to explore the available pool of extensive literature, some of which
+ has been listed in the <a href="#bibliography">Bibliography</a> section.
+ Hands-on experience may be gained by following various online tutorials,
+ with <a href="http://nehe.gamedev.net/">NeHe Productions</a> providing a
+ particularly good selection of 48 OpenGL lessons.
+ </p>
+
+
+ <h2>OpenGL</h2>
+
+ <p>
+ Open Graphics Library, or OpenGL for short, traces its roots to SGI's IRIS GL.
+ Its first public release was made available on July 1, 1992. It went through six
+ revisions, culminating in version 2.0 published on September 7, 2004.
+ The main goal of OpenGL is to provide an efficient and easy-to-use
+ API for creating 2D and 3D computer graphics. Interestingly, and in part
+ due to the fact that it was designed when hardware capable of
+ rendering 3D scenes efficiently was expensive and often only available
+ on a central server, OpenGL can work transparently across a network. OpenGL
+ was designed to be cross-platform, and as a consequence is devoid of methods,
+ also known as commands, for
+ performing windowing tasks or obtaining user input. Instead, the bulk of the
+ calls specify vertices or properties of geometric
+ primitives, such as points, lines, triangles, quads and polygons.
+ Properties may define
+ colors, textures, and material properties such as how they interact
+ with light. Through these and other calls that deal with light sources,
+ scene depth and angles, OpenGL allows one to build sophisticated 3D scenes.
+ Some of the features that go beyond regular graphics are listed
+ below.
+ </p>
+
+ <dl>
+ <dt>3D world</dt>
+ <dd>
+ Each point may be given a <i>z</i> coordinate, placing it at a
+ particular depth of the scene. If depth testing is enabled,
+ OpenGL removes those surfaces that are hidden by
+ other surfaces located closer to the viewer. A drawing may
+ be depth-cued, so that the lines further from the eye
+ appear dimmer.
+ </dd>
+ <dt>Transparency and Blending</dt>
+ <dd>
+ Colors of several objects may be combined to create a blended
+ color. This creates translucent fragments, and can be used to
+ mimic the effect of light passing through stained glass or a
+ reflection appearing on a surface. By
+ specifying transparency, or the alpha value of colors, you can
+ control how much light can pass through each object.
+ </dd>
+ <dt>Anti-aliasing</dt>
+ <dd>
+ By default, all lines drawn at an angle appear jagged on a
+ computer screen. OpenGL calculates coverage values for
+ pixels for diagonal lines, which in turn is used to compute
+ the correct blending of the pixel color with the background.
+ This blending creates the appearance of smooth rather than
+ sharp, unnatural edges.
+ </dd>
+ <dt>Projection Transformations</dt>
+ <dd>
+ The scene may use either a perspective or orthographic projection.
+ In perspective projection, objects that are further from the
+ viewer appear smaller, while the orthographic projection maintains the
+ original size of the objects. Orthographic projection is useful in applications such as CAD,
+ which should communicate information about the real size
+ of objects rather than how they may look when viewed from a distance.
+ </dd>
+ <dt>Textures</dt>
+ <dd>
+ Textures allow you to glue a 2D image to a polygon. For example,
+ by using a picture of a wooden plank you can easily create a
+ wooden wall. Texture mapping also performs required transformations
+ of the original image when the polygon onto which it was mapped
+ is reshaped.
+ </dd>
+ <dt>Lighting and Shadows</dt>
+ <dd>
+ Scenes may be lit by up to eight sources of light, each with
+ ambient, diffuse, and specular components, as well
+ as color and position.
+ Further, by specifying material type and how it reflects light, in
+ combination with textures, you can create
+ realistic looking objects. Lifelike shadows may be added to a
+ scene to further enhance the illusion of depth.
+ </dd>
+ <dt>Atmospheric effects</dt>
+ <dd>
+ Atmospheric effects add further realism to scenes by blurring
+ and dispersing light, similar to how the light reflected from
+ objects is distorted by air.
+ </dd>
+ </dl>
+
+ <p>
+ OpenGL concentrates on core 2D and 3D functionality, and as such
+ does not provide high-level commands that describe complex 3D
+ models and their dependencies. As a result, a few extensions have
+ been added for working with higher-level structures. In particular,
+ the OpenGL Utility Library (GLU <a href="#opengl-glu">[9]</a>) provides
+ a number of APIs that allow one to create more complex objects with
+ ease. Disks, cylinders, spheres, and nonuniform rational B-splines
+ (NURBS for short) are a few such examples.
+ </p>
+
+ <p>
+ Each GL command consists of the library prefix,
+ followed by the command name, followed by an optional argument
+ count, and ends with an optional argument type. This is illustrated in Figure 2. For example,
+ the <code>glVertex3f</code> has the library prefix <code>gl</code>,
+ the command <code>Vertex</code>, and it takes <code>3</code> arguments
+ of the type <code>f</code>loat. The parameter count varies between
+ 2 and 4, and parameters may be of type double (d), float (f),
+ integer (i), short (s), byte (b), unsigned integer (ui),
+ unsigned short (us), unsigned byte (ub), or a vector of any
+ of these types (*v).
+ </p>
+
+ <div class="figure">
+ <img src="images/gl_command.png" width="105" height="142" border="0" alt="GL command"><br /> <br />
+ <div class="figure-caption">
+ <span class="figure-number">Figure 2</span>. The structure of a GL command
+ </div>
+ </div>
+
+ <p>
+ One may roughly divide OpenGL methods into two types: those that
+ specify parameters of geometric primitives and those that alter
+ the state of the drawing engine. Because of this, OpenGL is often
+ described as a state machine. Parameters such as color,
+ projection transformation, line and polygon stipple patterns
+ are said to be part of the state of the OpenGL machine.
+ State can be changed by calling methods such as
+ <code>glColor*()</code> or <code>glLight*()</code>. In order
+ for state variables to impact rendering, you need to
+ enable or disable them with the <code>glEnable()</code>
+ and <code>glDisable()</code> methods, respectively. While the
+ full description of the OpenGL state machine
+ <a href="#opengl-machine">[6]</a> is well beyond the scope of this
+ article, the basic concept is simple. You can put the rendering engine
+ in a state by, for instance, defining the current color as blue, and from then on
+ all objects are drawn with this attribute until that particular state
+ variable is changed.
+ </p>
+
+ <p>
+ Drawing of objects follows the begin/end paradigm.
+ You indicate to the rendering engine, by passing the appropriate value to
+ the <code>glBegin(int)</code> method, what you are going to draw. Next,
+ you specify one or more vertices of the object's surface. Finally, you end drawing
+ by calling the <code>glEnd()</code> method.
+ There are ten geometric objects that can be drawn this way: points,
+ line segment strips, line segment loops, individual line segments,
+ polygons, triangle strips, triangle fans, individual triangles,
+ quad strips, and individual quads (quads are four-vertex surfaces such as
+ rectangles, squares and rhomboids).
+ For example, if you specify that you are drawing line strips, the first
+ vertex specifies the starting point of line segments, and every subsequent
+ vertex defines the end of the previous segment and the start of the next.
+ If you specify <i>i &gt; 1</i> vertices, <i>i-1</i> connected segments are
+ drawn. For efficiency reasons, querying the state of the OpenGL machine between
+ the begin and end calls is not guaranteed to return correct values. A single
+ scene may consist of one or more begin/end blocks.
+ </p>
+
+
+ <h2>SWT OpenGL plug-in</h2>
+
+ <p>
+ SWT exposes the functionality of OpenGL version 1.1. It consists
+ of three core classes and one data class. The core classes are
+ <code>GLContext</code>, <code>GL</code> and <code>GLU</code>.
+ The <code>GLContext</code> provides a bridge between SWT and OpenGL.
+ A context must be created with a <code>Drawable</code>, usually an
+ SWT <code>Canvas</code>, on which OpenGL renders its scenes. It is
+ important that the context be disposed when no longer needed. Also,
+ it is erroneous to attempt to render a scene once the drawable has
+ been disposed. Every time the drawable is resized, the
+ context must be notified about it through a call to its <code>resize</code>
+ method. The call allows the context to adjust its view port and perspective
+ parameters. The <a href="#groundwork">Laying
+ Groundwork</a> section describes a class that
+ takes care of most of these tasks.
+ </p>
+
+ <p>
+ A scene may be drawn by making a series of calls to methods defined
+ in the <code>GL</code> and <code>GLU</code> classes once the
+ context is made current.
+ The <code>GL</code> class exposes over 330 commands. There are
+ essentially one-to-one mappings between methods
+ defined in the <code>GL</code> and <code>GLU</code> classes
+ and their native counterparts. Figure 3 provides
+ sample code that draws a triangle. For every <code>gl*</code>
+ function in C, there is a corresponding <code>GL.gl*</code> Java method, and
+ for every enumerated value <code>GL_*</code> in C,
+ there is an equivalent <code>GL.GL_*</code> Java constant.
+ Adopting the same APIs in the SWT OpenGL plug-in makes it easy for those
+ familiar with the C language APIs to code in Java.
+ </p>
+
+ <a name="fig3"></a>
+ <table align="center">
+ <tbody>
+ <tr>
+ <td>
+ <center><b>(a)</b> C Code</center>
+<pre class="code" style="background-color: #f0fff0;">
+void drawScene() {
+ glClear(GL_COLOR_BUFFER_BIT
+ | GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity();
+ glTranslatef(0.0f, 0.0f, -5.0f);
+
+ glBegin(GL_TRIANGLES);
+ glVertex3f(-1.0f, -1.0f, 0.0f);
+ glVertex3f(1.0f, -1.0f, 0.0f);
+ glVertex3f(0.0f, 1.0f, 0.0f);
+ glEnd();
+
+ glutSwapBuffers();
+}</pre>
+ </td>
+ <td>
+ <center><b>(b)</b> Java Code</center>
+<pre class="code" style="background-color: #f0f0ff;">
+public void drawScene() {
+ GL.glClear(GL.GL_COLOR_BUFFER_BIT
+ | GL.GL_DEPTH_BUFFER_BIT);
+ GL.glLoadIdentity();
+ GL.glTranslatef(0.0f, 0.0f, -5.0f);
+
+ GL.glBegin(GL.GL_TRIANGLES);
+ GL.glVertex3f(-1.0f, -1.0f, 0.0f);
+ GL.glVertex3f(1.0f, -1.0f, 0.0f);
+ GL.glVertex3f(0.0f, 1.0f, 0.0f);
+ GL.glEnd();
+
+ glContext.swapBuffers();
+}</pre>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="figure-caption">
+ <span class="figure-number">Figure 3</span>. GL scene rendered in C and Java
+ </div>
+
+ <h3>JNI Interface</h3>
+ <p>
+ The OpenGL plug-in relies on the JNI interface to access the native OpenGL
+ libraries. The native interface consists of roughly two parts. First,
+ as OpenGL was designed to be free of hardware and operating system dependencies,
+ the <code>GL</code> and <code>GLU</code> calls can be translated to
+ identical calls under all operating systems.
+ Thus, on all three platforms you can see the following code
+ for the <code>glBegin</code> method:
+ </p>
+<pre class="code">
+JNIEXPORT void JNICALL GL_NATIVE(glBegin)
+ (JNIEnv *env, jclass that, jint arg0)
+{
+ GL_NATIVE_ENTER(env, that, glBegin_FUNC);
+ glBegin(arg0);
+ GL_NATIVE_EXIT(env, that, glBegin_FUNC);
+}</pre>
+
+ <p>
+ The difference between the three available implementations is how the
+ SWT drawable is hooked up with the native GL context. This code
+ is internal to the SWT OpenGL plug-in and is platform-dependent. For example, both
+ the GTK and Motif implementations use GLX, "the glue connecting
+ OpenGL and the X Windowing System", while the Windows native
+ interface is provided through a similar Windows library called WGL.
+ At the time of this writing there was no plug-in for Apple's
+ OpenGL for Mac OS.
+ </p>
+
+ <h3>Alternatives</h3>
+ <p>
+ There exist alternative solutions for performing 3D drawing in Java. For example, Sun maintains
+ <a href="http://java.sun.com/products/java-media/3D/">Java 3D</a>, which
+ unlike OpenGL,
+ provides a set of object-oriented interfaces that support a
+ high-level programming model for building, rendering, and controlling
+ the behavior of 3D objects. Closer to the spirit of the SWT OpenGL plug-in
+ is the <a href="https://jogl.dev.java.net/">JOGL</a> project, which provides access to OpenGL commands for drawing on AWT and Swing components.
+ While both solutions are
+ more mature than the SWT OpenGL plug-in project, they both target Swing and
+ AWT, and therefore do not tie in to the Eclipse environment
+ and SWT as directly as the SWT OpenGL plug-in does.
+ </p>
+
+ <h2>Example Application</h2>
+
+ <p>
+ In the following sections I describe a simple application that shows a
+ 3D chart of four quantities. The application uses
+ <code>GLScene</code>, which is a utility class for displaying OpenGL scenes.
+ In order to facilitate looking at a scene from various angles
+ and zoom levels, a scene grip is added; the
+ grip uses either the mouse or the keyboard to do zooming and
+ panning. Both the <code>GLScene</code> class and the grip are of a generic nature and may
+ be reused in other applications that use OpenGL. These components
+ are described first.
+ </p>
+
+ <a name="groundwork"></a>
+ <h3>Laying Groundwork</h3>
+ <p>
+ The <code>GLScene</code> class is similar to SWT's
+ <code>Canvas</code>. However, rather than using
+ a <code>GC</code> to draw on it, its content is
+ rendered by OpenGL commands. This is achieved by associating
+ a <code>GLContext</code> with an SWT <code>Canvas</code>
+ and making it the current context whenever a scene is
+ rendered by the commands defined in the <code>drawScene</code>
+ method.
+ </p>
+
+<pre class="code">
+<a name="line1"> 1</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">class</span> <span class="c2h_identifier">GLScene</span> <span class="c2h_braces">{</span>
+<a name="line2"> 2</a> <span class="c2h_reserved_word">private</span> <span class="c2h_identifier">GLContext</span> <span class="c2h_identifier">context</span><span class="c2h_symbol">;</span>
+<a name="line3"> 3</a> <span class="c2h_reserved_word">private</span> <span class="c2h_identifier">Canvas</span> <span class="c2h_identifier">canvas</span><span class="c2h_symbol">;</span>
+<a name="line4"> 4</a>
+<a name="line5"> 5</a> <span class="c2h_reserved_word">public</span> <span class="c2h_identifier">GLScene</span><span class="c2h_braces">(</span><span class="c2h_identifier">Composite</span> <span class="c2h_identifier">parent</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line6"> 6</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">canvas</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">new</span> <span class="c2h_identifier">Canvas</span><span class="c2h_braces">(</span><span class="c2h_identifier">parent</span>, <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">NONE</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line7"> 7</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">canvas</span>.<span class="c2h_identifier">addControlListener</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">new</span> <span class="c2h_identifier">ControlAdapter</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line8"> 8</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">controlResized</span><span class="c2h_braces">(</span><span class="c2h_identifier">ControlEvent</span> <span class="c2h_identifier">e</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line9"> 9</a> <span class="c2h_identifier">resizeScene</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line10">10</a> <span class="c2h_braces">}</span>
+<a name="line11">11</a> <span class="c2h_braces">}</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line12">12</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">canvas</span>.<span class="c2h_identifier">addDisposeListener</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">new</span> <span class="c2h_identifier">DisposeListener</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line13">13</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">widgetDisposed</span><span class="c2h_braces">(</span><span class="c2h_identifier">DisposeEvent</span> <span class="c2h_identifier">e</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line14">14</a> <span class="c2h_identifier">dispose</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line15">15</a> <span class="c2h_braces">}</span>
+<a name="line16">16</a> <span class="c2h_braces">}</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line17">17</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">init</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line18">18</a> <span class="c2h_identifier">Rectangle</span> <span class="c2h_identifier">clientArea</span> <span class="c2h_symbol">=</span> <span class="c2h_identifier">parent</span>.<span class="c2h_identifier">getClientArea</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line19">19</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">canvas</span>.<span class="c2h_identifier">setSize</span><span class="c2h_braces">(</span><span class="c2h_identifier">clientArea</span>.<span class="c2h_identifier">width</span>, <span class="c2h_identifier">clientArea</span>.<span class="c2h_identifier">height</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line20">20</a> <span class="c2h_braces">}</span>
+</pre>
+
+ <p>
+ In the constructor, a new SWT <code>Canvas</code> is created. This is
+ the canvas that is associated with a <code>GLContext</code>
+ instance. Immediately, two listeners are registered on it. The first
+ listener makes sure that whenever the canvas is resized the <code>GLContext</code>
+ is notified and appropriately resized. The second listener takes care of
+ disposing the context once the canvas is disposed. In order to make sure
+ that the rendering area is of non-zero size, the client rectangle of
+ the parent is fetched and used to set the initial size of the canvas.
+ This size may later be changed either by a layout manager or user
+ actions.
+ </p>
+<pre class="code">
+<a name="line22">22</a> <span class="c2h_reserved_word">protected</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">resizeScene</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line23">23</a> <span class="c2h_identifier">Rectangle</span> <span class="c2h_identifier">rect</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">canvas</span>.<span class="c2h_identifier">getClientArea</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line24">24</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">context</span>.<span class="c2h_identifier">resize</span><span class="c2h_braces">(</span><span class="c2h_numeric">0</span>, <span class="c2h_numeric">0</span>, <span class="c2h_identifier">rect</span>.<span class="c2h_identifier">width</span>, <span class="c2h_identifier">rect</span>.<span class="c2h_identifier">height</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line25">25</a> <span class="c2h_braces">}</span>
+<a name="line26">26</a>
+<a name="line27">27</a> <span class="c2h_reserved_word">protected</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">dispose</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line28">28</a> <span class="c2h_reserved_word">if</span> <span class="c2h_braces">(<span class="c2h_reserved_word">this</span>.</span><span class="c2h_identifier">context</span> <span class="c2h_symbol">!</span><span class="c2h_symbol">=</span> <span class="c2h_reserved_word">null</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line29">29</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">context</span>.<span class="c2h_identifier">dispose</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line30">30</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">context</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">null</span><span class="c2h_symbol">;</span>
+<a name="line31">31</a> <span class="c2h_braces">}</span>
+<a name="line32">32</a> <span class="c2h_braces">}</span>
+</pre>
+ <p>
+ <code>GLScene</code> uses the entire area of the canvas for
+ drawing. Whenever the canvas is resized, we fetch the client area and
+ pass the new width and height to the context. Based on the new width
+ and height, the context adjusts the view appropriately.
+ </p>
+ <p>
+ Disposing the canvas (line 27) requires that we dispose the context.
+ This is particularly important in operating systems where a limited
+ number of device contexts are available. To prevent multiple calls to
+ the <code>dispose</code> method of the context, once it is disposed it
+ is set to <code>null</code>.
+ </p>
+<pre class="code">
+<a name="line34">34</a> <span class="c2h_reserved_word">protected</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">init</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line35">35</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">initGLContext</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line36">36</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">initGL</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line37">37</a> <span class="c2h_braces">}</span>
+<a name="line38">38</a>
+<a name="line39">39</a> <span class="c2h_reserved_word">protected</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">initGLContext</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line40">40</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">context</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">new</span> <span class="c2h_identifier">GLContext</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">canvas</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line41">41</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">context</span>.<span class="c2h_identifier">setCurrent</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line42">42</a> <span class="c2h_braces">}</span>
+<a name="line43">43</a>
+<a name="line44">44</a> <span class="c2h_reserved_word">protected</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">initGL</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line45">45</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glClearColor</span><span class="c2h_braces">(</span><span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line46">46</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glClearDepth</span><span class="c2h_braces">(</span><span class="c2h_numeric">1.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line47">47</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glDepthFunc</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_LEQUAL</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line48">48</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glEnable</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_DEPTH_TEST</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line49">49</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glShadeModel</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_SMOOTH</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line50">50</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glHint</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_PERSPECTIVE_CORRECTION_HINT</span>, <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_NICEST</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line51">51</a> <span class="c2h_braces">}</span>
+</pre>
+ <p>
+ The <code>GLScene</code> initialization is split into two parts:
+ initializing the context and initializing the state machine of
+ OpenGL. For the context, we simply create a new <code>GLContext</code> and make it
+ current. OpenGL rendering always draws on the current
+ context, and thus if you have more than one <code>GLScene</code>
+ active, it is important to make its context current before any
+ drawing takes place. The <code>initGL</code> method is a bit more
+ interesting. It begins by specifying the color used to clean color buffers
+ (black). Next, the
+ depth buffer is set up; line 46 establishes the
+ depth value used when the depth buffer is cleared (this value must be between 0.0 and 1.0), and line 47 specifies how
+ depth value comparisons are done. This comparison function is used to
+ reject or accept incoming pixels, and
+ <code>GL.GL_LEQUAL</code> in particular accepts only those pixels that are
+ closer to or at an equal distance from the viewer. Line 48 enables
+ depth testing, since as was mentioned before, not only must the OpenGL state machine
+ be set in a particular state, but the state must also be enabled in order to
+ impact rendering. The
+ next line sets the shade model to <code>GL.GL_SMOOTH</code>, which
+ interpolates colors (smooths them out) if two vertices
+ of a surface have different colors. Finally, line 50 asks
+ the rendering engine to put a significant effort into the computing of color and texture coordinate interpolation.
+ On older and slower hardware you may wish to use <code>GL.GL_FASTEST</code>
+ or <code>GL.GL_DONT_CARE</code> instead.
+ </p>
+<pre class="code">
+<a name="line53">53</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">render</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line54">54</a> <span class="c2h_reserved_word">if</span> <span class="c2h_braces">(</span><span class="c2h_symbol">!</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">context</span>.<span class="c2h_identifier">isCurrent</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line55">55</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">context</span>.<span class="c2h_identifier">setCurrent</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line56">56</a> <span class="c2h_braces">}</span>
+<a name="line57">57</a>
+<a name="line58">58</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">drawScene</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line59">59</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">context</span>.<span class="c2h_identifier">swapBuffers</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line60">60</a> <span class="c2h_braces">}</span>
+<a name="line61">61</a>
+<a name="line62">62</a> <span class="c2h_reserved_word">protected</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">drawScene</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line63">63</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glClear</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_COLOR_BUFFER_BIT</span> <span class="c2h_symbol">|</span> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_DEPTH_BUFFER_BIT</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line64">64</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glLoadIdentity</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line65">65</a> <span class="c2h_braces">}</span>
+</pre>
+
+ <p>
+ The final two methods of the <code>GLScene</code> class deal with
+ repainting and scene drawing. The first method is exposed to other
+ classes and should be used whenever a repaint of the scene is
+ needed. As an example, one could repeatedly call it to display
+ animation. The second method is meant to be overridden by
+ extending classes. Its default implementation simply clears the color and depth buffers and
+ restores the coordinate system by loading the identify matrix.
+ </p>
+
+ <h3>A Scene Grip</h3>
+
+ <p>
+ One of the nice things about 3D is that it allows you to view scenes
+ in perspective, with obstructed objects hidden. However,
+ sometimes you might want to view a scene from a different angle, so
+ that what was hidden becomes visible and what was in the foreground
+ moves to the background. OpenGL provides two methods that can be
+ used to achieve just that. The <code>glRotate</code> method allows
+ you to rotate your scene by any angle in the x, y and z planes.
+ For example, <code>GL.glRotatef(180f, 0f, 1f, 0f)</code> rotates
+ the scene by 180 degrees and thus makes its furthest point become the
+ closest to the viewer. <code>GL.glRotatef(180f, 1f, 0f, 0f)</code>
+ flips the scene upside down (see Figure 4).
+ Scene translation can be achieved by calling the <code>GL.glTranslate</code>
+ method, which takes three parameters, <i>x</i>, <i>y</i> and <i>z</i>,
+ to indicate how many units to move the scene in each direction. For
+ example, <code>GL.glTranslatef(5f, -1f, -2f)</code> moves the
+ scene 5 units to the right, 1 unit down, and 2 units away from the viewer.
+ </p>
+
+ <div class="figure">
+ <img src="images/rotation5.png" width="242" height="245" border="0" alt="rotation">
+ <div class="figure-caption">
+ <span class="figure-number">Figure 4</span>. Scene rotation
+ </div>
+ </div>
+
+ <p>
+ In order to provide the ability to move and rotate a scene, we
+ need to perform the appropriate transformation before the scene is
+ being rendered. The solution developed in this article relies on an
+ external class, a <code>SceneGrip</code>, that does necessary rotations
+ and translations. How much the scene is transformed is dictated by
+ internal variables. These, in turn, are adjusted on key and mouse events.
+ </p>
+<pre class="code">
+<a name="line31"> 31</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">class</span> <span class="c2h_identifier">SceneGrip</span> <span class="c2h_reserved_word">extends</span> <span class="c2h_identifier">MouseAdapter</span>
+<a name="line32"> 32</a> <span class="c2h_reserved_word">implements</span> <span class="c2h_identifier">MouseMoveListener</span>, <span class="c2h_identifier">Listener</span>, <span class="c2h_identifier">KeyListener</span> <span class="c2h_braces">{</span>
+<a name="line33"> 33</a> <span class="c2h_reserved_word">private</span> <span class="c2h_reserved_word">float</span> <span class="c2h_identifier">xrot</span><span class="c2h_symbol">;</span>
+<a name="line34"> 34</a> <span class="c2h_reserved_word">private</span> <span class="c2h_reserved_word">float</span> <span class="c2h_identifier">yrot</span><span class="c2h_symbol">;</span>
+<a name="line35"> 35</a> <span class="c2h_reserved_word">private</span> <span class="c2h_reserved_word">float</span> <span class="c2h_identifier">zoff</span><span class="c2h_symbol">;</span>
+<a name="line36"> 36</a> <span class="c2h_reserved_word">private</span> <span class="c2h_reserved_word">float</span> <span class="c2h_identifier">xoff</span><span class="c2h_symbol">;</span>
+<a name="line37"> 37</a> <span class="c2h_reserved_word">private</span> <span class="c2h_reserved_word">float</span> <span class="c2h_identifier">yoff</span><span class="c2h_symbol">;</span>
+...
+<a name="line45"> 45</a> <span class="c2h_reserved_word">public</span> <span class="c2h_identifier">SceneGrip</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line46"> 46</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">init</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line47"> 47</a> <span class="c2h_braces">}</span>
+<a name="line48"> 48</a>
+<a name="line49"> 49</a> <span class="c2h_reserved_word">protected</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">init</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line50"> 50</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">xrot</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">yrot</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">0.0f</span><span class="c2h_symbol">;</span>
+<a name="line51"> 51</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">xoff</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">yoff</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">0.0f</span><span class="c2h_symbol">;</span>
+<a name="line52"> 52</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">zoff</span> <span class="c2h_symbol">=</span> <span class="c2h_symbol">-</span><span class="c2h_numeric">8.0f</span><span class="c2h_symbol">;</span>
+<a name="line53"> 53</a> <span class="c2h_braces">}</span>
+</pre>
+
+ <p>
+ The class defines two variables that store the current angle of the
+ rotation along the <i>x</i> and <i>y</i> axis. In addition, three
+ variables remember by how much to move a scene in each of the three
+ directions. The initial values of all of the variables, except for the
+ <i>z</i> offset, are set to 0.0f. The offset along the <i>z</i> axis
+ is set to <i>-8.0f</i> so that the scene has some separation
+ from the viewer. Setting <i>z</i> offset to 0.0f would be equivalent to
+ jamming the scene up against the viewer's nose.
+ </p>
+<pre class="code">
+<a name="line99"> 99</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">keyPressed</span><span class="c2h_braces">(</span><span class="c2h_identifier">KeyEvent</span> <span class="c2h_identifier">e</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line100">100</a> <span class="c2h_reserved_word">switch</span> <span class="c2h_braces">(</span><span class="c2h_identifier">e</span>.<span class="c2h_identifier">keyCode</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line101">101</a> <span class="c2h_reserved_word">case</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">ARROW_UP</span><span class="c2h_symbol">:</span>
+<a name="line102">102</a> <span class="c2h_reserved_word">if</span> <span class="c2h_braces">(</span><span class="c2h_braces">(</span><span class="c2h_identifier">e</span>.<span class="c2h_identifier">stateMask</span> <span class="c2h_symbol">&amp;</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">CTRL</span><span class="c2h_braces">)</span> <span class="c2h_symbol">!</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line103">103</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">xrot</span> <span class="c2h_symbol">-</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.5f</span><span class="c2h_symbol">;</span>
+<a name="line104">104</a> <span class="c2h_braces">}</span> <span class="c2h_reserved_word">else</span> <span class="c2h_braces">{</span>
+<a name="line105">105</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">yoff</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.05f</span><span class="c2h_symbol">;</span>
+<a name="line106">106</a> <span class="c2h_braces">}</span>
+<a name="line107">107</a> <span class="c2h_reserved_word">break</span><span class="c2h_symbol">;</span>
+<a name="line108">108</a> <span class="c2h_reserved_word">case</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">ARROW_DOWN</span><span class="c2h_symbol">:</span>
+<a name="line109">109</a> <span class="c2h_reserved_word">if</span> <span class="c2h_braces">(</span><span class="c2h_braces">(</span><span class="c2h_identifier">e</span>.<span class="c2h_identifier">stateMask</span> <span class="c2h_symbol">&amp;</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">CTRL</span><span class="c2h_braces">)</span> <span class="c2h_symbol">!</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line110">110</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">xrot</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.5f</span><span class="c2h_symbol">;</span>
+<a name="line111">111</a> <span class="c2h_braces">}</span> <span class="c2h_reserved_word">else</span> <span class="c2h_braces">{</span>
+<a name="line112">112</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">yoff</span> <span class="c2h_symbol">-</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.05f</span><span class="c2h_symbol">;</span>
+<a name="line113">113</a> <span class="c2h_braces">}</span>
+<a name="line114">114</a> <span class="c2h_reserved_word">break</span><span class="c2h_symbol">;</span>
+<a name="line115">115</a> <span class="c2h_reserved_word">case</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">ARROW_LEFT</span><span class="c2h_symbol">:</span>
+<a name="line116">116</a> <span class="c2h_reserved_word">if</span> <span class="c2h_braces">(</span><span class="c2h_braces">(</span><span class="c2h_identifier">e</span>.<span class="c2h_identifier">stateMask</span> <span class="c2h_symbol">&amp;</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">CTRL</span><span class="c2h_braces">)</span> <span class="c2h_symbol">!</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line117">117</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">yrot</span> <span class="c2h_symbol">-</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.5f</span><span class="c2h_symbol">;</span>
+<a name="line118">118</a> <span class="c2h_braces">}</span> <span class="c2h_reserved_word">else</span> <span class="c2h_braces">{</span>
+<a name="line119">119</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">xoff</span> <span class="c2h_symbol">-</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.05f</span><span class="c2h_symbol">;</span>
+<a name="line120">120</a> <span class="c2h_braces">}</span>
+<a name="line121">121</a> <span class="c2h_reserved_word">break</span><span class="c2h_symbol">;</span>
+<a name="line122">122</a> <span class="c2h_reserved_word">case</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">ARROW_RIGHT</span><span class="c2h_symbol">:</span>
+<a name="line123">123</a> <span class="c2h_reserved_word">if</span> <span class="c2h_braces">(</span><span class="c2h_braces">(</span><span class="c2h_identifier">e</span>.<span class="c2h_identifier">stateMask</span> <span class="c2h_symbol">&amp;</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">CTRL</span><span class="c2h_braces">)</span> <span class="c2h_symbol">!</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line124">124</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">yrot</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.5f</span><span class="c2h_symbol">;</span>
+<a name="line125">125</a> <span class="c2h_braces">}</span> <span class="c2h_reserved_word">else</span> <span class="c2h_braces">{</span>
+<a name="line126">126</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">xoff</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.05f</span><span class="c2h_symbol">;</span>
+<a name="line127">127</a> <span class="c2h_braces">}</span>
+<a name="line128">128</a> <span class="c2h_reserved_word">break</span><span class="c2h_symbol">;</span>
+<a name="line129">129</a> <span class="c2h_reserved_word">case</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">PAGE_UP</span><span class="c2h_symbol">:</span>
+<a name="line130">130</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">zoff</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.05f</span><span class="c2h_symbol">;</span>
+<a name="line131">131</a> <span class="c2h_reserved_word">break</span><span class="c2h_symbol">;</span>
+<a name="line132">132</a> <span class="c2h_reserved_word">case</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">PAGE_DOWN</span><span class="c2h_symbol">:</span>
+<a name="line133">133</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">zoff</span> <span class="c2h_symbol">-</span><span class="c2h_symbol">=</span> <span class="c2h_numeric">0.05f</span><span class="c2h_symbol">;</span>
+<a name="line134">134</a> <span class="c2h_reserved_word">break</span><span class="c2h_symbol">;</span>
+<a name="line135">135</a> <span class="c2h_reserved_word">case</span> <span class="c2h_identifier">SWT</span>.<span class="c2h_identifier">HOME</span><span class="c2h_symbol">:</span>
+<a name="line136">136</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">init</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line137">137</a> <span class="c2h_reserved_word">break</span><span class="c2h_symbol">;</span>
+<a name="line138">138</a> <span class="c2h_braces">}</span>
+<a name="line139">139</a> <span class="c2h_braces">}</span>
+</pre>
+
+ <p>
+ Upon receiving a key event, we adjust the offset and rotation variables.
+ The convention used here is that if the Ctrl key is pressed, pressing
+ arrow keys rotates the scene. Otherwise, pressing arrow keys moves the scene. For example,
+ when the arrow up key is pressed we either increase the <i>y</i> offset,
+ moving the scene up, or decrease the <i>x</i> angle, twisting the scene
+ so that the part closest to the viewer is lifted up, and the part
+ furthest away from the user is rotated down. The left arrow performs a
+ similar function for the <i>x</i> offset or <i>y</i> axis rotation.
+ Page up and page down keys are used to zoom in and out.
+ Finally, hitting the Home key restores the scene to its original settings.
+ (The step size values
+ chosen here work well for small scenes. For larger scenes,
+ the step size should be calculated based on how far the viewer is from the
+ center of the scene. However, for simplicity this has been omitted in this example.)
+ </p>
+
+<pre class="code">
+<a name="line144">144</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">adjust</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line145">145</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glTranslatef</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">xoff</span>, <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">yoff</span>, <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">zoff</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line146">146</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glRotatef</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">xrot</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line147">147</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glRotatef</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">yrot</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line148">148</a> <span class="c2h_braces">}</span>
+</pre>
+ <p>
+ The <code>adjust</code> method performs necessary translations and
+ rotations of the scene. Just like other OpenGL operations, they
+ are applied to the current context. As the reader may notice, the
+ translations can be performed in one call. However, to enable independent
+ rotation in the <i>x</i> and <i>y</i> axis, two <code>glRotatef</code> calls passing the
+ appropriate <i>x</i> and <i>y</i> angles are made. To make use of the
+ scene grip, the <code>GLScene</code> class needs to be modified. When
+ creating a new instance, a scene grip must be created and register as
+ a listener of mouse, mouse move, and key events of the SWT canvas. In <code>drawScene</code>,
+ a call must be made to the <code>adjust</code> method before any GL
+ calls are made (see next section).
+ </p>
+
+ <h3>3D Charting</h3>
+
+ <p>
+ With all the above preparations, we are ready to dive into the main
+ application. The chart shows four sets of data. Each set consists
+ of the same, fixed number of points, each point being a positive value
+ between 0.0 and 10.0. These requirements are intentionally simple,
+ so that the brunt of the work can go into developing OpenGL
+ code rather than dealing with issues of scaling, missing points,
+ disparate axis ranges, and other challenges that a true charting application
+ needs to address.
+ </p>
+ <p>
+ The demo runs as a very simple Eclipse view (a stand-alone SWT
+ application is
+ also included in the provided source code). The only
+ interesting addition is the <code>Refresher</code>, which
+ periodically forces repainting of the OpenGL scene.
+ This way, as the viewpoint is moved or rotated, the up-to-date
+ rendering is shown in the component. The refresher, which is launched
+ just after the SWT control for the view
+ is created, repeatedly calls the
+ <code>redraw</code> method of the scene. The calls are spaced
+ every 100ms, giving it a theoretical rate of 10 frames per second.
+ </p>
+<pre class="code">
+<a name="line13">13</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">class</span> <span class="c2h_identifier">Refresher</span> <span class="c2h_reserved_word">implements</span> <span class="c2h_identifier">Runnable</span> <span class="c2h_braces">{</span>
+<a name="line14">14</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">static</span> <span class="c2h_reserved_word">final</span> <span class="c2h_reserved_word">int</span> <span class="c2h_identifier">DELAY</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">100</span><span class="c2h_symbol">;</span>
+<a name="line15">15</a>
+<a name="line16">16</a> <span class="c2h_reserved_word">private</span> <span class="c2h_identifier">GLScene</span> <span class="c2h_identifier">scene</span><span class="c2h_symbol">;</span>
+<a name="line17">17</a>
+<a name="line18">18</a> <span class="c2h_reserved_word">public</span> <span class="c2h_identifier">Refresher</span><span class="c2h_braces">(</span><span class="c2h_identifier">GLScene</span> <span class="c2h_identifier">scene</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line19">19</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">scene</span> <span class="c2h_symbol">=</span> <span class="c2h_identifier">scene</span><span class="c2h_symbol">;</span>
+<a name="line20">20</a> <span class="c2h_braces">}</span>
+<a name="line21">21</a>
+<a name="line22">22</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">run</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line23">23</a> <span class="c2h_reserved_word">if</span> <span class="c2h_braces">(</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">scene</span> <span class="c2h_symbol">!</span><span class="c2h_symbol">=</span> <span class="c2h_reserved_word">null</span> <span class="c2h_symbol">&amp;</span><span class="c2h_symbol">&amp;</span> <span class="c2h_symbol">!</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">scene</span>.<span class="c2h_identifier">isDisposed</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line24">24</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">scene</span>.<span class="c2h_identifier">render</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line25">25</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">scene</span>.<span class="c2h_identifier">getDisplay</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span>.<span class="c2h_identifier">timerExec</span><span class="c2h_braces">(</span><span class="c2h_identifier">DELAY</span>, <span class="c2h_reserved_word">this</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line26">26</a> <span class="c2h_braces">}</span>
+<a name="line27">27</a> <span class="c2h_braces">}</span>
+<a name="line28">28</a> <span class="c2h_braces">}</span>
+</pre>
+
+ <p>
+ The values of points of each data set are represented
+ by cylinders. Rendering a cylinder can be achieved
+ by executing three GLU calls: two to render the disks needed at
+ both ends of the cylinder, and one to render the cylinder walls. For
+ example, to draw a cylinder 2 units long, you could use the
+ code shown in Figure 5.
+ </p>
+
+ <table align="center" width="80%">
+ <tbody>
+ <tr>
+ <td width="50%">
+<pre class="code">
+<a name="line1">1</a> <span class="c2h_reserved_word">int</span> <span class="c2h_identifier">qobj</span> <span class="c2h_symbol">=</span> <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluNewQuadric</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line2">2</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glRotatef</span><span class="c2h_braces">(</span><span class="c2h_symbol">-</span><span class="c2h_numeric">90.0f</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line3">3</a> <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluDisk</span><span class="c2h_braces">(</span><span class="c2h_identifier">qobj</span>, <span class="c2h_numeric">0.0</span>, <span class="c2h_numeric">1.0</span>, <span class="c2h_numeric">32</span>, <span class="c2h_numeric">1</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line4">4</a> <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluCylinder</span><span class="c2h_braces">(</span><span class="c2h_identifier">qobj</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">1.0</span>, <span class="c2h_numeric">2.0</span>, <span class="c2h_numeric">32</span>, <span class="c2h_numeric">1</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line5">5</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glTranslatef</span><span class="c2h_braces">(</span><span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">2.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line6">6</a> <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluDisk</span><span class="c2h_braces">(</span><span class="c2h_identifier">qobj</span>, <span class="c2h_numeric">0.0</span>, <span class="c2h_numeric">1.0</span>, <span class="c2h_numeric">32</span>, <span class="c2h_numeric">1</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line7">7</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glTranslatef</span><span class="c2h_braces">(</span><span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_symbol">-</span><span class="c2h_numeric">2.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line8">8</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glRotatef</span><span class="c2h_braces">(</span><span class="c2h_numeric">90.0f</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line9">9</a> <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluDeleteQuadric</span><span class="c2h_braces">(</span><span class="c2h_identifier">qobj</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+</pre>
+ </td>
+ <td width="50%" align="center">
+ <img src="images/cylinder.png" width="82" height="105" alt="Cylinder">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="figure-caption">
+ <span class="figure-number">Figure 5</span>. Code for rendering a cylinder and its result
+ </div>
+
+ <p>
+ The first line allocates a new quadric needed by the disk and cylinder
+ calls. The scene is then rotated by -90 degrees, so that the cylinder is
+ drawn upright. Next, the bottom disk is rendered, followed by the
+ cylinder walls (the value of 32 indicates how many slices are to be used to
+ approximate the circular perimeter of both, and
+ gives a fair approximation of roundness). Before we can draw the
+ top disk, we need to move 2 units along the z-axis,
+ which is done by
+ performing a scene translation. The final disk is then drawn and
+ the coordinate system is restored by moving back by 2 units and
+ twisting it in the opposite direction. Finally, the
+ quadric that was allocated in line 1 is deleted.
+ </p>
+ <p>
+ While this approach works, it is also time-consuming. When drawing
+ one cylinder the inefficiency is not a problem, but rendering hundreds
+ of them could severely impact the program's performance. OpenGL provides
+ a solution for such situations, allowing us to perform a cooking
+ show trick - rather than "baking" the scene in front of a live
+ audience, we can ask OpenGL to use the one we prepared earlier. This
+ trick can be done by using display lists.
+ </p>
+ <p>
+ A display list is a collection of compiled OpenGL commands. A list
+ is defined by the set of commands placed between the
+ <code>glNewList(int list, int mode)</code> and <code>glEndList()</code>
+ method calls. The first parameter must be a positive integer that
+ uniquely identifies the display list being created. You can ask
+ GL to create one or more list identifiers for you, using the
+ <code>glGenLists(int n)</code>
+ method. The second <code>glNewList</code> parameter specifies whether the list is compiled
+ or compiled and immediately executed. Most of the time you probably just
+ want to compile the list. Later, you can display the list by
+ calling the <code>glCallList(int list)</code> method with the
+ identifier of the list to be displayed. For example, the triangle
+ code shown in <a href="#fig3">Figure&nbsp;3</a> could be turned into a list using the
+ following code:
+ </p>
+<pre class="code">
+<span class="c2h_identifier">triangle</span> <span class="c2h_symbol">=</span> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glGenLists</span><span class="c2h_braces">(</span><span class="c2h_numeric">1</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glNewList</span><span class="c2h_braces">(</span><span class="c2h_identifier">triangle</span>, <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_COMPILE</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glBegin</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_TRIANGLES</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glVertex3f</span><span class="c2h_braces">(</span><span class="c2h_symbol">-</span><span class="c2h_numeric">1.0f</span>, <span class="c2h_symbol">-</span><span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glVertex3f</span><span class="c2h_braces">(</span><span class="c2h_numeric">1.0f</span>, <span class="c2h_symbol">-</span><span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glVertex3f</span><span class="c2h_braces">(</span><span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glEnd</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glEndList</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+</pre>
+ <p>
+ To display it in, for instance, the <code>drawScene</code> method, you would simply
+ call <code>glCallList(triangle)</code>. Finally, you should also delete
+ any lists no longer needed by calling the <code>glDeleteLists(int list, int range)</code>
+ method. If you allocated just one list, the <code>range</code> is set
+ to 1.
+ </p>
+ <p>
+ In the charting application we are using two kinds of display lists,
+ one to represent a particular value in a chart, and the other to
+ draw chart axes. To simplify chart rendering, I defined a common
+ base class, the <code>CompiledShape</code>. In the constructor, it
+ grabs the next available list index. In addition, it defines three
+ methods: one for accessing the list index (line 8), one for rendering the
+ pre-compiled list (line 12), and one for deleting it (line 16).
+ </p>
+<pre class="code">
+<a name="line1"> 1</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">abstract</span> <span class="c2h_reserved_word">class</span> <span class="c2h_identifier">CompiledShape</span> <span class="c2h_braces">{</span>
+<a name="line2"> 2</a> <span class="c2h_reserved_word">private</span> <span class="c2h_reserved_word">int</span> <span class="c2h_identifier">listIndex</span><span class="c2h_symbol">;</span>
+<a name="line3"> 3</a>
+<a name="line4"> 4</a> <span class="c2h_reserved_word">public</span> <span class="c2h_identifier">CompiledShape</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line5"> 5</a> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">listIndex</span> <span class="c2h_symbol">=</span> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glGenLists</span><span class="c2h_braces">(</span><span class="c2h_numeric">1</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line6"> 6</a> <span class="c2h_braces">}</span>
+<a name="line7"> 7</a>
+<a name="line8"> 8</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">int</span> <span class="c2h_identifier">getListIndex</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line9"> 9</a> <span class="c2h_reserved_word">return</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">listIndex</span><span class="c2h_symbol">;</span>
+<a name="line10">10</a> <span class="c2h_braces">}</span>
+<a name="line11">11</a>
+<a name="line12">12</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">draw</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line13">13</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glCallList</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">getListIndex</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line14">14</a> <span class="c2h_braces">}</span>
+<a name="line15">15</a>
+<a name="line16">16</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">dispose</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line17">17</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glDeleteLists</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">getListIndex</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span>, <span class="c2h_numeric">1</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line18">18</a> <span class="c2h_braces">}</span>
+<a name="line19">19</a> <span class="c2h_braces">}</span>
+</pre>
+ <p>
+ The values of the chart are represented by instances of
+ the <code>CompiledShape</code> class. Note that <code>CompiledShape</code>
+ does not create a display list, but leaves this task to the constructors
+ of extending classes. For the <code>BarValue</code> we reuse the
+ same quadric for each generated list. For a value passed to the
+ constructor, we build a cylinder in a similar manner as previously
+ described. The only two significant differences here are that the cylinder is
+ compiled into a display list (lines 6-14), and the specified <code>value</code>
+ is used to render the cylinder height (lines 8 and 10).
+ </p>
+<pre class="code">
+<a name="line1"> 1</a> <span class="c2h_reserved_word">private</span> <span class="c2h_reserved_word">static</span> <span class="c2h_reserved_word">class</span> <span class="c2h_identifier">BarValue</span> <span class="c2h_reserved_word">extends</span> <span class="c2h_identifier">CompiledShape</span> <span class="c2h_braces">{</span>
+<a name="line2"> 2</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">static</span> <span class="c2h_reserved_word">final</span> <span class="c2h_reserved_word">float</span> <span class="c2h_identifier">RADIUS</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">1.0f</span><span class="c2h_symbol">;</span>
+<a name="line3"> 3</a> <span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">static</span> <span class="c2h_reserved_word">int</span> <span class="c2h_identifier">QUADRIC</span></span><span class="c2h_symbol">;</span>
+<a name="line4"> 4</a>
+<a name="line5"> 5</a> <span class="c2h_reserved_word">public</span> <span class="c2h_identifier">BarValue</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">float</span> <span class="c2h_identifier">value</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+<a name="line6"> 6</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glNewList</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">getListIndex</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span>, <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_COMPILE</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line7"> 7</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glRotatef</span><span class="c2h_braces">(</span><span class="c2h_symbol">-</span><span class="c2h_numeric">90.0f</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line8"> 8</a> <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluCylinder</span><span class="c2h_braces">(</span><span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">QUADRIC</span>, <span class="c2h_identifier">RADIUS</span>, <span class="c2h_identifier">RADIUS</span>, <span class="c2h_identifier">value</span>, <span class="c2h_numeric">32</span>, <span class="c2h_numeric">1</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line9"> 9</a> <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluDisk</span><span class="c2h_braces">(</span><span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">QUADRIC</span>, <span class="c2h_numeric">0.0</span>, <span class="c2h_identifier">RADIUS</span>, <span class="c2h_numeric">32</span>, <span class="c2h_numeric">32</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line10">10</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glTranslatef</span><span class="c2h_braces">(</span><span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_identifier">value</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line11">11</a> <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluDisk</span><span class="c2h_braces">(</span><span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">QUADRIC</span>, <span class="c2h_numeric">0.0</span>, <span class="c2h_identifier">RADIUS</span>, <span class="c2h_numeric">32</span>, <span class="c2h_numeric">32</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line12">12</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glTranslatef</span><span class="c2h_braces">(</span><span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_symbol">-</span><span class="c2h_identifier">value</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line13">13</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glRotatef</span><span class="c2h_braces">(</span><span class="c2h_numeric">90.0f</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line14">14</a> <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glEndList</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<a name="line15">15</a> <span class="c2h_braces">}</span>
+<a name="line16">16</a> <span class="c2h_braces">}</span>
+</pre>
+
+ <p>
+ The widget on which the chart is drawn is a modification of the previously
+ introduced <code>GLScene</code> class. It overrides a number of methods
+ to add functionality needed by the application. Its <code>initGL</code>
+ method starts by setting up and enabling color blending. This creates
+ translucent rather than opaque cylinders, allowing us to view chart
+ values that would normally be hidden. To add the 3D realism, a light
+ source is set up. It emits a dim white light and a bright diffuse
+ (directional) light. The light is positioned above and to the left
+ of the scene. Finally, compiled shapes are created. First the axes
+ are set up, then bar values are generated. A simple shifted
+ sinusoidal curve is used for each row.
+ </p>
+<pre class="code">
+<span class="c2h_reserved_word">protected</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">initGL</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+ <span class="c2h_reserved_word">super</span>.<span class="c2h_identifier">initGL</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">QUADRIC</span> <span class="c2h_symbol">=</span> <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluNewQuadric</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span>;
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glBlendFunc</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_SRC_ALPHA</span>, <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_ONE_MINUS_SRC_ALPHA</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glEnable</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_BLEND</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glEnable</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_LINE_SMOOTH</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluQuadricNormals</span><span class="c2h_braces">(</span><span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">QUADRIC</span>, <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">GLU_SMOOTH</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glLightfv</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_LIGHT1</span>,
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_DIFFUSE</span>,
+ <span class="c2h_reserved_word">new</span> <span class="c2h_reserved_word">float</span><span class="c2h_braces">[</span><span class="c2h_braces">]</span> <span class="c2h_braces">{</span><span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">1.0f</span>, <span class="c2h_numeric">1.0f</span><span class="c2h_braces">}</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glLightfv</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_LIGHT1</span>,
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_AMBIENT</span>,
+ <span class="c2h_reserved_word">new</span> <span class="c2h_reserved_word">float</span><span class="c2h_braces">[</span><span class="c2h_braces">]</span> <span class="c2h_braces">{</span><span class="c2h_numeric">0.5f</span>, <span class="c2h_numeric">0.5f</span>, <span class="c2h_numeric">0.5f</span>, <span class="c2h_numeric">1.0f</span><span class="c2h_braces">}</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glLightfv</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_LIGHT1</span>,
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_POSITION</span>,
+ <span class="c2h_reserved_word">new</span> <span class="c2h_reserved_word">float</span><span class="c2h_braces">[</span><span class="c2h_braces">]</span> <span class="c2h_braces">{</span><span class="c2h_symbol">-</span><span class="c2h_numeric">50.f</span>, <span class="c2h_numeric">50.0f</span>, <span class="c2h_numeric">100.0f</span>, <span class="c2h_numeric">1.0f</span><span class="c2h_braces">}</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glEnable</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_LIGHT1</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glEnable</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_LIGHTING</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glEnable</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_COLOR_MATERIAL</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glColorMaterial</span><span class="c2h_braces">(</span><span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_FRONT</span>, <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">GL_AMBIENT_AND_DIFFUSE</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">axis</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">new</span> <span class="c2h_identifier">Axis</span><span class="c2h_braces">(</span><span class="c2h_numeric">15.0f</span>, <span class="c2h_numeric">9.0f</span>, <span class="c2h_numeric">11.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">chart</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">new</span> <span class="c2h_identifier">BarValue</span><span class="c2h_braces">[</span><span class="c2h_identifier">CHART_COUNT</span><span class="c2h_braces">]</span><span class="c2h_braces">[</span><span class="c2h_identifier">ROW_LENGTH</span><span class="c2h_braces">]</span><span class="c2h_symbol">;</span>
+ <span class="c2h_reserved_word">double</span> <span class="c2h_identifier">slice</span> <span class="c2h_symbol">=</span> <span class="c2h_identifier">Math</span>.<span class="c2h_identifier">PI</span>/<span class="c2h_identifier">ROW_LENGTH</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_reserved_word">for</span> <span class="c2h_braces">(</span><span class="c2h_reserved_word">int</span> <span class="c2h_identifier">i</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">0</span><span class="c2h_symbol">;</span> <span class="c2h_identifier">i</span> <span class="c2h_symbol">&lt;</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">chart</span>.<span class="c2h_identifier">length</span><span class="c2h_symbol">;</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">+</span> <span class="c2h_identifier">i</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+ <span class="c2h_identifier">BarValue</span><span class="c2h_braces">[</span><span class="c2h_braces">]</span> <span class="c2h_identifier">value</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">chart</span><span class="c2h_braces">[</span><span class="c2h_identifier">i</span><span class="c2h_braces">]</span><span class="c2h_symbol">;</span>
+ <span class="c2h_reserved_word">double</span> <span class="c2h_identifier">shift</span> <span class="c2h_symbol">=</span> <span class="c2h_identifier">i</span><span class="c2h_symbol">*</span><span class="c2h_identifier">Math</span>.<span class="c2h_identifier">PI</span>/<span class="c2h_numeric">4.0</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_reserved_word">for</span> <span class="c2h_braces">(</span><span class="c2h_reserved_word">int</span> <span class="c2h_identifier">j</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">1</span><span class="c2h_symbol">;</span> <span class="c2h_identifier">j</span> <span class="c2h_symbol">&lt;</span><span class="c2h_symbol">=</span> <span class="c2h_identifier">value</span>.<span class="c2h_identifier">length</span><span class="c2h_symbol">;</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">+</span> <span class="c2h_identifier">j</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+ <span class="c2h_identifier">value</span><span class="c2h_braces">[</span><span class="c2h_identifier">j</span><span class="c2h_symbol">-</span><span class="c2h_numeric">1</span><span class="c2h_braces">]</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">new</span> <span class="c2h_identifier">BarValue</span><span class="c2h_braces">(</span><span class="c2h_braces">(</span><span class="c2h_reserved_word">float</span><span class="c2h_braces">)</span> <span class="c2h_braces">(</span><span class="c2h_numeric">8.0</span><span class="c2h_symbol">*</span><span class="c2h_identifier">Math</span>.<span class="c2h_identifier">abs</span><span class="c2h_braces">(</span><span class="c2h_identifier">Math</span>.<span class="c2h_identifier">sin</span><span class="c2h_braces">(</span><span class="c2h_identifier">slice</span><span class="c2h_symbol">*</span><span class="c2h_identifier">j</span> <span class="c2h_symbol">-</span> <span class="c2h_identifier">shift</span><span class="c2h_braces">)</span><span class="c2h_braces">)</span><span class="c2h_braces">)</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_braces">}</span>
+ <span class="c2h_braces">}</span>
+<span class="c2h_braces">}</span>
+</pre>
+
+ <p>
+ To render the chart we override the <code>drawScene</code> method.
+ This method first asks the scene grip to adjust the view point. Next,
+ the axes figure is drawn, followed by the bars. After each bar is drawn,
+ the coordinate system is moved to the right so that bars are
+ arranged in a row. After a complete row of bars is rendered, the
+ coordinate system is translated to the left and forward.
+ </p>
+ <p>
+ When using light sources it is customary to set up
+ material properties. These define how each component of light
+ is reflected by a given material, and whether the material is
+ shiny or dull. To simplify this procedure, the <code>initGL</code>
+ method sets up color tracking. This way, material properties are
+ automatically inferred from the current color. In order to make
+ cylinders translucent rather than opaque, we use the color command
+ that defines four rather than three parameters. The fourth parameter is the
+ alpha composite, which dictates the level of transparency. Objects that have
+ alpha set to <code>1.0f</code> are opaque, while objects with an alpha of <code>0.0f</code> are completely
+ transparent, and hence effectively invisible.
+ The program
+ uses alpha equal to <code>0.7f</code> to allow some but not all
+ light to pass through walls of cylinders.
+ </p>
+<pre class="code">
+<span class="c2h_reserved_word">protected</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">drawScene</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+ <span class="c2h_reserved_word">super</span>.<span class="c2h_identifier">drawScene</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">grip</span>.<span class="c2h_identifier">adjust</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glLineWidth</span><span class="c2h_braces">(</span><span class="c2h_numeric">1.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">axis</span>.<span class="c2h_identifier">draw</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glTranslatef</span><span class="c2h_braces">(</span><span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">RADIUS</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">RADIUS</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_reserved_word">for</span> <span class="c2h_braces">(</span><span class="c2h_reserved_word">int</span> <span class="c2h_identifier">i</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">0</span><span class="c2h_symbol">;</span> <span class="c2h_identifier">i</span> <span class="c2h_symbol">&lt;</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">chart</span>.<span class="c2h_identifier">length</span><span class="c2h_symbol">;</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">+</span> <span class="c2h_identifier">i</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+ <span class="c2h_identifier">BarValue</span><span class="c2h_braces">[</span><span class="c2h_braces">]</span> <span class="c2h_identifier">value</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">chart</span><span class="c2h_braces">[</span><span class="c2h_identifier">i</span><span class="c2h_braces">]</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glColor4fv</span><span class="c2h_braces">(</span><span class="c2h_identifier">COLOR</span><span class="c2h_braces">[</span><span class="c2h_identifier">i</span> <span class="c2h_symbol">%</span> <span class="c2h_identifier">COLOR</span>.<span class="c2h_identifier">length</span><span class="c2h_braces">]</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_reserved_word">for</span> <span class="c2h_braces">(</span><span class="c2h_reserved_word">int</span> <span class="c2h_identifier">j</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">0</span><span class="c2h_symbol">;</span> <span class="c2h_identifier">j</span> <span class="c2h_symbol">&lt;</span> <span class="c2h_identifier">value</span>.<span class="c2h_identifier">length</span><span class="c2h_symbol">;</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">+</span> <span class="c2h_identifier">j</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+ <span class="c2h_identifier">value</span><span class="c2h_braces">[</span><span class="c2h_identifier">j</span><span class="c2h_braces">]</span>.<span class="c2h_identifier">draw</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glTranslatef</span><span class="c2h_braces">(</span><span class="c2h_numeric">2.0f</span><span class="c2h_symbol">*</span><span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">RADIUS</span>, <span class="c2h_numeric">0.0f</span>, <span class="c2h_numeric">0.0f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_braces">}</span>
+
+ <span class="c2h_identifier">GL</span>.<span class="c2h_identifier">glTranslatef</span><span class="c2h_braces">(</span><span class="c2h_symbol">-</span><span class="c2h_numeric">2.0f</span><span class="c2h_symbol">*</span><span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">RADIUS</span><span class="c2h_symbol">*</span><span class="c2h_identifier">value</span>.<span class="c2h_identifier">length</span>,
+ <span class="c2h_numeric">0.0f</span>,
+ <span class="c2h_numeric">2.0f</span><span class="c2h_symbol">*</span><span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">RADIUS</span> <span class="c2h_symbol">+</span> <span class="c2h_numeric">0.5f</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_braces">}</span>
+<span class="c2h_braces">}</span>
+</pre>
+
+ <p>
+ The <code>dispose</code> method is used to free resources used by the
+ program. First, the quadric used by GLU to render cylinders and disks
+ is destroyed. Next, all display lists used by bars are freed, as well
+ as the list used to display the axes. Finally, the parent's <code>dispose</code>
+ method is called to dispose the context.
+ </p>
+<pre class="code">
+<span class="c2h_reserved_word">public</span> <span class="c2h_reserved_word">void</span> <span class="c2h_identifier">dispose</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+ <span class="c2h_identifier">GLU</span>.<span class="c2h_identifier">gluDeleteQuadric</span><span class="c2h_braces">(</span><span class="c2h_identifier">BarValue</span>.<span class="c2h_identifier">QUADRIC</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_reserved_word">for</span> <span class="c2h_braces">(</span><span class="c2h_reserved_word">int</span> <span class="c2h_identifier">i</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">0</span><span class="c2h_symbol">;</span> <span class="c2h_identifier">i</span> <span class="c2h_symbol">&lt;</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">chart</span>.<span class="c2h_identifier">length</span><span class="c2h_symbol">;</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">+</span> <span class="c2h_identifier">i</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+ <span class="c2h_identifier">BarValue</span><span class="c2h_braces">[</span><span class="c2h_braces">]</span> <span class="c2h_identifier">value</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">chart</span><span class="c2h_braces">[</span><span class="c2h_identifier">i</span><span class="c2h_braces">]</span><span class="c2h_symbol">;</span>
+
+ <span class="c2h_reserved_word">for</span> <span class="c2h_braces">(</span><span class="c2h_reserved_word">int</span> <span class="c2h_identifier">j</span> <span class="c2h_symbol">=</span> <span class="c2h_numeric">0</span><span class="c2h_symbol">;</span> <span class="c2h_identifier">j</span> <span class="c2h_symbol">&lt;</span> <span class="c2h_identifier">value</span>.<span class="c2h_identifier">length</span><span class="c2h_symbol">;</span> <span class="c2h_symbol">+</span><span class="c2h_symbol">+</span> <span class="c2h_identifier">j</span><span class="c2h_braces">)</span> <span class="c2h_braces">{</span>
+ <span class="c2h_identifier">value</span><span class="c2h_braces">[</span><span class="c2h_identifier">j</span><span class="c2h_braces">]</span>.<span class="c2h_identifier">dispose</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_identifier">value</span><span class="c2h_braces">[</span><span class="c2h_identifier">j</span><span class="c2h_braces">]</span> <span class="c2h_symbol">=</span> <span class="c2h_reserved_word">null</span><span class="c2h_symbol">;</span>
+ <span class="c2h_braces">}</span>
+ <span class="c2h_braces">}</span>
+
+ <span class="c2h_reserved_word">this</span>.<span class="c2h_identifier">axis</span>.<span class="c2h_identifier">dispose</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+ <span class="c2h_reserved_word">super</span>.<span class="c2h_identifier">dispose</span><span class="c2h_braces">(</span><span class="c2h_braces">)</span><span class="c2h_symbol">;</span>
+<span class="c2h_braces">}</span>
+</pre>
+
+ <p>
+ The end result is shown in Figure&nbsp;6. The view point can be moved
+ around and rotated using either the mouse left or right buttons or the
+ keyboard. Depending on the
+ angle from which the chart is inspected, one can observe different
+ interaction of the light source and objects in the scene. The color
+ blending creates the translucent appearance of cylinders.
+ </p>
+
+ <div class="figure">
+ <img src="images/3dchart4.png" width="500" height="366" border="0" alt="3D Chart">
+ <div class="figure-caption">
+ <span class="figure-number">Figure 6</span>. OpenGL 3D Chart
+ </div>
+ </div>
+
+ <p>
+ <img src="images/tryit.gif" alt="Try it!" width="61" height="13">
+ To run this article's demo plug-in in your workspace make sure you
+ have the correct
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/opengl/opengl.html">OpenGL</a>
+ plug-in installed. Download
+ <a href="lib/demo_plugin.zip">demo_plugin.zip</a> which contains an
+ Eclipse plug-in that defines a view that shows the OpenGL chart.
+ Unzip it to your Eclipse root directory; it should create the
+ <code>org.bluear.opengl_0.1.0</code> directory in Eclipse's plugins
+ folder. Start Eclipse with the <code>-clean</code> switch to ensure
+ that your newly-installed plug-in is detected. From the
+ <i>Show View</i> dialog, accessible under the <i>Windows</i> menu,
+ select the <i>OpenGL Chart</i> view listed in
+ the <i>OpenGL Examples</i> category.
+ In order to obtain access to the source code, import the plug-in
+ as the source project. The code also contains a stand alone version in the
+ form of an SWT program, with the entry point defined in the <code>Launcher</code>
+ class. To run it you need to set the <code>java.library.path</code>
+ variable with the path to both the SWT and OpenGL binary libraries.
+ </p>
+ <div class="figure">
+ <img src="images/workbench2.png" width="734" height="400" border="0" alt="Eclipse OpenGL view">
+ <div class="figure-caption" style="margin-top: 1ex;">
+ <span class="figure-number">Figure 7</span>. An Eclipse view using <code>GLScene</code>.
+ </div>
+ </div>
+
+
+ <h2>Conclusion</h2>
+
+ <p>
+ This article introduces and presents some of the functionality available
+ today in the OpenGL plug-in for SWT. While the subject of 3D and OpenGL
+ is too vast to be fully explored, I tried to give the reader a taste
+ of what can be achieved. Some of the components and techniques, such
+ as <code>GLScene</code> and <code>SceneGrip</code>, may be reused
+ in other 3D applications.
+ </p>
+ <p>
+ The plug-in is still considered experimental. For example, if you pass a
+ <code>null</code> array to some GL methods, rather than getting a possible to catch
+ <code>NullPointerException</code>, you end up with a JVM crash. These
+ and other issues must be addressed before the final release of the
+ plug-in.
+ </p>
+ <p>
+ OpenGL is not the only game in town; one could expect that a Windows-only
+ DirectX plug-in with similar capabilities could be developed. On
+ the other hand, OpenGL has the enormous benefit of being a platform-neutral
+ solution. The majority of the code for this article has been developed
+ under Linux and then tested, without any additional modifications,
+ under Windows. This fits well with the SWT philosophy of using native platform
+ capabilities but exposing them through platform-agnostic APIs. One
+ can only hope that the plug-in will continue to mature and be deployed
+ in other operating systems to which Eclipse has been ported.
+ </p>
+
+ <h3>Acknowledgments</h3>
+ <p>
+ I would like to thank Grant Gayed and Ed Burnette for their comments
+ that helped improve the structure and accuracy of this article. My
+ thanks also go to Jill Sueoka for tirelessly reviewing numerous
+ versions that I managed to produce.
+ </p>
+
+ <a name="bibliography"></a>
+ <h2>Bibliography</h2>
+
+ <table>
+ <tbody>
+ <tr>
+ <td valign="top"><a name="winchester"></a>[1]</td>
+ <td>
+ Joe Winchester,
+ <a href="http://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html"><i>Introduction
+ to SWT Graphics</i></a>,
+ Eclipse Corner Article, July 2003
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="saillet"></a>[2]</td>
+ <td>
+ Yannick Saillet,
+ <a href="http://www-106.ibm.com/developerworks/library/j-2dswt/?ca=dnt-522"><i>Java
+ 2D imaging for the Standard Widget Toolkit</i></a>,
+ IBM developerWorks, Jun 2004
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="opengl-pg"></a>[3]</td>
+ <td>
+ OpenGL Architecture Review Board, Dave Shreiner, Mason Woo, Jackie Neider,
+ Tom Davis,
+ <a href="http://fly.cc.fer.hr/~unreal/theredbook/"><i>OpenGL Programming
+ Guide</i></a>,
+ Addison-Wesley, November 14, 2003, ISBN 0321173481.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="opengl-pg"></a>[4]</td>
+ <td>
+ OpenGL Architecture Review Board, Dave Shreiner,
+ <a href="http://rush3d.com/reference/opengl-bluebook-1.0/"><i>OpenGL Reference
+ Manual</i></a>,
+ Addison-Wesley, March 16, 2004, ISBN 032117383X.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="computer-graphics"></a>[5]</td>
+ <td>
+ James D. Foley, Andries van Dam, Steven K. Feiner, John F. Hughes,
+ <a href="http://www.awprofessional.com/titles/0-201-84840-6"><i>Computer
+ Graphics: Principles and Practice in C</i></a>,
+ Addison-Wesley, August 4, 1995, ISBN 0201848406.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="opengl-machine"></a>[6]</td>
+ <td>
+ <a href="http://www.opengl.org/documentation/specs/version1.1/state.pdf"><i>The
+ OpenGL Machine</i></a>,
+ Silicon Graphics, Inc., 1996.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="opengl-spec"></a>[7]</td>
+ <td>
+ Mark Segal, Kurt Akeley,
+ <a href="http://www.opengl.org/documentation/specs/version1.1/glspec1.1/index.html"><i>The
+ OpenGL Graphics System: A Specification (Version 1.1)</i></a>,
+ Silicon Graphics, Inc., 1992-1997.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="opengl-superbible"></a>[8]</td>
+ <td>
+ Richard S Wright, Benjamin Lipchak,
+ <a href="http://www.starstonesoftware.com/OpenGL/"><i>OpenGL
+ SuperBible</i></a>,
+ Sams, 3rd edition, June 30, 2004, ISBN: 0672326019
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="opengl-glu"></a>[9]</td>
+ <td>
+ Norman Chin, Chris Frazier, Paul Ho, Zacheng Liu, Kevin P. Smith,
+ <a href="http://www.opengl.org/documentation/specs/glu/glu1_3.pdf"><i>OpenGL
+ Graphics System Utility Library</i></a>,
+ Editor Jon Leech, version 1.3, November 1998
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <p>
+ <small>Java and all Java-based trademarks and logos are trademarks or
+ registered trademarks of Sun Microsystems, Inc. in the United States,
+ other countries, or both.</small>
+ </p>
+</body>
+</html> \ No newline at end of file
diff --git a/Article-SWT-browser-widget/DocumentationViewer.java b/Article-SWT-browser-widget/DocumentationViewer.java
new file mode 100644
index 0000000..6b38360
--- /dev/null
+++ b/Article-SWT-browser-widget/DocumentationViewer.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *******************************************************************************/
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.browser.*;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import java.io.*;
+import java.net.*;
+
+public class DocumentationViewer {
+
+static Browser browser;
+static String[] urls;
+static String[] titles;
+static int index;
+
+public static void main(String argv[]) {
+ Display display = new Display();
+ final Shell shell = new Shell(display);
+ shell.setText("SWT Browser - Documentation Viewer");
+ shell.setLayout(new GridLayout());
+ Composite compTools = new Composite(shell, SWT.NONE);
+ GridData data = new GridData(GridData.FILL_HORIZONTAL);
+ compTools.setLayoutData(data);
+ compTools.setLayout(new GridLayout(2, false));
+ ToolBar tocBar = new ToolBar(compTools, SWT.NONE);
+ ToolItem openItem = new ToolItem(tocBar, SWT.PUSH);
+ openItem.setText("Browse");
+ ToolBar navBar = new ToolBar(compTools, SWT.NONE);
+ navBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_END));
+ final ToolItem back = new ToolItem(navBar, SWT.PUSH);
+ back.setText("Back");
+ back.setEnabled(false);
+ final ToolItem forward = new ToolItem(navBar, SWT.PUSH);
+ forward.setText("Forward");
+ forward.setEnabled(false);
+
+ Composite comp = new Composite(shell, SWT.NONE);
+ data = new GridData(GridData.FILL_BOTH);
+ comp.setLayoutData(data);
+ comp.setLayout(new FillLayout());
+ final SashForm form = new SashForm(comp, SWT.HORIZONTAL);
+ form.setLayout(new FillLayout());
+
+ final List list = new List(form, SWT.SINGLE);
+ try {
+ browser = new Browser(form, SWT.NONE);
+ } catch (SWTError e) {
+ MessageBox messageBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
+ messageBox.setMessage("Closing application. The Browser could not be initialized.");
+ messageBox.setText("Fatal error - application terminated");
+ messageBox.open();
+ System.exit(-1);
+ }
+ back.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ browser.back();
+ }
+ });
+ forward.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ browser.forward();
+ }
+ });
+ list.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event e) {
+ int index = list.getSelectionIndex();
+ browser.setUrl(urls[index]);
+ }
+ });
+ final LocationListener locationListener = new LocationListener() {
+ public void changed(LocationEvent event) {
+ Browser browser = (Browser)event.widget;
+ back.setEnabled(browser.isBackEnabled());
+ forward.setEnabled(browser.isForwardEnabled());
+ }
+ public void changing(LocationEvent event) {
+ }
+ };
+ /* Build a table of contents. Open each HTML file
+ * found in the given folder to retrieve their title.
+ */
+ final TitleListener tocTitleListener = new TitleListener() {
+ public void changed(TitleEvent event) {
+ titles[index] = event.title;
+ }
+ };
+ final ProgressListener tocProgressListener = new ProgressListener() {
+ public void changed(ProgressEvent event) {
+ }
+ public void completed(ProgressEvent event) {
+ Browser browser = (Browser)event.widget;
+ index++;
+ boolean tocCompleted = index >= titles.length;
+ if (tocCompleted) {
+ browser.dispose();
+ browser = new Browser(form, SWT.NONE);
+ DocumentationViewer.browser = browser;
+ form.layout(true);
+ browser.addLocationListener(locationListener);
+ list.removeAll();
+ for (int i = 0; i < titles.length; i++) list.add(titles[i]);
+ list.select(0);
+ browser.setUrl(urls[0]);
+ shell.setText("SWT Browser - Documentation Viewer");
+ return;
+ }
+ shell.setText("Building index "+index+"/"+urls.length);
+ browser.setUrl(urls[index]);
+ }
+ };
+ openItem.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event e) {
+ DirectoryDialog dialog = new DirectoryDialog(shell);
+ String folder = dialog.open();
+ if (folder == null) return;
+ File file = new File(folder);
+ File[] files = file.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".html") || name.endsWith(".htm");
+ }
+ });
+ if (files.length == 0) return;
+ urls = new String[files.length];
+ titles = new String[files.length];
+ index = 0;
+ for (int i = 0; i < files.length; i++) {
+ try {
+ String url = files[i].toURL().toString();
+ urls[i] = url;
+ } catch (MalformedURLException ex) {}
+ }
+ shell.setText("Building index");
+ browser.addTitleListener(tocTitleListener);
+ browser.addProgressListener(tocProgressListener);
+ if (urls.length > 0) browser.setUrl(urls[0]);
+ }
+ });
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) display.sleep();
+ }
+ display.dispose();
+}
+}
diff --git a/Article-SWT-browser-widget/about.xml b/Article-SWT-browser-widget/about.xml
new file mode 100644
index 0000000..42a4e50
--- /dev/null
+++ b/Article-SWT-browser-widget/about.xml
@@ -0,0 +1,15 @@
+<article link="browser.html">
+ <title>Viewing HTML pages with SWT Browser widget</title>
+ <date>August 26, 2004</date>
+ <category>rcp</category>
+ <category>swt</category>
+ <author>
+ <name>Christophe Cornu</name>
+ <company>IBM</company>
+ </author>
+ <description>
+ This article explains how to add HTML viewing capability to an
+ SWT application. The Browser widget provides an easy way to
+ integrate rich HTML content into your application.
+ </description>
+</article> \ No newline at end of file
diff --git a/Article-SWT-browser-widget/browser.html b/Article-SWT-browser-widget/browser.html
new file mode 100644
index 0000000..ca5ffde
--- /dev/null
+++ b/Article-SWT-browser-widget/browser.html
@@ -0,0 +1,191 @@
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<title>Viewing HTML pages with SWT Browser widget</title>
+<link rel="stylesheet" href="../default_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2004 International Business Machines Corp.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<h1 ALIGN="CENTER">Viewing HTML pages with SWT Browser widget</h1>
+<blockquote>
+<b>Summary</b>
+
+<br>
+ This article explains how to add HTML viewing capability to an SWT application. The Browser widget provides an easy way to integrate rich HTML content into your application.
+ <p><b> By Christophe Cornu, IBM OTI Labs </b> <br>
+ <font size="-1">August 26, 2004</font></p>
+</blockquote>
+
+<hr width="100%">
+<h2>Ubiquitous HTML </h2>
+<p>HTML has evolved considerably since 1990. Web designers and artists take advantage
+ of some of the sophisticated extensions supported by today's popular browsers.
+ Cascading Style Sheet (CSS) in particular is unleashing even further the flexibility
+ of HTML. User documentation and contextual help are prime candidates to leverage
+ the hyperlink navigation metaphor and rich HTML rendering. The SWT Browser widget
+ embeds a platform's popular HTML rendering engine: Internet Explorer on a Microsoft&reg; Windows&reg; platform,
+ Mozilla on Linux&reg;, Safari on the Mac. It provides the capability to integrate
+ HTML rendering into a Java&trade; application. This widget is part of SWT starting
+ with the 3.0 release.</p>
+<p>Let's get started. We will implement an application that lists all the HTML documents present in a folder selected by the user. Selecting an entry in this list will cause the document to be displayed in the Browser widget (Figure 1).</p>
+<h2>Sample application - HTML page viewer </h2>
+<p>The following sample HTML documentation viewer allows the user to select a topic from the table of content. The corresponding documentation is displayed.</p>
+<p align="center"><img src="images/help_browser.png" width="632" height="302"></p>
+<p align="center">Figure 1 - Documentation Browser sample application </p>
+<p align="left">The user selects the directory containing HTML documents by clicking the Browse button at the top. The list on the left is populated with the titles of the HTML documents. Clicking an item in the list displays the corresponding document in the Browser widget on the right.</p>
+<p align="left"> The first task is to create an instance of the Browser widget. </p>
+<h3>Instantiate a Browser widget </h3>
+<p>The Browser widget binds to a suitable native HTML rendering engine for the platform it is running on (Internet Explorer on Windows, Mozilla on Linux, Safari on the Mac; the <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/faq.html#browserplatforms">Eclipse SWT FAQ page</a> lists the prerequisites for running the Browser widget on a particular platform). The constructor of the Browser widget throws an <code>SWTError</code> if a suitable native HTML rendering engine is not available. An application could trap this exception and degrade gracefully by disabling features that require the Browser widget.</p>
+<pre> import org.eclipse.swt.browser.*;
+ ...
+ Browser browser;
+ try {
+ browser = new Browser(shell, SWT.NONE);
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> } catch (SWTError e) {
+ MessageBox messageBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
+ messageBox.setMessage(&quot;Browser cannot be initialized.&quot;);
+ messageBox.setText(&quot;Exit&quot;);
+ messageBox.open();
+ System.exit(-1);
+ }</pre>
+<p>In this snippet, the application detects if the constructor of the Browser widget throws an <code>SWTError</code><img src="images/tag_1.gif" height=13 width=24 align=CENTER> the first time it is instantiated. It warns the user the application cannot be initialized and exits. If no <code>SWTError</code> has been thrown, the Browser widget is ready to display HTML content. The next step is to set the content of the Browser every time an item is selected in the <code>List</code>. </p>
+<h3>Display an HTML document</h3>
+<p>The Browser displays the HTML document related to the entry the user selected in the <code>List</code>. The method <code>Browser.setUrl</code> is used to navigate to a specific URL. It takes a <code>java.lang.String</code> argument that defines the new URL to navigate to.</p>
+<pre> String[] urls;
+ int index;
+ Browser browser;
+ ...
+ List list = new List(parent, SWT.SIMPLE);
+ list.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event e) {
+ int index = list.getSelectionIndex();
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> browser.setUrl(urls[index]);
+ }
+ });</pre>
+<p><code>Browser.setUrl</code><img src="images/tag_1.gif" height=13 width=24 align=CENTER> posts a request to change the location. Location loading and the actual rendering (drawing) are handled asynchronously by the underlying native engine. An application registers specific Browser listeners to track - and act upon - the different stages of a request. </p>
+<p> <img src="images/tip.gif" width="62" height="13"> It is also possible to render HTML from an in-memory string with the method <code>Browser.setText</code>. <code>Browser.setText</code> takes a Java String containing HTML tags. The encoding is implicitly Unicode since a Java String is itself in Unicode. The example below does not specify the HTML meta tag charset as a result. </p>
+<pre>browser.setText(&quot;&lt;html&gt;&lt;body&gt;This is Unicode HTML content from memory&lt;/body&gt;&lt;/html&gt;); </pre>
+<p>The Browser widget provides listeners to monitor when a location is actually changed, when a page is completely loaded, and what title needs to be displayed for the current document. Before we take a deeper look at these listeners, we will explore the history navigation. </p>
+<h3>Add history navigation</h3>
+<p>The user can navigate back and forth between locations already visited. The user interface of the documentation viewer defines two buttons Back and Forward, for this purpose. The snippet below describes how to provide tool items to navigate the location history of the Browser.</p>
+<pre> final ToolItem back = new ToolItem(navBar, SWT.PUSH);
+ back.setText(&quot;back&quot;);
+ back.setEnabled(false);
+ final ToolItem forward = new ToolItem(navBar, SWT.PUSH);
+ forward.setText(&quot;forward&quot;);
+ forward.setEnabled(false);
+
+ back.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> browser.back();
+ }
+ });
+ forward.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> browser.forward();
+ }
+ });</pre>
+<p>
+The excerpt above creates two tool items. The Browser widget provides the methods <code>Browser.back</code><img src="images/tag_1.gif" height=13 width=24 align=CENTER> and <code>Browser.forward</code><img src="images/tag_2.gif" height=13 width=24 align=CENTER> to navigate, respectively, back and forward in its navigation history. Each tool item activates a back or forward method when it is selected by the user. Since there is no navigation history when the Browser is created, the two tool items are initially disabled. Their state is updated with the code below. </p>
+<pre> LocationListener locationListener = new LocationListener() {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> public void changed(LocationEvent event) {
+ Browser browser = (Browser)event.widget;
+ back.setEnabled(browser.isBackEnabled());
+ forward.setEnabled(browser.isForwardEnabled());
+ }
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> public void changing(LocationEvent event) {
+ }
+ };
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> browser.addLocationListener(locationListener);</pre>
+<p>When the Browser has navigated to a new location, the navigation history stores the previous location. The state of the back and forward buttons can change every time the Browser has moved to a different location. Tracking location changes is done by implementing the <code>org.eclipse.swt.browser.LocationListener</code> interface. The method <code>LocationListener.changed</code><img src="images/tag_1.gif" height=13 width=24 align=CENTER> is invoked by the Browser widget every time it has moved to a different location, such as when the user activates a hyperlink or when the application requests that the Browser navigate to a different location. The methods <code>Browser.isBackEnabled</code> and <code>Browser.isForwardEnabled</code> return the actual state of the navigation history. The <code>LocationListener</code> must be registered with the Browser<img src="images/tag_3.gif" height=13 width=24 align=CENTER>.</p>
+<p> <img src="images/tip.gif" width="62" height="13"> It is possible to filter and block a document that is about to be navigated to. <code>LocationListener</code> defines another method: <code>changing</code><img src="images/tag_2.gif" height=13 width=24 align=CENTER>. This notification is sent before the target location defined in the <code>LocationEvent</code> begins loading. The argument <code>LocationEvent</code> in the method <code>changing</code> contains a <code>doit</code> flag. Setting this flag to false prevents the <code>LocationEvent.location</code> target from being loaded.</p>
+<p>The navigation history is now taken care of. There is just one more piece left to implement in order to have a working HTML document viewer. The next section deals with the initialization of the table of contents used to access the actual documentation.
+</p>
+<h3>Build a table of contents </h3>
+<p>The table of contents provides entry points to major aspects of a document. It is often generated along with the documentation and stored in a variety of formats (XML, plain text, etc.). The following snippet generates a table of contents dynamically by storing the URL and the title of the HTML files found in a particular folder. This naive approach suits the needs of our simple HTML doc browser example. </p>
+<pre> static String[] urls;
+ static String[] titles;
+ static int index;
+ ...
+
+ TitleListener tocTitleListener = new TitleListener() {
+ public void changed(TitleEvent event) {
+ titles[index] = event.title;
+ }
+ };</pre>
+<p>The application implements a TitleListener to obtain the title of the document that is currently displayed by the Browser. This title corresponds to the string typically displayed in the decoration of a Browser application and is usually related to the title tag found in the HTML document. Certain Browser applications may send a default value before the title tag has been parsed, such as the filename, or fire a new title event every time the value of the title tag is modified, such as when a JavaScript is executed that changes the title node. Our sample application will store the value of the title as it was reported by the Browser when the document was completely loaded. The application implements a ProgressListener in order to be notified when the current document is completely loaded.</p>
+<pre> ProgressListener tocProgressListener = new ProgressListener() {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> public void changed(ProgressEvent event) {
+ }
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> public void completed(ProgressEvent event) {
+ Browser browser = (Browser)event.widget;
+ index++;
+ boolean tocCompleted = index &gt;= titles.length;
+ if (tocCompleted) {
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> browser.dispose();
+ ...
+ return;
+ }
+ shell.setText(&quot;Building index &quot;+index+&quot;/&quot;+urls.length);
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> browser.setUrl(urls[index]);
+ }
+ };</pre>
+<p>The <code>ProgressListener</code> provides two methods. The method <code>changed</code><img src="images/tag_1.gif" height=13 width=24 align=CENTER> is often called multiple times to report progress as the document and some of the content it references get loaded (images for example). It is meant to be used to animate the progress bar found in a browser application. The method <code>completed</code><img src="images/tag_2.gif" height=13 width=24 align=CENTER> is invoked when the current document has been completely loaded.</p>
+<p>The following sequence occurs when building the table of contents. The first document is loading. The title is retrieved through the <code>TitleListener</code> notification. When the document has been loaded<img src="images/tag_2.gif" height=13 width=24 align=CENTER>, it is time to move on to the next document with a call to <code>Browser.setUrl</code><img src="images/tag_4.gif" height=13 width=24 align=CENTER>. The table of content is completed when all documents have been loaded and their titles retrieved. The Browser is disposed<img src="images/tag_3.gif" height=13 width=24 align=CENTER>. The application can initialize the user interface displaying the table of contents and create the Browser to render the document selected by the user. </p>
+<p>Figure 1 shows an example using a <code>List</code> widget for the TOC on the left side, separated by a <code>Sash</code> from a Browser instance on the right. <br>
+ <br>
+ The <code>TitleListener</code> and <code>ProgressListener</code> still need to be registered. This is done after the user selects a folder containing HTML files as implemented in the code below. </p>
+<pre> DirectoryDialog dialog = new DirectoryDialog(shell);
+ String folder = dialog.open();
+ if (folder == null) return;
+ File file = new File(folder);
+ File[] files = file.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(&quot;.html&quot;);
+ }
+ });</pre>
+<p>The final touch: </p>
+<pre> urls = new String[files.length];
+ titles = new String[files.length];
+ index = 0;
+ for (int i = 0; i &lt; files.length; i++) {
+ try {
+<img src="images/tag_1.gif" height=13 width=24 align=CENTER> String url = files[i].toURL().toString();
+ urls[i] = url;
+ } catch (MalformedURLException ex) {}
+ }
+ shell.setText(&quot;Building index&quot;);
+<img src="images/tag_2.gif" height=13 width=24 align=CENTER> browser.addTitleListener(tocTitleListener);
+<img src="images/tag_3.gif" height=13 width=24 align=CENTER> browser.addProgressListener(tocProgressListener);
+<img src="images/tag_4.gif" height=13 width=24 align=CENTER> browser.setUrl(urls[0]);</pre>
+<p>Each <code>File</code> instance is converted into a <code>String</code> representing its URL<img src="images/tag_1.gif" height=13 width=24 align=CENTER>. The process of building the table of contents requires registering the <code>TitleListener</code> <img src="images/tag_2.gif" height=13 width=24 align=CENTER> and <code>ProgressListener</code> <img src="images/tag_3.gif" height=13 width=24 align=CENTER> implemented above. The first document is opened with the call <code>Browser.setUrl</code><img src="images/tag_4.gif" height=13 width=24 align=CENTER>.</p>
+<p>The full source code for DocumentationViewer.java is <a href="DocumentationViewer.java">here</a>. </p>
+<h2>Summary</h2>
+<p>Documentation and contextual help benefit from the powerful HTML capabilities of today's popular browsers such as Internet Explorer, Mozilla and Safari. The Browser widget allows you to leverage the latest HTML standards and to integrate rich HTML content into your application.</p>
+<h2>References</h2>
+<p><a href="http://www.w3.org/People/Berners-Lee/WorldWideWeb.html">The WorldWideWeb Browser - Tim Berners-Lee</a> Where it all started, not so long ago.</p>
+<p><a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/faq.html#whatisbrowser">SWT Browser FAQ</a> Platform requirements for the Browser widget. </p>
+<p><a href="http://www.eclipse.org/downloads/index.php">BrowserExample (included with the Eclipse Example Plug-ins)</a> An Eclipse plugin browser based on the Browser widget.</p>
+<p> <a href="news://news.eclipse.org/eclipse.platform.swt">news://news.eclipse.org/eclipse.platform.swt</a> The SWT newsgroup is a good place to ask and discuss about the Browser widget. </p>
+<p><a href="http://www.csszengarden.com/">Zen Garden - The Beauty of CSS Design</a> A visual proof of the extraordinary versatility of CSS - same HTML content rendered with different CSS scripts.</p>
+<h2>Acknowledgements</h2>
+<p> Thanks to John Arthorne from the Eclipse Platform Core team and Jim des Rivi&egrave;res at OTI Labs for proof reading and providing feedback for this article. </p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small><br>
+<small>Microsoft and Windows are trademarks of Microsoft Corporation in the United States, other countries, or both.</small><br>
+<small>Linux is a trademark of Linus Torvalds in the United States, other countries, or both.</small><br>
+<small>Other company, product, and service names may be trademarks or service marks of others.</small></p>
+</body>
+</html> \ No newline at end of file
diff --git a/Article-SWT-browser-widget/images/Idea.jpg b/Article-SWT-browser-widget/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-SWT-browser-widget/images/Idea.jpg
Binary files differ
diff --git a/Article-SWT-browser-widget/images/help_browser.png b/Article-SWT-browser-widget/images/help_browser.png
new file mode 100644
index 0000000..1c02eb7
--- /dev/null
+++ b/Article-SWT-browser-widget/images/help_browser.png
Binary files differ
diff --git a/Article-SWT-browser-widget/images/linux_only.gif b/Article-SWT-browser-widget/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-SWT-browser-widget/images/linux_only.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/tag_1.gif b/Article-SWT-browser-widget/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-SWT-browser-widget/images/tag_1.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/tag_2.gif b/Article-SWT-browser-widget/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-SWT-browser-widget/images/tag_2.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/tag_3.gif b/Article-SWT-browser-widget/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-SWT-browser-widget/images/tag_3.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/tag_4.gif b/Article-SWT-browser-widget/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-SWT-browser-widget/images/tag_4.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/tag_5.gif b/Article-SWT-browser-widget/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-SWT-browser-widget/images/tag_5.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/tag_6.gif b/Article-SWT-browser-widget/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-SWT-browser-widget/images/tag_6.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/tag_7.gif b/Article-SWT-browser-widget/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-SWT-browser-widget/images/tag_7.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/tip.gif b/Article-SWT-browser-widget/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-SWT-browser-widget/images/tip.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/tryit.gif b/Article-SWT-browser-widget/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-SWT-browser-widget/images/tryit.gif
Binary files differ
diff --git a/Article-SWT-browser-widget/images/win_only.gif b/Article-SWT-browser-widget/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-SWT-browser-widget/images/win_only.gif
Binary files differ
diff --git a/Article-SWT-graphics/SWT_graphics.html b/Article-SWT-graphics/SWT_graphics.html
new file mode 100644
index 0000000..88a830c
--- /dev/null
+++ b/Article-SWT-graphics/SWT_graphics.html
@@ -0,0 +1,629 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (Windows NT 5.0; U) [Netscape]">
+ <meta name="ProgId" content="FrontPage.Editor.Document">
+ <title>Introduction to SWT Graphics</title>
+<link
+href="../default_style.css"
+rel=stylesheet>
+</head>
+<body link="#0000FF" vlink="#800080">
+<div align="right"><font size="-2">Copyright &copy; 2003 International Business Machines
+ Corp.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></b></td>
+ </tr>
+ </table>
+</div>
+<h1> <img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+<center>
+ <h1> Graphics Context - Quick on the draw</h1>
+</center>
+<blockquote><b>Summary</b> <br>
+ The package <code>org.eclipse.swt.graphics</code> contains classes that allows
+ management of graphics resources. Graphics can be drawn on anything that implements
+ <code>org.eclipse.swt.graphics.Drawable, </code>which includes <code>org.eclipse.swt.widgets.Control</code>
+ and <code>org.eclipse.swt.graphics.Image</code>. The class <code>org.eclipse.swt.graphics.GC
+ </code>encapsulates all of the drawing API, including how to draw lines and
+ shapes, draw text and images and fill shapes. This article shows how to
+ use a GC to draw onto an Image, or onto a control through its paintEvent callback.
+ The Canvas control, specifically designed for drawing operations, has a number
+ of constructor style bits that allow you to determine when and how painting
+ occurs, and the article shows how to use these.
+ <p><b>By Joe Winchester, IBM</b> <br>
+ July 3, 2003</blockquote>
+<hr width="100%">
+<br>
+Table of contents:
+<ul>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Graphics Context">Graphics
+ Context</a></li>
+ <ul>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Graphics Context">Drawing
+ on an Image</a></li>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Graphics Context">Drawing
+ on a Control</a></li>
+ </ul>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Clipping">Clipping</a></li>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Canvas">Canvas</a></li>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Drawing lines and">Drawing
+ lines and shapes</a></li>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Drawing Text">Drawing
+ text</a></li>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Filling shapes">Filling
+ shapes</a></li>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#XOR">XOR</a></li>
+ <li> <a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Drawing Images">Drawing
+ images</a></li>
+</ul>
+The SWT graphics system uses the same coordinate convention used for controls,
+where the origin is at 0,0 is the top left corner, and the x axis increases to
+the right while the y axis increases downwards.&nbsp; The Point class is used
+to represent both a location (a position in the coordinate system) and also an
+offset (there is no Dimension class in SWT - the size of a rectangle is represented
+by a Point capturing the x and y offset from its origin).
+<h1> <a NAME="Graphics Context"></a>Graphics Context</h1>
+Graphics can be drawn on anything that implements <code>org.eclipse.swt.graphics.Drawable</code>.&nbsp;
+This includes a Control, an Image, a Display device or a Printer device.&nbsp;
+The class <code>org.eclipse.swt.graphics.GC</code> is a graphics context that encapsulates
+the drawing operations that can be performed.&nbsp; There are two common ways
+to use a GC; either by creating one using the Drawable instance as a constructor
+argument, or else using a GC that's given to you as part of a paintEvent callback.
+<h2> Drawing on an Image</h2>
+The code below creates a GC with an image as its argument and draws two lines
+on it,&nbsp;<img src="images/tag_1.gif" height=13 width=24> one from the top left (0,0)
+to the bottom right, and&nbsp;<img src="images/tag_2.gif" height=13 width=24> one from
+the top right to the bottom left.
+<p><code>&nbsp;&nbsp;&nbsp; Image image = new Image(display,"C:/devEclipse_02/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");</code>
+ <br>
+ <code>&nbsp;&nbsp;&nbsp; GC gc = new GC(image);</code> <br>
+ <code>&nbsp;&nbsp;&nbsp; Rectangle bounds = image.getBounds();</code> <br>
+ <img src="images/tag_1.gif" height=13 width=24><code> gc.drawLine(0,0,bounds.width,bounds.height);</code>
+ <br>
+ <img src="images/tag_2.gif" height=13 width=24><code> gc.drawLine(0,bounds.height,bounds.width,0);</code>
+ <br>
+ <img src="images/tag_3.gif" height=13 width=24><code> gc.dispose();</code> <br>
+ <code>&nbsp;&nbsp;&nbsp; image.dispose();</code> <br>
+ &nbsp;
+<table BORDER >
+ <caption>
+ <TBODY>
+ <br></TBODY>
+ </caption>
+ <tr>
+ <td>&nbsp;<i>Original image&nbsp;</i></td>
+ <td><i>Image after the GC draws across it</i></td>
+ </tr>
+ <tr>
+ <td><img src="images/image_lg_orig.gif" height=164 width=115></td>
+ <td><img src="images/image_lg_lines.gif" height=164 width=115></td>
+ </tr>
+</table>
+<p>When creating a GC you must be responsible for disposing it&nbsp;<img src="images/tag_3.gif" height=13 width=24>
+ by calling its dispose() method. For more information on how to manage SWT resources
+ see <a href="http://www.eclipse.org/articles/swt-design-2/swt-design-2.html">SWT:
+ The Standard Widget Toolkit.</a>&nbsp; A GC that's instantiated by the program
+ should be drawn upon and then disposed as soon as possible.&nbsp; This is because
+ each GC requires an underlying platform resource, and on some operating systems
+ these may be scarce, such as Windows 98 that only allows 5 GC objects to be
+ created before it runs out resources.
+<h2> Drawing on a Control</h2>
+The class <code>org.eclipse.swt.widgets.Control</code> is a Drawable, so you could
+draw onto a Control the same way you draw onto an Image (passing the Control as
+the argument of GC to draw onto it), however unlike drawing on an image (that
+permanently changes the data making up the graphic), if you use a GC to draw onto
+a control you must be aware that when the operating system itself draws the control
+it will overwrite your changes.&nbsp; The correct way to draw onto a control is
+by adding a listener to its paint event.&nbsp; The listener class is <code>org.eclipse.swt.events.PaintListener</code>,
+and the callback method argument is an instance of <code>org.eclipse.swt.events.PaintEvent</code>.&nbsp;
+The PaintEvent includes a GC that you can send message to, that is already prepared
+to draw onto the control and includes the damaged area.
+<p>The following code&nbsp;<img src="images/tag_1.gif" height=13 width=24> adds a paint
+ listener to a Shell, and in the paintControl callback method&nbsp;<img src="images/tag_2.gif" height=13 width=24>
+ draws a line from the origin to bottom right corner.
+<p><code>&nbsp;&nbsp;&nbsp; Shell shell = new Shell(display);</code> <br>
+ <img src="images/tag_1.gif" height=13 width=24><code> shell.addPaintListener(new PaintListener(){</code>
+ <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void paintControl(PaintEvent
+ e){</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Rectangle
+ clientArea = shell.getClientArea();</code> <br>
+ <img src="images/tag_2.gif" height=13 width=24><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ e.gc.drawLine(0,0,clientArea.width,clientArea.height);</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</code> <br>
+ <code>&nbsp;&nbsp;&nbsp; });</code> <br>
+ <code>&nbsp;&nbsp;&nbsp; shell.setSize(150,150)</code>
+<p><img src="images/ShellDrawnLine.gif" height=215 width=267>
+<p>Although the size of the Shell is set to (150,150), the area that can be drawn
+ onto is smaller.&nbsp; This is known as the client area, and takes into account
+ any trim or borders; for a Shell this includes its edges, titlebar and menubar.&nbsp;
+ To determine the clientArea of any Composite use the method <code>getClientArea().</code>
+<p>The application always get a paint event after the underlying OS has drawn
+ the control, so any drawing done to the paint event's GC will be shown on top
+ of the control.&nbsp; There are some exceptions to this, such as for a ToolBar
+ where on certain platforms the items are heavyweight controls that can't be
+ drawn on top of, however this is not considered normal behavior.&nbsp; For general-purpose
+ drawing the control <code><a href="http://eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html#Canvas">org.eclipse.swt.widgets.Canvas</a></code>
+ can be used that is optimized for graphics operations.
+<h1> <a NAME="Clipping"></a>Clipping</h1>
+The clipping area of a GC is the portion onto which visible drawing occurs. By
+default a GC is clipped to the bounds of the drawable that it was constructed
+with. Altering the clipping area of a GC allows you to create graphic effects.&nbsp;
+An example of this is if you wanted to fill a triangle shape that had a portion
+of its edges missing.&nbsp; One way to do this would be to draw multiple polygons
+rectangles making up the shape, another way however is to fill the shape, but
+to clip the GC so that the edges are outside the clipping area.
+<p><code>&nbsp;&nbsp;&nbsp; shell.addPaintListener(new PaintListener() {</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void paintControl(PaintEvent
+ e) {</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Rectangle
+ clientArea = shell.getClientArea();</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int width
+ = clientArea.width;</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int height
+ = clientArea.height;</code> <br>
+ <img src="images/tag_2.gif" height=13 width=24><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ e.gc.setClipping(20,20,width - 40, height - 40);</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN));</code>
+ <br>
+ <img src="images/tag_1.gif" height=13 width=24><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ e.gc.fillPolygon(new int[] {0,0,width,0,width/2,height});</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</code> <br>
+ <code>&nbsp;&nbsp;&nbsp; });</code>
+<p>This code draws a triangle on a Shell as a polygon from&nbsp; the&nbsp;<img src="images/tag_1.gif" height=13 width=24>
+ top left, top right, and center of the bottom edge. Beforehand however, the
+ GC is clipped with a rectangle&nbsp;<img src="images/tag_2.gif" height=13 width=24>
+ that reduces the client area with a margin of 20 pixels wide, so only the clipped
+ rectangle is draw.
+<p><img src="images/ClippedTriangles.gif" height=191 width=562>
+<p>When a paintEvent occurs for a control the GC is always clipped to just the
+ area that needs repainting. For example, if another window is moved in front
+ of an SWT shell and then moved away, the newly revealed portion of the GUI is
+ marked as damaged and a paint event is queued.&nbsp; When the paint event occurs,
+ the <code>paintControl(PaintEvent evt)</code> method argument contains the area
+ of the Control that requires redrawing in its x, y, width and height fields.&nbsp;
+ The damage to the control can be complex containing multiple disjoint rectangles,
+ and if there is more than one damaged area of a control when the paint event
+ occurs the damaged areas are merged into a single rectangle representing the
+ union of the damaged areas. This step is performed by the underlying platform
+ and is designed to aid performance as multiple paint events are processed in
+ a single callback.
+<p>In the example above that fills a clipped triangle&nbsp; each time the <code>paintControl(PaintEvent)</code>
+ method is called, an optimization could be to look at the PaintEvent's area.&nbsp;
+ It maybe that the paint event doesn't even intersect the shape being drawn in
+ which case no drawing need occur, or if only a portion of the drawing is needs
+ repainting then only this is drawn.&nbsp; Depending on the type of drawing,
+ working out which portion of a GC to selectively redraw however can be more
+ expensive than just relying on the fact the GC is clipped, and in practice code
+ inside paint events often just ignores the damaged area and re-does all of the
+ GC drawing, relying on clipping to ensure only the damaged area is refreshed.
+<p>If a program needs to manually damage an area of a control this can be done
+ using <code>Control.redraw(int x, int y, int width, int height)</code>, or <code>Control.redraw()</code>
+ to damage the entire client area.&nbsp; The area is marked as damaged and will
+ be included in the next paint event that occurs.&nbsp; To cause a synchronous
+ and immediate paint event to occur use the method <code>Control.update()</code>
+ that will force all outstanding paint requests to be processed for the control.
+ If there are no paint request&nbsp; (i.e. none of the client area is damaged),
+ then <code>update()</code> will do nothing.
+<h1> <a NAME="Canvas"></a>Canvas</h1>
+Although any Control can be drawn onto through its paintEvent, the subclass org.eclipse.swt.widgets.<code>Canvas</code>
+is specifically designed for graphics operations. This can be done either by using
+a Canvas and adding a paint listener, or through subclassing to create a re-usable
+Custom Control.&nbsp; Canvas has a number of style bits that can be used to affect
+how painting occurs.
+<p>The default behavior for a Canvas is that before it paints itself the entire
+ client area is filled with the current background color.&nbsp; This can create
+ screen flicker, because if the paintEvent also draws onto the GC, then the user
+ sees a flash between the original background being filled, and the drawing occurring.&nbsp;
+ One way to avoid this is to use the style bit SWT.NO_BACKGROUND when creating
+ the Canvas.&nbsp; This prevents the native background from being drawn, however
+ it means the program must be responsible for drawing every pixel of the client
+ area.
+<p>When a widget is resized a paint event occurs.&nbsp; This can create screen
+ flicker as repeated repainting of the client area occurs.&nbsp; Flicker is also
+ known as flash, and the style bit SWT.NO_REDRAW_RESIZE can be used to reduce
+ this.&nbsp; When NO_REDRAW_RESIZE is used and the control's size is reduced
+ no paint event is generated.&nbsp; This means there will be no flash as the
+ control is not unnecessarily redrawn, and if the size is increased then the
+ paint event's GC is clipped set to just the area that needs repainting.&nbsp;
+ This is the newly revealed bottom and right edge rectangles in a shape like
+ a backwards L.
+<p>The style bit NO-REDRAW_RESIZE works well to reduce flicker if a fixed-size
+ drawing is being done on the GC, and each newly exposed area generates a paint
+ event onto which a fresh piece of the drawing occurs.&nbsp; Incorrectly used
+ however, NO_REDRAW_RESIZE can lead to a graphic effect known as cheese.&nbsp;
+ Cheese is a general term that applies when a portion of a widget is not updated
+ correctly following a resize. An example of&nbsp; is shown below where the paint
+ event needs to update the entire client area, such as&nbsp;<img src="images/tag_1.gif" height=13 width=24>
+ fill it with an oval shape.&nbsp; Because no paint event occurs when the window
+ is reduced in size the shape is not redrawn when the size is decreased, and
+ when the window is made larger because the GC is clipped to just the damaged
+ area Cheese occurs in the newly expanded area because the previous drawing is
+ not erased ( as the paint event is clipped to only the newly exposed area ).
+<p><code>&nbsp;&nbsp;&nbsp; shell.setLayout(new FillLayout());</code> <br>
+ <img src="images/tag_2.gif" height=13 width=24><code> final Canvas canvas = new Canvas(shell,SWT.NO_REDRAW_RESIZE);</code>
+<p><code>&nbsp;&nbsp;&nbsp; canvas.addPaintListener(new PaintListener() {</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void paintControl(PaintEvent
+ e) {</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Rectangle
+ clientArea = canvas.getClientArea();</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN));</code>
+ <br>
+ <img src="images/tag_1.gif" height=13 width=24><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ e.gc.fillOval(0,0,clientArea.width,clientArea.height);</code> <br>
+ <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</code> <br>
+ <code>&nbsp;&nbsp;&nbsp; });</code>
+<p>When the canvas size is increased the GC is clipped to just the area that needs
+ repainting and cheese occurs.
+<p><img src="images/Cheese_Complete.gif">
+<p>To correct this problem in line&nbsp;<img src="images/tag_2.gif" height=13 width=24>
+ the style bit of SWT.NONE should be used so that the GC is not clipped on expansion,
+ and a paint event occurs even when the shell size is reduced so the full oval
+ can be repainted.
+<p><img src="images/tag_2.gif" height=13 width=24><code> final Canvas canvas = new Canvas(shell,SWT.NONE);</code>
+<p>For any SWT widget, if more than one rectangle is damaged then the platform
+ merges these into a single damaged area that is the union of all damaged rectangles
+ so the SWT program only processes a single paint event. The style bit NO_MERGE_PAINTS
+ on Canvas can be used to override this behavior which means the listener will
+ be called with a single paint event for every separate damaged rectangle.
+<p>The style bits NO_BACKGROUND, NO_REDRAW_RESIZE and NO_MERGE_PAINTS can be used
+ with any Composite or subclass, including Canvas, Shell, or Group.&nbsp; Although
+ this is allowed by SWT ( no exceptions will be thrown ) the Composite class's
+ Javadoc includes the following style bit warning <i>"... their behavior is undefined
+ if they are used with subclasses of <code>Composite</code> other than <code>Canvas</code>".&nbsp;
+ </i>The Canvas class is therefore the preferred control to use when performing
+ arbitrary drawing operations.
+<p>Another way to reduce flicker is to batch up the drawing that occurs on the
+ display by double buffering.&nbsp; Double buffering is a technique where the
+ drawing occurs onto a GC that is not the one used on the paintEvent, and the
+ contents are then copied across. To do this you can create an Image with the
+ same size as the Canvas' client area and then draw onto this with a <code>GC(Image)</code>;&nbsp;
+ The final image is then transferred across to the paint event's GC with a single
+ <code>drawImage(Image image, int x, int y) </code>method call.&nbsp; When using
+ this technique be aware that some platforms perform native double buffering
+ for you already, so you may in fact be triple buffering.
+<h1> <a NAME="Drawing lines and"></a>Drawing lines and shapes</h1>
+A GC has a number of methods that allow lines to be drawn on it, either between
+two points, a series of interconnected points, or a pre-defined shape.&nbsp; Lines
+are drawn in the foreground color of the GC and can be drawn in a number of styles
+and with different thickeness.&nbsp; For a paint event the GC has the same attributes
+as the control that fired the event (foreground / background color and font),
+and the default line style is solid with a width of 1 pixel.
+<h2> <code>GC.drawLine(int x1, int y1, int x2, int y2);</code></h2>
+Draw a line between two points on the drawable surface beginning at x1,y1 and
+ending at x2,y2.&nbsp; The end points are included in the line, and if they are
+the same then a single pixel dot will be drawn.
+<h2> <code>GC.drawPolyline(int[] pointArray);</code></h2>
+Draw a series of interconnecting lines with the int[] representing x and y positions
+for consecutive points.&nbsp; The statement: <br>
+<code>gc.drawPolyline(new int[] { 25,5,45,45,5,45 });</code> <br>
+draws a line from 25,5 to 45,45 and then from 45,45 onto 5,45.
+<p><img src="images/PolygonClient.gif" height=94 width=161>
+<h2> <code>GC.drawPolygon(int[] pointArray);</code></h2>
+Similar to <code>drawPolyline(int[])</code> except that the last point is joined to
+the first <br>
+<code>gc.drawPolygon(new int[] { 25,5,45,45,5,45 });</code> <br>
+This draws the three corners of the triangle and, by joining the point at 5,45
+with 25,5 completes the shape by creating a contained area <br>
+<img src="images/PolygonClient.gif" height=94 width=161>
+<h2> <code>GC.drawRectangle(int x, int y, int width, int height);</code></h2>
+Draw a rectangle with the top left corner at x,y with the specified with and height
+<br>
+<code>gc.drawRectangle(5,5,90,45);</code> <br>
+draws a rectangle with one corner at 5,5 and the opposite corner at 95,50; <br>
+<img src="images/RectangleClient.gif" height=97 width=174>
+<p>When a rectangle is drawn the bottom and right edges are drawn and it is conceptually
+ similar to lines being drawn between its four corners.&nbsp; As well as passing
+ the x,y,width and height as individual arguments the method is overloaded so
+ you can pass in the entire Rectangle - <code>GC.drawRectangle(Rectangle);</code>
+<h2> <code>GC.drawRoundedRectangle(int x, int y, int width, int height, int arcWidth,
+ int arcHeight);</code></h2>
+A rounded rectangle differs from a standard rectangle in that its corners are
+rounded.&nbsp; The rounding on each corner can be thought of as 1/4 of an oval,
+and the arcWidth and arcHeight specify the width and height of the full oval.
+<br>
+<code>gc.drawRoundedRectangle(5,5,90,45,25,15); </code>draws a rounded rectangle with
+a top left corner of 5,5.&nbsp; The figure below shows a zoomed picture of the
+bottom right corner together with an imaginary oval shown with a width of 25 and
+a height of 15 to show how the rounded corner is created from 1/4 of the oval.
+<p><img src="images/RoundedRectangleClient.gif" height=121 width=449>
+<p>The implementation of the rounded rectangle could be achieved with 4 calls
+ to <code>drawArc() </code>and 4 to <code>drawLine(). </code>However on some platforms
+ such as Windows or Photon there is an optimized platform API that SWT uses.
+<h2> <code>GC.drawOval(int x, int y, int width, int height);</code></h2>
+An oval is draw within the rectangle defined by its top left corner (x,y) and
+its width and height.&nbsp; To draw a circle set the width and height to be the
+same value. <br>
+<code>gc.drawOval(5,5,90,45);</code>
+<p><img src="images/OvalClient.gif" height=95 width=188>
+<h2> <code>GC.drawArc(int x, int y, int width, int height, int startAngle, int endAngle);</code></h2>
+An arc is drawn within the area bounded by the rectangle whose top left corner
+is x,y and has the specified width and height.&nbsp; The startAngle is on the
+horizontal x axis, so 0 degrees does not represent North but instead can be thought
+of as pointing East.&nbsp; The arc is drawn anticlockwise for the number of degrees
+specified by the endAngle <br>
+<code>gc.drawArc(5,5,90,45,90,200);</code> <br>
+This draws an arc beginning at 90 degrees, which is vertical ( 0 degrees being
+horizontal ), and the arc continues for 200 degrees.&nbsp; The arc does not stop
+when it reaches the endAngle of 200 degrees relative to the 0 axis, rather it
+stops when it has traversed 200 degrees relative to its starting position.
+<p><img src="images/ArcClient.gif" height=87 width=161>
+<h2> <code>GC.setLineStyle(int style);</code></h2>
+Lines can be drawn in a number of styles that are defined as static constants
+on the class <code>org.eclipse.swt.SWT </code>beginning LINE_. <br>
+&nbsp;
+<table BORDER >
+ <caption>
+ <TBODY>
+ <br></TBODY>
+ </caption>
+ <tr>
+ <td>SWT.LINE_SOLID</td>
+ <td><img src="images/Line_SOLID.gif" height=16 width=292></td>
+ </tr>
+ <tr>
+ <td>SWT.LINE_DOT</td>
+ <td><img src="images/LINE_DOT.gif" height=16 width=292></td>
+ </tr>
+ <tr>
+ <td>SWT.LINE_DASH</td>
+ <td><img src="images/LINE_DASH.gif" height=16 width=292></td>
+ </tr>
+ <tr>
+ <td>SWT.LINE_DASHDOT</td>
+ <td><img src="images/LINE_DASHDOT.gif" height=16 width=292></td>
+ </tr>
+ <tr>
+ <td>SWT.LINE_DASHDOTDOT</td>
+ <td><img src="images/LINE_DASHDOTDOT.gif" height=16 width=292></td>
+ </tr>
+</table>
+<h2> <code>GC.setLineWidth(int width);</code></h2>
+The default width for a line is 1 pixel, however this can be changed by setting
+the lineWidth of the GC. <br>
+&nbsp;
+<table BORDER >
+ <caption>
+ <TBODY>
+ <br></TBODY>
+ </caption>
+ <tr>
+ <td>gc.setLineWidth(2);</td>
+ <td><img src="images/Width_2.gif" height=16 width=292></td>
+ </tr>
+ <tr>
+ <td>gc.setLineWidth(4);</td>
+ <td><img src="images/Width_4.gif" height=16 width=292></td>
+ </tr>
+</table>
+<p>Because line styles and width affect all of the draw operations, allowing you
+ to achieve effects such as a dotted rectangle or an oval with a thick line.
+<p><code>gc.setLineWidth(3);</code> <br>
+ <code>gc.drawOval(5,5,40,40);</code> <br>
+ <code>gc.setLineWidth(1);</code> <br>
+ <code>gc.setLineStyle(SWT.LINE_DOT);</code> <br>
+ <code>gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));</code> <br>
+ <code>gc.drawRectangle(60,5,60,40);</code>
+<p><img src="images/LineShapes.gif" height=91 width=172> <br>
+ When a property such as a line width, line style or color is changed on a GC
+ this affects all subsequent drawing operations.&nbsp; The code snippet above
+ changes the width to 3 to draw the oval, but it then changes it back to 1 before
+ drawing the dotted blue rectangle.&nbsp; Forgetting to revert values in a GC
+ after modifying them is a common bug when doing SWT graphics programming.
+<h1> <a NAME="Drawing Text"></a>Drawing text</h1>
+Text can be drawn onto a GC, the glyphs are drawn in the GC's foreground color
+and font, and the area it occupies is drawn with the GC's background color.&nbsp;
+To draw text you define its top left corner, width and height.&nbsp; There are
+two sets of methods to draw text, the first set of which have <b><code>Text</code></b>
+in their method name, and will handle line delimiters and tabs and are used to
+implement an emulated Label. The second set of API methods have <b><code>String</code></b>
+in their method name, and no tab expansion or carriage return processing occurs,
+and are used for more sophisticated controls like the <code>StyledText </code>used
+by the Eclipse Java editor.
+<h2> <code>GC.drawText(String text, int x, int y);</code></h2>
+<code>Font font = new Font(display,"Arial",14,SWT.BOLD | SWT.ITALIC);</code> <br>
+<code>// ...</code> <br>
+<code>gc.drawText("Hello World",5,5);</code> <br>
+<code>gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));</code> <br>
+<code>gc.setFont(font);</code> <br>
+<code>gc.drawText("Hello\tThere\nWide\tWorld",5,25);</code> <br>
+<code>// ...</code> <br>
+<code>font.dispose();</code>
+<p><img src="images/TextHelloWorld.gif" height=108 width=200>
+<p>The drawText API processes the control characters \t as tab \n as a carriage
+ return.
+<h2> <code>GC.drawString(String text, int x, int y);</code></h2>
+<code>Font font = new Font(display,"Arial",14,SWT.BOLD | SWT.ITALIC);</code> <br>
+<code>// ...</code> <br>
+<code>gc.drawString("Hello World",5,5);</code> <br>
+<code>gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));</code> <br>
+<code>gc.setFont(font);</code> <br>
+<code>gc.drawString("Hello\tThere\nWide\tWorld",5,25);</code> <br>
+<code>// ...</code> <br>
+<code>font.dispose()</code>
+<p><img src="images/StringHelloWorld.gif" height=106 width=304> <br>
+ When drawString is used, the tab and carriage return characters are not processed
+<p>The size that a String occupies when it is drawn onto a GC is based on its
+ contents and the font of the GC.&nbsp; To determine the area that a String will
+ occupy when it is drawn use the methods <code>GC.stringExtent(String text), </code>or<code>
+ GC.textExtent(String text). </code>These return a Point whose x and y are the
+ width and height required to render the String argument.
+<h2> <code>GC.drawText(String text, int x, int y, boolean isTransparent);</code></h2>
+When drawText(String text, int x, int y) is used the text is drawn in the GC's
+current foreground color.&nbsp; If you are drawing on top of an area where you
+want the existing background to show through, then you can set the isTransparent
+argument to true.&nbsp; This is useful if you are drawing on top of an image and
+you don't want the text to obscure the image's background.
+<p><code>Font font = new Font(display,"Arial",12,SWT.BOLD | SWT.ITALIC);</code> <br>
+ <code>Image image = new Image(display,"C:/devEclipse_02/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");</code>
+ <br>
+ <code>GC gc = new GC(image);</code> <br>
+ <code>gc.drawText("Hello World",5,5);</code> <br>
+ <code>gc.setFont(font);</code> <br>
+ <code>gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));</code> <br>
+ <code>gc.drawText("Hello World",5,25,true);</code> <br>
+ <code>gc.dispose();</code> <br>
+ <code>image.dispose();</code> <br>
+ <code>font.dispose();</code>
+<p><img src="images/TextHelloWorldTransparent.gif" height=182 width=159> <br>
+ &nbsp;
+<h2> <code>GC.drawText(String text, int x, int y, int flags);</code></h2>
+The flags are a bitmask of the constants SWT.DRAW_DELIMITER, SWT.DRAW_TAB, SWT.DRAW_TRANSPARENT
+and SWT.DRAW_MNEMONIC.&nbsp; These determine whether or not \n is processed as
+a carriage return, \t as a tab expansion, whether background transparency is used,
+and whether &amp; is processed as a mnemonic or a literal.
+<p><code>gc.drawImage(image,0,0);</code> <br>
+ <code>gc.drawText("Hello\t&amp;There\nWide\tWorld",5,5,SWT.DRAW_TRANSPARENT);</code>
+ <br>
+ <code>gc.drawText("Hello\t&amp;There\nWide\tWorld",5,25,SWT.DRAW_DELIMITER | SWT.DRAW_TAB
+ | SWT.DRAW_MNEMONIC );</code>
+<p><img src="images/TextFlags.gif" height=166 width=192> <br>
+ &nbsp; <br>
+ &nbsp;
+<h1> <a NAME="Filling shapes"></a>Filling shapes</h1>
+Whereas lines are drawn in the GC's foreground color, shapes are filled with the
+GC's background color.
+<h2> <code>GC.fillPolygon(int[]);</code></h2>
+<code>gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));</code> <br>
+<code>gc.fillPolygon(new int[] { 25,5,45,45,5,45 })</code> <br>
+<img src="images/PolygonFillClient.gif" height=96 width=164>
+<h2> <code>GC.fillRectangle(int x, int y, int width, int height);</code></h2>
+<code>gc.fillRectangle(5,5,90,45);</code>
+<p><img src="images/RectangleFillClient.gif" height=98 width=165>
+<p>When a rectangle is filled, the bottom and right edges are not included.&nbsp;
+ With the code above the origin point 5,5 is included in the filled blue rectangle,
+ however the argument rectangle's bottom right corner of 95,50 (5+90 , 45+5)
+ is outside the filled area.&nbsp; The bottom right corner of the filled rectangle
+ is at 94,49.&nbsp; This is unlike the behavior for <code>drawRectangle(5,5,90,45)</code>,
+ where the full shape is outlined so the bottom right corner is 95,50.
+<p>To illustrate this, the code below strokes a rectangle whose corners are 5,5
+ and 90,45 before filling it in cyan.&nbsp; To ensure that the filling of the
+ rectangle doesn't overwrite its drawn outline, the origin is offset to 6,6.&nbsp;
+ This moves the bottom right corner of the filled rectangle, however because
+ it has already excluded the bottom and right edges it only needs to be inset
+ by one to not overlap with the drawn rectangle.
+<p><code>gc.drawRectangle(5,5,90,45);</code> <br>
+ <code>gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN));</code> <br>
+ <code>gc.fillRectangle(6,6,89,44);</code>
+<p><img src="images/RectangleStrokeFill.gif" height=111 width=195>
+<h2> <code>GC.fillRoundedRectangle(int x, int y, int width, int height, int arcWidth,
+ int arcHeight);</code></h2>
+<code>gc.fillRoundRectangle(5,5,90,45,25,15);</code>
+<p><img src="images/RoundedRectangleFilledClient.gif" height=95 width=166>
+<p>Like the <code>GC.fillRectangle(...) </code>method, the bottom and right edges
+ are excluded from the filled shape so the bottom right corner becomes 94,49
+ rather than 95,50.
+<h2> <code>GC.fillOval(int x, int y, int width, int height);</code></h2>
+<code>gc.fillOval(5,5,90,45);</code>
+<p><img src="images/OvalFilledClient.gif" height=93 width=167 align=ABSBOTTOM>
+<p>Like the other fill APIs, the bounding rectangle's bottom right corner is inset
+ by one.
+<h2> <code>GC.fillArc(int x, int y, int widt4h., int height, int startAngle, int
+ endAngle);</code></h2>
+<code>gc.fillArc(5,5,90,45,90,200);</code> <br>
+<img src="images/ArcFilledClient.gif" height=97 width=196> <br>
+The arguments to the <code>fillArc(...)</code> method are similar to the <code>drawArc(...)</code>,
+with the offset from an East axis to begin filling and the number of degrees to
+continue the arc in an anti-clockwise direction. However unlike the <code>drawArc(...)</code>
+whose bottom right corner of the bounding rectangle is the origin offset by the
+width and height, <code>fillArc(...)</code> follows the same pattern used by the other
+fill methods where the bottom and right edge are excluded and the corner inset
+by one.
+<h2> <code>GC.fillGradientRectangle(int x, int y, int width. int height, vertical
+ boolean);</code></h2>
+This allows a rectangle to be filled with a gradient of coloring between the GC's
+foreground and background color.&nbsp; The gradient can either be horizontal or
+vertical
+<p><code>gc.setBackgrouind(display,getSystemColor(SWT.COLOR_BLUE));</code> <br>
+ <code>gc.fillGradientRectangle(5,5,90,45,false);</code>
+<p>This creates a horizontal gradient fill starting with the foreground color
+ (black) on the left, and finishing with the background color (blue) on the right.&nbsp;
+ As with the other fill methods, the bottom and right edges are excluded so the
+ bottom right corner becomes inset by 1.
+<p><img src="images/GradientFillFalse.gif" height=97 width=166>
+<p><code>gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));</code> <br>
+ <code>gc.setForeground(display.getSystemColor(SWT.COLOR_CYAN));</code> <br>
+ <code>gc.fillGradientRectangle(5,5,90,45,true);</code>
+<p>The vertical gradient begins at the top with the foreground color (cyan) and
+ finishes at the bottom with the blue background color.
+<p><img src="images/GradientFillTrue.gif" height=100 width=166>
+<h1> <a NAME="XOR"></a>XOR</h1>
+When drawing occurs on a GC you are altering its pixel values that make up the
+graphic on the Drawable surface.&nbsp; If you set the GC's XOR mode to true, then
+what occurs is that for each pixel the red, green and blue values of the source
+being drawn are XOR'd with the existing red, green and blue values and the result
+becomes the new destination pixel. <br>
+&nbsp;
+<p><code>shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE));</code> <br>
+ <code>// ...</code> <br>
+ <code>gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));</code> <br>
+ <code>gc.fillRectangle(5,5,90,45);</code> <br>
+ <code>gc.setXORMode(true);</code> <br>
+ <code>gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));</code> <br>
+ <code>gc.fillRectangle(20,20,50,50);</code> <br>
+ <code>gc.setBackground(display.getSystemColor(SWT.COLOR_RED));</code> <br>
+ <code>gc.fillOval(80,20,50,50);</code>
+<p><img src="images/XORFills.gif" height=117 width=276>
+<p>The filled rectangle has a background color of white (255,255,255).&nbsp; When
+ this is drawn over the blue (0,0,255) the XOR'd result is yellow (255,255,0).&nbsp;
+ The portion of the rectangle drawn over the white background (255,255,255) creates
+ an XOR result of black (0,0,0). The filled oval has a background color or red
+ (255,0,0).&nbsp; When this is drawn over blue the resulting XOR value is purple
+ (255,0,255), and when it is drawn over white the result is cyan (0,255,255);
+<h1> <a NAME="Drawing Images"></a>Drawing Images</h1>
+The class <code>org.eclipse.swt.graphics.Image</code> represents a graphic that has
+been prepared ready to be displayed on a device such as a Display or Printer.&nbsp;
+The simplest way to create an image is to load it from a recognized file format.&nbsp;
+Supported file formats are GIF, BMP (Windows format bitmap), JPG, PNG, and in
+newer Eclipse releases TIFF.
+<p><code>Image image = new Image(display,"C:/eclipse/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");</code>
+<h2> <code>GC.drawImage(Image image, int x, int y);</code></h2>
+Every image has a size that is determined by its bounds.&nbsp; For example, the
+size of the image <code>eclipse_lg.gif </code>is 115,164 and can be determined by
+using the method <code>image.getBounds(). </code>When an image is drawn it will be
+shown at the width and height defined by its bounds..
+<p><code>gc.drawImage(image,5,5);</code> <br>
+ <img src="images/ImageClient.jpg" height=221 width=175>
+<h2> <code>GC.drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight,
+ int dstX, int dstY, int dstWidth, int dstHeight);</code></h2>
+Images can be drawn with different sizes from their original width and height,
+and also portions of images can be drawn.
+<p>The src coordinates are relative to image itself, so to draw the entire image
+ use 0,0 and width and height set to the image bound's width and height.&nbsp;
+ The dst arguments represent where to draw the image on the GC, and what size
+ to draw it at.&nbsp; The original image is 115 by 164, so to stretch it to twice
+ the width and half the height use the statement
+<p><code>gc.drawImage(image,0,0,115,164,5,5,230,82);</code> <br>
+ <img src="images/ImageClientStretched.jpg" height=136 width=289>
+<p>Using the src coordinates allows you to specify that you want only a portion
+ of the image drawn.&nbsp; For example, if you only want a section from the top
+ right area of the image drawn, you can use src coordinates of 20,0 and a width
+ and height of 95,82.&nbsp; The code below draws the destination rectangle with
+ the same width and height (95,82) as the cropped area, however a different size
+ could be used to stretch or shrink the image portion.
+<p><code>gc.drawImage(image,20,0,95,82,5,5,95,82);</code>
+<p><img src="images/ImageClipped.jpg" height=219 width=405>
+<p>Other images effects can be achieved, such as transparency, animation and alpha
+ channel blending of images.&nbsp; These are outside the scope of this article,
+ however I hope to cover these in a future article.
+<h1> <a NAME="Understanding Images"></a>Conclusion</h1>
+This article has shown how a GC can be used to draw lines, text, and to fill shapes.&nbsp;
+A GC can be created by passing the drawable into its constructor, such as an Image,
+or for a Control by using the <code>paintEvent</code> callback.&nbsp; The API of a
+GC allows lines and shapes to be drawn in its foreground color and filled in its
+background color.&nbsp; The general purpose Canvas control is optimized to allow
+drawing through its <code>paintEvent</code>, and it has a number of constructor style
+bits to control when paint events occur.&nbsp; GC clipping allows you to control
+the region of the GC that visible drawing occurs on, and when drawing different
+line styles can be used, and text and images can be shown.
+<p><font size="-2">Java and all Java-based trademarks and logos are trademarks
+ or registered trademarks of Sun Microsystems, Inc. in the United States, other
+ countries, or both. </font>
+<p><font size="-2">Other company, product, and service names may be trademarks
+ or service marks of others. </font>
+</body>
+</html>
diff --git a/Article-SWT-graphics/about.xml b/Article-SWT-graphics/about.xml
new file mode 100644
index 0000000..a32caa7
--- /dev/null
+++ b/Article-SWT-graphics/about.xml
@@ -0,0 +1,33 @@
+<!DOCTYPE doc [
+ <!ENTITY trade "&#153;">
+ <!ENTITY reg "&#174;">
+]>
+
+<article link="SWT_graphics.html">
+ <title>Graphics Context - Quick on the draw</title>
+ <date>July 3, 2003</date>
+ <category>rcp</category>
+ <category>swt</category>
+ <author>
+ <name>Joe Winchester</name>
+ <company>IBM</company>
+ </author>
+ <description>
+ <![CDATA[
+ The package <code>org.eclipse.swt.graphics</code> contains
+ classes that allow management of graphics resources. Graphics
+ can be drawn on anything that implements
+ <code>org.eclipse.swt.graphics.Drawable</code>, which includes
+ <code>org.eclipse.swt.widgets.Control</code> and
+ <code>org.eclipse.swt.graphics.Image</code>. The class
+ <code>org.eclipse.swt.graphics.GC</code> encapsulates all of
+ the drawing API, including how to draw lines and shapes, draw
+ text and images and fill shapes. This article shows how to use
+ a GC to draw onto an Image, or onto a control through its
+ paintEvent callback. The Canvas control, specifically designed
+ for drawing operations, has a number of constructor style bits
+ that allow you to determine when and how painting
+ occurs, and the article shows how to use these.
+ ]]>
+ </description>
+</article> \ No newline at end of file
diff --git a/Article-SWT-graphics/images/ArcClient.gif b/Article-SWT-graphics/images/ArcClient.gif
new file mode 100644
index 0000000..454e6a7
--- /dev/null
+++ b/Article-SWT-graphics/images/ArcClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/ArcFilledClient.gif b/Article-SWT-graphics/images/ArcFilledClient.gif
new file mode 100644
index 0000000..ed9d0da
--- /dev/null
+++ b/Article-SWT-graphics/images/ArcFilledClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/Cheese_Complete.gif b/Article-SWT-graphics/images/Cheese_Complete.gif
new file mode 100644
index 0000000..7c35e42
--- /dev/null
+++ b/Article-SWT-graphics/images/Cheese_Complete.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/ClippedTriangles.gif b/Article-SWT-graphics/images/ClippedTriangles.gif
new file mode 100644
index 0000000..8d8512c
--- /dev/null
+++ b/Article-SWT-graphics/images/ClippedTriangles.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/GradientFillFalse.gif b/Article-SWT-graphics/images/GradientFillFalse.gif
new file mode 100644
index 0000000..56405c7
--- /dev/null
+++ b/Article-SWT-graphics/images/GradientFillFalse.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/GradientFillTrue.gif b/Article-SWT-graphics/images/GradientFillTrue.gif
new file mode 100644
index 0000000..aea088a
--- /dev/null
+++ b/Article-SWT-graphics/images/GradientFillTrue.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/Idea.jpg b/Article-SWT-graphics/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-SWT-graphics/images/Idea.jpg
Binary files differ
diff --git a/Article-SWT-graphics/images/ImageClient.jpg b/Article-SWT-graphics/images/ImageClient.jpg
new file mode 100644
index 0000000..dda9a16
--- /dev/null
+++ b/Article-SWT-graphics/images/ImageClient.jpg
Binary files differ
diff --git a/Article-SWT-graphics/images/ImageClientStretched.jpg b/Article-SWT-graphics/images/ImageClientStretched.jpg
new file mode 100644
index 0000000..6d4739c
--- /dev/null
+++ b/Article-SWT-graphics/images/ImageClientStretched.jpg
Binary files differ
diff --git a/Article-SWT-graphics/images/ImageClipped.jpg b/Article-SWT-graphics/images/ImageClipped.jpg
new file mode 100644
index 0000000..700a345
--- /dev/null
+++ b/Article-SWT-graphics/images/ImageClipped.jpg
Binary files differ
diff --git a/Article-SWT-graphics/images/LINE_DASH.gif b/Article-SWT-graphics/images/LINE_DASH.gif
new file mode 100644
index 0000000..3f6c096
--- /dev/null
+++ b/Article-SWT-graphics/images/LINE_DASH.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/LINE_DASHDOT.gif b/Article-SWT-graphics/images/LINE_DASHDOT.gif
new file mode 100644
index 0000000..20018cc
--- /dev/null
+++ b/Article-SWT-graphics/images/LINE_DASHDOT.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/LINE_DASHDOTDOT.gif b/Article-SWT-graphics/images/LINE_DASHDOTDOT.gif
new file mode 100644
index 0000000..64552d2
--- /dev/null
+++ b/Article-SWT-graphics/images/LINE_DASHDOTDOT.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/LINE_DOT.gif b/Article-SWT-graphics/images/LINE_DOT.gif
new file mode 100644
index 0000000..1620f90
--- /dev/null
+++ b/Article-SWT-graphics/images/LINE_DOT.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/LineShapes.gif b/Article-SWT-graphics/images/LineShapes.gif
new file mode 100644
index 0000000..4c95499
--- /dev/null
+++ b/Article-SWT-graphics/images/LineShapes.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/Line_SOLID.gif b/Article-SWT-graphics/images/Line_SOLID.gif
new file mode 100644
index 0000000..0c8e96f
--- /dev/null
+++ b/Article-SWT-graphics/images/Line_SOLID.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/OvalClient.gif b/Article-SWT-graphics/images/OvalClient.gif
new file mode 100644
index 0000000..a97100a
--- /dev/null
+++ b/Article-SWT-graphics/images/OvalClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/OvalFilledClient.gif b/Article-SWT-graphics/images/OvalFilledClient.gif
new file mode 100644
index 0000000..d657c3d
--- /dev/null
+++ b/Article-SWT-graphics/images/OvalFilledClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/PolygonClient.gif b/Article-SWT-graphics/images/PolygonClient.gif
new file mode 100644
index 0000000..7942cea
--- /dev/null
+++ b/Article-SWT-graphics/images/PolygonClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/PolygonFillClient.gif b/Article-SWT-graphics/images/PolygonFillClient.gif
new file mode 100644
index 0000000..636183f
--- /dev/null
+++ b/Article-SWT-graphics/images/PolygonFillClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/RectangleClient.gif b/Article-SWT-graphics/images/RectangleClient.gif
new file mode 100644
index 0000000..287d5d3
--- /dev/null
+++ b/Article-SWT-graphics/images/RectangleClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/RectangleFillClient.gif b/Article-SWT-graphics/images/RectangleFillClient.gif
new file mode 100644
index 0000000..034e9e5
--- /dev/null
+++ b/Article-SWT-graphics/images/RectangleFillClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/RectangleStrokeFill.gif b/Article-SWT-graphics/images/RectangleStrokeFill.gif
new file mode 100644
index 0000000..af55763
--- /dev/null
+++ b/Article-SWT-graphics/images/RectangleStrokeFill.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/RoundedRectangleClient.gif b/Article-SWT-graphics/images/RoundedRectangleClient.gif
new file mode 100644
index 0000000..1b4287e
--- /dev/null
+++ b/Article-SWT-graphics/images/RoundedRectangleClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/RoundedRectangleFilledClient.gif b/Article-SWT-graphics/images/RoundedRectangleFilledClient.gif
new file mode 100644
index 0000000..798b57e
--- /dev/null
+++ b/Article-SWT-graphics/images/RoundedRectangleFilledClient.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/ShellDrawnLine.gif b/Article-SWT-graphics/images/ShellDrawnLine.gif
new file mode 100644
index 0000000..8e94211
--- /dev/null
+++ b/Article-SWT-graphics/images/ShellDrawnLine.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/StringHelloWorld.gif b/Article-SWT-graphics/images/StringHelloWorld.gif
new file mode 100644
index 0000000..d9c5233
--- /dev/null
+++ b/Article-SWT-graphics/images/StringHelloWorld.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/TextFlags.gif b/Article-SWT-graphics/images/TextFlags.gif
new file mode 100644
index 0000000..f5264da
--- /dev/null
+++ b/Article-SWT-graphics/images/TextFlags.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/TextHelloWorld.gif b/Article-SWT-graphics/images/TextHelloWorld.gif
new file mode 100644
index 0000000..5120626
--- /dev/null
+++ b/Article-SWT-graphics/images/TextHelloWorld.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/TextHelloWorldTransparent.gif b/Article-SWT-graphics/images/TextHelloWorldTransparent.gif
new file mode 100644
index 0000000..50e2aa7
--- /dev/null
+++ b/Article-SWT-graphics/images/TextHelloWorldTransparent.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/Width_2.gif b/Article-SWT-graphics/images/Width_2.gif
new file mode 100644
index 0000000..4afc1cd
--- /dev/null
+++ b/Article-SWT-graphics/images/Width_2.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/Width_4.gif b/Article-SWT-graphics/images/Width_4.gif
new file mode 100644
index 0000000..a720ba0
--- /dev/null
+++ b/Article-SWT-graphics/images/Width_4.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/XORFills.gif b/Article-SWT-graphics/images/XORFills.gif
new file mode 100644
index 0000000..8a0797b
--- /dev/null
+++ b/Article-SWT-graphics/images/XORFills.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/default_style.css b/Article-SWT-graphics/images/default_style.css
new file mode 100644
index 0000000..d725483
--- /dev/null
+++ b/Article-SWT-graphics/images/default_style.css
@@ -0,0 +1,11 @@
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
diff --git a/Article-SWT-graphics/images/image_lg_lines.gif b/Article-SWT-graphics/images/image_lg_lines.gif
new file mode 100644
index 0000000..59449e7
--- /dev/null
+++ b/Article-SWT-graphics/images/image_lg_lines.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/image_lg_orig.gif b/Article-SWT-graphics/images/image_lg_orig.gif
new file mode 100644
index 0000000..f75d32b
--- /dev/null
+++ b/Article-SWT-graphics/images/image_lg_orig.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/linux_only.gif b/Article-SWT-graphics/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-SWT-graphics/images/linux_only.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/tag_1.gif b/Article-SWT-graphics/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-SWT-graphics/images/tag_1.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/tag_2.gif b/Article-SWT-graphics/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-SWT-graphics/images/tag_2.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/tag_3.gif b/Article-SWT-graphics/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-SWT-graphics/images/tag_3.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/tag_4.gif b/Article-SWT-graphics/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-SWT-graphics/images/tag_4.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/tag_5.gif b/Article-SWT-graphics/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-SWT-graphics/images/tag_5.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/tag_6.gif b/Article-SWT-graphics/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-SWT-graphics/images/tag_6.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/tag_7.gif b/Article-SWT-graphics/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-SWT-graphics/images/tag_7.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/tip.gif b/Article-SWT-graphics/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-SWT-graphics/images/tip.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/tryit.gif b/Article-SWT-graphics/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-SWT-graphics/images/tryit.gif
Binary files differ
diff --git a/Article-SWT-graphics/images/win_only.gif b/Article-SWT-graphics/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-SWT-graphics/images/win_only.gif
Binary files differ
diff --git a/Article-SWT-images/graphics-resources.html b/Article-SWT-images/graphics-resources.html
new file mode 100644
index 0000000..df13bb6
--- /dev/null
+++ b/Article-SWT-images/graphics-resources.html
@@ -0,0 +1,1050 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="Author" content="Joe Winchester">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Taking a look at SWT Images</title>
+<link href="../default_style.css" rel=stylesheet>
+</head>
+
+<body>
+
+<div align="right">
+ <font face="Times New Roman, Times, serif"><font size="-1">Copyright © 2003
+ International Business Machines Corp.</font></font>
+</div>
+<div align="right">
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP" colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<h1><img src="images/Idea.jpg" height="86" width="120" align="CENTER"></h1>
+<center>
+ <h1>Taking a look at SWT Images</h1>
+</center>
+<blockquote>
+ <b>Summary</b><br>
+ SWT's Image class can be used to display images in a GUI. The most common
+ source of images is to load from a standard file format such as GIF, JPEG,
+ PNG, or BMP. Some controls, including Buttons and TreeItems, are able to
+ display an Image directly through the setImage(Image) method, but any
+ control's paint event allows images to be drawn through the callback's graphic
+ context. SWT's ImageData class represents the raw data making up an SWT Image
+ and determines the color for each pixel coordinate. This article shows the
+ correct uses of ImageData and Image, shows how to load images from files, and
+ how to achieve graphic effects such as transparency, alpha blending,
+ animation, scaling, and custom cursors.
+ <p><b>By Joe Winchester, IBM</b><br>
+ <font size="-1">September 10th, 2003</font></blockquote>
+<hr width="100%">
+<p>This first section of this article gives an introduction to colors and shows
+how an image records the color value of each pixel.
+<ul>
+ <li><a href="#Introduction">Introduction</a></li>
+ <li><a href="#Image lifecycle">Image lifecycle</a></li>
+ <li><a href="#ImageData">ImageData</a></li>
+ <li><a href="#Colors">Color</a></li>
+ <li><a href="#PaletteData">PaletteData</a></li>
+ <ul>
+ <li><a href="#Indexed palette">Indexed palette</a></li>
+ <li><a href="#Direct palette">Direct palette</a></li>
+ </ul>
+</ul>
+The next section describes image transparency, alpha blending, animation, and
+how to scale images.
+<ul>
+ <li><a href="#Transparency">Transparency</a></li>
+ <li><a href="#Manipulating Image Data">Manipulating ImageData</a></li>
+ <li><a href="#Saving Images">Saving Images</a></li>
+ <li><a href="#Blending">Blending</a></li>
+ <ul>
+ <li><a href="#Single alpha value">Single alpha value</a></li>
+ <li><a href="#Different alpha value per pixel">Different alpha value per
+ pixel</a></li>
+ </ul>
+ <li><a href="#Image Effects">Image effects</a></li>
+ <li><a href="#Animation">GIF animation</a></li>
+ <li><a href="#Scaling">Scaling</a></li>
+</ul>
+Finally, the article shows how to create cursors from images, by using a source
+image together with a mask.
+<ul>
+ <li><a href="#Cursor">Cursors</a></li>
+ <ul>
+ <li><a href="#Platform cursors">Platform cursors</a></li>
+ <li><a href="#Custom cursors">Custom cursors</a></li>
+ </ul>
+</ul>
+<h1><a name="Introduction"></a>Introduction</h1>
+The simplest way to create an SWT Image is to load it from a recognized graphic
+file format. This includes GIF, BMP (Windows format bitmap), JPG, and PNG. The
+TIFF format is also supported in more recent Eclipse releases. Images can be
+loaded from a known location in the file system using the constructor <tt>Image(Display
+display, String fileLocation)</tt>:
+<p><tt>Image image = new Image(display,<br>
+&nbsp;&nbsp;
+&quot;C:/eclipse/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif&quot;);</tt>
+<p>Instead of hard-coding the location of the image, it's more common to load
+the Image from a folder location relative to a given class. This is done by
+creating an InputStream pointing to the file with the method <tt>Class.getResourceAsStream(String
+name)</tt>, and using the result as the argument to the constructor <tt>Image(Display
+display, InputStream inputStream)</tt>.
+<p>The Eclipse package explorer below shows the class <tt>com.foo.ShellWithButtonShowingEclipseLogo
+</tt>and the <tt>eclipse_lg.gif</tt> in the same folder. To following code would
+load the graphic from its location relative to the class.
+<p><tt>Image image = new Image(display, <br>
+&nbsp;&nbsp;&nbsp;
+ShellWithButtonShowingEclipseLogo.class.getResourceAsStream(<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;eclipse_lg.gif&quot;));</tt>
+<p><img src="images/IntroductionRelativeIcon.gif" height="184" width="298">
+<p>Once the image has been created it can be used as part of a control such as a
+Button or Label that is able to render the graphic as part of their <tt>setImage(Image
+image)</tt> methods.
+<p><tt>Button button = new Button(shell,SWT.PUSH);</tt><br>
+<tt>button.setImage(image);</tt>
+<p><img src="images/ButonLogo.gif" height="220" width="278">
+<p>Images can be drawn onto using a graphics context that is created with the
+constructor <tt>GC(Drawable drawable)</tt> with the Image as the argument.
+<p><tt>GC gc = new GC(image);</tt><br>
+<tt>gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));</tt><br>
+<tt>gc.drawText(&quot;I've been drawn on&quot;,0,0,true);</tt><br>
+<tt>gc.dispose();</tt>
+<p><img src="images/IveBeenDrawnOn.gif" height="218" width="276">
+<p>Using a GC to draw onto an Image permanently alters the graphic. More
+information on how to use a GC is covered in the article <a href="http://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html">Graphics
+Context - Quick on the draw.</a>
+<h1><a name="Image lifecycle"></a>Image lifecycle</h1>
+When an image is loaded, the first step is to create device independent ImageData
+represented by the class <tt>org.eclipse.swt.graphics.ImageData</tt>. Following
+this, the data is prepared for a specific device by creating an actual Image instance.
+<p>As well as loading an Image directly from a file, you can separately create
+ the ImageData object and then construct the Image using <tt>Image(Device device,
+ ImageData imageData)</tt>. The data for an existing Image can be retrieved using
+ <tt>getImageData()</tt>, although this will not be the same object that was
+ used to create the image. This is because when preparing an image to be drawn
+ onto a screen, properties such as its color depth might be different from the
+ initial image data.
+<p>Instances of Image represent an underlying resource that has been prepared
+for a specific device and they must be disposed when they are no longer required
+to free up the allocated resource. There is no finalization of resources in SWT
+when an object is garbage collected. For more information see <a href="http://www.eclipse.org/articles/swt-design-2/swt-design-2.html">SWT:
+The Standard Widget Toolkit: Managing Operating System Resources.</a>
+<h2><a name="ImageData"></a>ImageData</h2>
+ImageData can be thought of as the model for an image, whereas the Image is the
+view that's been prepared for output onto a specific device. The ImageData has a
+width and height, and a pixel value for each coordinate. The raw data of the
+image is a byte[], and the depth of the image specifies the number of bits that
+are used for each coordinate. An image depth of 1 can store two possible values
+for each pixel (0 and 1), a depth of 4 can store 2^4=16, a depth of 8 can
+store 2^8=256 values and a depth of 24 can represent 2^24=16 million different
+values per pixel. The larger the depth of an image the more bytes are required
+for its pixels, and some formats such as GIF that were initially designed for
+download across internet connections only support a maximum depth of 8. How the
+value of each pixel value translates into an actual color depends on its palette
+represented by the class <tt>org.eclipse.swt.graphics.PaletteData.</tt>
+<p>The next section describes how <a href="#Colors">colors</a> are represented
+by their RGB values, and how <a href="#PaletteData">PaletteData</a> maps a map
+pixel value to a particular color.
+<h2><a name="Colors"></a>Color</h2>
+The class <tt>org.eclipse.swt.graphics.Color </tt>is used to manage resources
+that implement the RGB color model. Each color is described in terms of its red,
+green and blue component (each expressed as an integer value from 0 for no color
+to 255 for full color).
+<p><tt>Color cyanColor = new Color(display,0,255,255);</tt><br>
+<tt><font color="#00CC00">// ... Code to use the Color</font></tt><br>
+<tt>cyanColor.dispose();</tt>
+<p>The convenience class <tt>org.eclipse.swt.graphics.RGB </tt>exists in SWT
+that combines a color's red, green and blue values into a single object.
+<p><tt>RGB cyanRGB = new RGB(0,255,255);</tt><br>
+<tt>Color cyanColor = new Color(display,cyanRGB);</tt><br>
+<tt><font color="#009900">// ... Code to use the Color</font></tt><br>
+<tt>cyanColor.dispose();</tt>
+<p>The Color instance should be disposed when it is no longer required, whereas
+the RGB has no need to be disposed. This is similar to the relationship between
+an Image and its ImageData, where Color and Image are device specific objects
+using underlying native resources, while RGB and ImageData are the underlying
+model data.
+<p>To avoid having to create and manage instances of the commonly used colors,
+the Display class allow these to be retrieved using the method <tt>Display.getSystemColor(int
+id)</tt>.
+<p><tt>Color cyanColor = display.getSystemColor(SWT.COLOR_CYAN)</tt>
+<p>When a Color is obtained by an SWT program using the method <tt>Display.getSystemColor(int
+id) </tt>method, it must not be disposed. The rule of thumb that works for any
+SWT resource is <i>&quot;If you created it, you are responsible for disposing it</i>&quot;.
+Because the statement above retrieved the cyan color instance, and didn't
+explicitly construct it, it should not be disposed.
+<p>How a Color is actually represented on the display depends on factors such
+ as the resolution and depth of the display. For more information on this and
+ the SWT color model see <a href="http://www.eclipse.org/articles/SWT%20Color%20Model/swt-color-model.htm">SWT
+ Color Model.</a>
+<h2><a name="PaletteData"></a>PaletteData</h2>
+There are two kinds of PaletteData, an <a href="#Indexed palette">indexed palette
+</a>and a <a href="#Direct palette">direct palette</a>. PaletteData is a model
+of how pixel values map to RGB values, and because they do not represent an underlying
+resource, they do not require disposing.
+<h3><a name="Indexed palette"></a>Indexed palette</h3>
+With an indexed palette each pixel value represents a number that is then cross
+indexed with the palette to determine the actual color. The range of allowable
+pixel values is the depth of the image.
+<p>The example below is a 48 by 48 square image created with a depth of 1, and
+ an indexed color palette. The indexed palette assigns <img src="images/tag_1.gif" height="13" width="24">
+ 0 to be red and 1 to be green (by virtue of their order in the RGB[] in the
+ constructor). The ImageData's un-initialized pixel values will initially be
+ 0 (red), and two for loops <img src="images/tag_2.gif" height="13" width="24">
+ set a 34 by 34 square in the center of the ImageData to be 1 (green).
+<p><img src="images/tag_1.gif" height="13" width="24"><tt> PaletteData
+paletteData = new PaletteData(<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new RGB[] {new RGB(255,0,0), new
+RGB(0,255,0)});</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; ImageData imageData = new ImageData(48,48,1,paletteData);</tt><br>
+<img src="images/tag_2.gif" height="13" width="24"><tt> for(int
+x=11;x&lt;35;x++){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int y=11;y&lt;35;y++){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+imageData.setPixel(x,y,1);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; Image image = new Image(display,imageData);</tt>
+<p><img src="images/RedGreenImage.gif" height="48" width="48">
+<p>The above example has a depth of 1 so it can store 2 colors, but as the color
+ depth of the ImageData increases then so can the number of colors in the palette.&nbsp;
+ An indexed palette can have a 1, 2, 4, or 8 bit depths, and an 8 bit depth provides
+ 2^8 = 256 possible colors.&nbsp; To have a higher color depth (such as 16, 24,
+ or 32) a direct palette must be used.
+<h3><a name="Direct palette"></a>Direct palette</h3>
+Instead of having each pixel value represent an index in the palette
+corresponding to its color, a direct palette allows each pixel value to directly
+record its red, green and blue component.&nbsp; A direct <tt>PaletteData</tt>
+defines red, green and blue masks.&nbsp; These masks are number of bits required
+to shift a pixel value to the left so the high bit of the mask aligns with the
+high bit of the first byte of color.&nbsp; For example, a 24 bit direct palette
+can divide itself into 3 portions, storing red in the lowest 8 bits, green in
+the central 8 bits and blue in the highest 8 bits.&nbsp; The red shift mask
+would be 0xFF, green 0xFF00 and blue 0xFF0000.
+<p><img src="images/DirectPalette_02.gif" height="250" width="596">
+<p>The value for each pixel represents a combination of the red, green and blue
+components into a single 24 bit integer. To construct an indexed palette the
+constructor used <img src="images/tag_1.gif" height="13" width="24"> allows
+the red, green and blue color masks to be specified.
+<p><img src="images/tag_1.gif" height="13" width="24"><tt> PaletteData palette =
+new PaletteData(0xFF , 0xFF00 , 0xFF0000);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; ImageData imageData = new ImageData(48,48,24,palette);</tt>
+<p>Using the same technique as earlier, the code iterates over every pixel coordinate
+ setting it to either <img src="images/tag_2.gif" height="13" width="24">
+ 0xFF (for red) or <img src="images/tag_3.gif" height="13" width="24"> 0xFF00
+ (for green).
+<p><tt>&nbsp;&nbsp;&nbsp; for (int x=0;x&lt;48;x++){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int y=0;y&lt;48;y++){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(y &gt;
+11 &amp;&amp; y &lt; 35 &amp;&amp; x &gt; 11 &amp;&amp; x &lt; 35){</tt><br>
+<img src="images/tag_2.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+imageData.setPixel(x,y,0xFF00);&nbsp;&nbsp; <font color="#009900">// Set the
+center to green</font></tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+imageData.setPixel(x,y,0xFF);&nbsp;&nbsp; <font color="#009900">// and
+everything else to red</font></tt><br>
+<img src="images/tag_1.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; };</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; Image image = new Image(display,imageData);</tt>
+<p>This creates the result below where the image is red with a green center.
+<p><img src="images/RedGreenImage.gif" height="48" width="48">
+<p>Because you can use color depths of 16, 24 and 32 bits with direct palettes,
+ you can represent more colors than are available with an indexed palette whose
+ maximum depth is 8. A color depth of 24 allows you to represent 16 million colors
+ (2^24). The tradeoff however is size, because an indexed palette with a depth
+ of 8 requires one byte per image coordinate whereas a direct palette with a
+ depth of 24 requires three bytes per image coordinate.
+<p>With both direct and indexed palettes you can go from an RGB to a pixel value
+and vice-versa using the public methods <tt>int getPixel(RGB rgb)</tt> and <tt>RGB getRGB(int
+pixelValue)</tt>.
+<h2><a name="Transparency"></a>Transparency</h2>
+The purpose of transparency is to make a portion of the image non-opaque, so
+when it is drawn on a GUI surface the original background shows through. This is
+done by specifying that one of the image colors is transparent. Whenever a pixel
+with the transparent color value is drawn, instead of using the RGB value
+defined in the palette the original destination background pixel color is used
+instead. The effect to the user is that the areas of the image that equal the
+transparent pixel show the background of whatever the image is being drawn over,
+thus achieving transparency. Persisted image file formats such as GIF or BMP
+allow you to specify a transparent pixel value, although only if the palette is
+indexed and the color depth is 8 or less.
+<p>When Images are used directly on controls such as Button or Label the native
+behavior may be that transparent pixels are ignored and drawn in the pixel color
+specified by the source. Native image transparency however is supported in SWT
+for operations involving a GC. To illustrate this the following file Idea.gif
+has a color depth of 8, and the white pixel (index 255 in the palette) set to be
+the transparent pixel.
+<p><img src="images/Idea.gif" border="0" height="86" width="120">
+<p>The shell below has a Label on the left with a Canvas next to it. The
+Idea.gif is used <img src="images/tag_1.gif" height="13" width="24"> as the
+label's image, and also in the paint event <img src="images/tag_2.gif" height="13" width="24">
+of the Canvas. Because the Label does not support native transparency the
+original white color of the transparent pixel is used as the background, however
+the GC in the paint event respects the transparent pixel and the grey background
+shows through.
+<p><tt>&nbsp;&nbsp;&nbsp; Image ideaImage = new
+ImageData(getClass().getResourceAsStream(&quot;Idea.gif&quot;));</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; Label label = new Label(shell,SWT.NONE);</tt><br>
+<img src="images/tag_1.gif" height="13" width="24"><tt>
+label.setImage(ideaImage);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; Canvas canvas = new Canvas(shell,SWT.NO_REDRAW_RESIZE);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; canvas.addPaintListener(new PaintListener() {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void
+paintControl(PaintEvent e) {</tt><br>
+<img src="images/tag_2.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+e.gc.drawImage(ideaImage,0,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; });</tt>
+<p><img src="images/TransparentIdea.gif" height="146" width="270">
+<p>For the above example I stacked the deck in my favor, because I didn't
+actually use the idea graphic that is included with eclipse articles in their
+banner. The reason is that the original graphic is a JPG file which doesn't
+support transparency, so I used a graphics tool to convert it to a GIF and set
+the value of the white pixel in the palette to be the transparency pixel. The
+original Idea.jpg is shown below, and although it looks the same as the
+Idea.gif, this is because it is on the white background of the HTML browser.
+<p><img src="images/Idea.jpg" border="0" height="86" width="120">
+<p>By using the original JPG file this offers a good example of how we to
+achieve a transparency effect progrmatically by manpulating its ImageData. The
+ImageData class has a public field <tt>transparentPixel</tt> to specify which
+pixel is transparent that can be set once a persisted image file is loaded into
+an ImageData instance, irrespective of whether the persisted file format
+supports transparency.
+<p>The code below loads the Idea.jpg file in an ImageData object and <img src="images/tag_1.gif" height="13" width="24">
+sets the transparent pixel for the ImageData to be the pixel value of the color
+white in the palette. The pixel value in the indexed palette that represents
+white is retrieved <img src="images/tag_2.gif" height="13" width="24"> by
+using getPixel(RGB). The manipulated ImageData is used to create an Image
+transparentIdeaImage that now has the white pixel value specified to be
+transparent.
+<p><tt>&nbsp;&nbsp;&nbsp; ImageData ideaData = new ImageData(<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+getClass().getResourceAsStream(&quot;Idea.jpg&quot;));</tt><br>
+<img src="images/tag_2.gif" height="13" width="24"><tt> int whitePixel =
+ideaData.palette.getPixel(new RGB(255,255,255));</tt><br>
+<img src="images/tag_1.gif" height="13" width="24"><tt>
+ideaData.transparentPixel = whitePixel;</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; Image transparentIdeaImage = new Image(display,ideaData);</tt>
+<p>Next a Shell uses the newly created image <img src="images/tag_3.gif" height="13" width="24">
+in a native Label and also in the paint event <img src="images/tag_4.gif" height="13" width="24">
+of a Canvas. A Windows Label does not support native transparency so it still
+appears with a white background, however the GC for the Canvas uses the existing
+background color whenever a white pixel is encountered in the source image, so
+the image appears as transparent.
+<p><tt>&nbsp;&nbsp;&nbsp; Label transparentIdeaLabel = new
+Label(shell,SWT.NONE);</tt><br>
+<img src="images/tag_3.gif" height="13" width="24"><tt>
+transparentIdeaLabel.setImage(transparentIdeaImage);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; Canvas canvas = new Canvas(shell,SWT.NONE);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; canvas.addPaintListener(new PaintListener() {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void
+paintControl(PaintEvent e) {</tt><br>
+<img src="images/tag_4.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+e.gc.drawImage(transparentIdeaImage,0,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; });</tt>
+<p><img src="images/IdeaTransparency.gif" height="146" width="280">
+<p>As can be seen from the second of the two images (drawn on the Canvas with
+ the white pixel set to transparent), there are still some patches of white.
+ Closer analysis reveals that this is not a bug, but that these regions are not
+ pure white (255,255,255), but are slighly off-white (such as 255,254,254). The
+ transparent pixel of an ImageData can only be used for a single value. This
+ now presents the next problem to be solved - locate all of the off-white pixels
+ in the ImageData and convert them to pure-white. To do this we will iterate
+ over each pixel in the image data and modify those that are close to white to
+ be pure white.
+<h2><a name="Manipulating Image Data"></a>Manipulating ImageData</h2>
+Because the graphic Idea.jpg isn't as white as we'd like it, we'll iterate over
+its imageData and convert the off-white pixels to pure white and then we'll save
+this into a new file Idea_white.jpg. In practice it's unlikely that you'd ever
+do this kind of programming in SWT, however it's a good example to use showing
+how ImageData can be analyzed and manipulated.
+<p>The first step is to load the image and then iterate over each pixel
+individually looking at its color. Because Idea.jpg is using a direct palette,
+the pixel value is an int that contains the red, green and blue component as
+masked bit areas. These mask value can be obtained from the palette.
+<p><tt>ImageData ideaImageData = new ImageData(<br>
+&nbsp;&nbsp;&nbsp; getClass().getResourceAsStream(&quot;Idea.jpg&quot;));</tt><br>
+<tt>int redMask = ideaImageData.palette.redMask;</tt><br>
+<tt>int blueMask = ideaImageData.palette.blueMask;</tt><br>
+<tt>int greenMask = ideaImageData.palette.greenMask;</tt>
+<p>For any pixel value we can bitwise AND it with the mask to see what the color
+component is. The red component is the low order bits so this will be the actual
+value (from 0 to 255), however the green and blue values need adjusting as they
+are the high order bits in the pixel value. To make this adjustment the color
+component can be bit shifted to the right using the &gt;&gt; operator. If you
+are writing generic code to do this kind of manipulating, take care that direct
+palettes for color depths of 24 or 32 store their color components with red
+being the low order bits, however for color depth of 16 the colors are reversed
+and red is high order with blue being low order. The reason for this is to be
+the same as how Windows stores images internally so there is less conversion
+when creating the image.
+<p>Two for loops will iterate over the imageData. The first is traversing the
+image from top to bottom a line at a time, and <img src="images/tag_1.gif" height="13" width="24">
+creates an int[] to hold each line of data. The method<tt>
+ImageData.getPixels(int x, int y, int getWidth, int[] pixels, int startIndex)</tt>
+is used <img src="images/tag_2.gif" height="13" width="24"> to extract a
+line at a time from the imageData's bytes. The API for this method is slightly
+irregular, because rather than returning the resulting data it instead is
+declared as <tt>void</tt>, and the resulting pixel data is injected into the
+int[] that is passed in as a method argument. The int[] of pixels is then
+iterated over and each value has its <img src="images/tag_3.gif" height="13" width="24">
+red, <img src="images/tag_4.gif" height="13" width="24"> green and <img src="images/tag_5.gif" height="13" width="24">
+blue component extracted. The desired effect we want is to determine whether the
+pixel is off-white and if so to make it pure white - a rule that works well is
+to assume that anything whose red and green component are higher than 230 <img src="images/tag_6.gif" height="13" width="24">
+and blue component higher than 150 is an off-white.
+<p><img src="images/tag_1.gif" height="13" width="24"><tt> int[] lineData = new
+int[ideaImageData.width];</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; for (int y = 0; y &lt; ideaImageData.height; y++) {</tt><br>
+<img src="images/tag_2.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;
+ideaImageData.getPixels(0,y,width,lineData,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#009900">&nbsp; // Analyze
+each pixel value in the line</font></tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int x=0;
+x&lt;lineData.length; x++){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#009900">//
+Extract the red, green and blue component</font></tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int
+pixelValue = lineData[x];</tt><br>
+<img src="images/tag_3.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+int r = pixelValue &amp; redShift;</tt><br>
+<img src="images/tag_4.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+int g = (pixelValue &amp; greenShift) &gt;&gt; 8;</tt><br>
+<img src="images/tag_5.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+int b = (pixelValue &amp; blueShift) &gt;&gt; 16;</tt><br>
+<img src="images/tag_6.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if (r &gt; 230 &amp;&amp; g &gt; 230 &amp;&amp; b &gt; 150){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ideaImageData.setPixel(x,y,0xFFFFFF);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; };</tt>
+<p>Having manipulated the raw bytes making up the ImageData we have now
+successfully changed the off-white values to pure white.
+<h2><a name="Saving Images"></a>Saving Images</h2>
+Now that we have the ImageData where all of the whitish pixels have been
+converted to white, and the transparency pixel of the palette has been set to be
+the color white, we'll save this image so that next time an SWT program needs
+the pure white JPF it can just load the file and use it as is. To save ImageData
+into a file use the class <tt>org.eclipse.swt.graphics.ImageLoader</tt>. The
+image loader has a public field data typed to ImageData[]. The reason the data
+field is an array of ImageData is to support image file formats with more than
+one frame such as animated GIFs or interlaced JPEG files. These are covered more
+in the <a href="#Animation">Animation</a> section later.
+<p><tt>ImageLoader imageLoader = new ImageLoader();</tt><br>
+<tt>imageLoader.data = new ImageData[] {ideaImageData};</tt><br>
+<tt>imageLoader.save(&quot;C:/temp/Idea_PureWhite.jpg&quot;,SWT.IMAGE_JPEG);</tt>
+<p>The finished result is shown below.
+<p><img src="images/Idea_transparent.jpg" height="86" width="120">
+<p>It doesn't look much different to the original Idea.jpg because it is drawn
+on a white background, but when it is drawn on a Canvas with the white pixel set
+to be the transparent pixel the background shows through achieving the desired
+effect.
+<p><tt>&nbsp;&nbsp;&nbsp; ImageData pureWhiteIdeaImageData =<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new ImageData(&quot;C:/temp/Idea_PureWhite.jpg&quot;);</tt><br>
+<img src="images/tag_1.gif" height="13" width="24"><tt>
+pureWhiteIdeaImageData.transparentPixel =<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+pureWhiteIdeaImageData.palette.getPixel(new RGB(255,255,255));</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; final Image transparentIdeaImage = new
+Image(display,pureWhiteIdeaImageData);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; Canvas canvas = new Canvas(shell,SWT.NONE);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; canvas.addPaintListener(new PaintListener() {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void
+paintControl(PaintEvent e) {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+e.gc.drawImage(transparentIdeaImage,0,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; });</tt>
+<p><img src="images/Idea_Transparent_DrawnOnCanvas.gif" height="150" width="173">
+<p><img src="images/Note.gif" height="13" width="62"> It might seem odd that in
+the above code that after loading the Idea_PureWhite.jpg file <img src="images/tag_1.gif" height="13" width="24">
+the transparent pixel was set to be white. Why not set the transparent pixel
+before we used the ImageLoader to create the persisted Idea_PureWhite.jpg file?
+The reason is that the JPEG image file format does not support transparency. A
+GIF file supports native transparency, however changing the file type to
+SWT.IMAGE_GIF on the ImageLoader would not have worked, because GIF supports a
+maximum image depth of 8 and uses an indexed palette, whereas the JPEG has an
+image depth of 24 and a direct palette. To convert between the two formats would
+require analyzing the colours used by the JPEG to create the best fit 256 color
+palette, before iterating over each JPEG pixel value and creating the GIF image
+data by finding the closest color. Doing this conversion is outside the scope of
+this article, although it can be done by most commercial graphics tools. To
+match pixel values as the color depth decreases from 24 to 8 involves algorithms
+that find the right color match for a block of pixels rather than a single pixel
+value, and is why image quality can sometimes be reduced when switching between
+different formats.
+<p>We have shown how an ImageData is an array of int values representing each
+pixel coordinate, and how each pixel value is mapped to a color through the
+palette. This allowed us to iterate over the image data for the Idea.jpg, query
+pixel values that were close to white, and convert these to a pure white RGB
+value. The end result of this was that we were able to create the
+Idea_PureWhite.jpg file that can be used as a transparent JPG by setting the
+white pixel to be transparent. Transparency works by having a source pixel value
+(the image being drawn), a destination pixel value (the image being drawn onto)
+and a rule by which the resulting destination pixel value is determined. For
+transparency the rule is that the source pixel value is used unless it's
+transparent in which case the destination pixel is used. Another technique is to
+use alpha values that specify the weight applied to the source relative to the
+destination to create the final pixel value. This allows the blending between
+the source image and the existing background it is being drawn onto.
+<h2><a name="Blending"></a>Blending</h2>
+Alpha blending is a technique used to merge two pixel values, where the source
+and destination pixel each specify an alpha value that weights how much they
+will affect the final destination pixel. An alpha value of 255 is full weight,
+and 0 is no weight. SWT supports a <a href="#Single alpha value">single alpha
+value</a> for the entire ImageData, or else each pixel can have its <a href="#Different alpha value per pixel">own
+alpha value.</a>
+<h3><a name="Single alpha value"></a>Single alpha value</h3>
+The <tt>int</tt> field <tt>alphaValue</tt> of ImageData is used to specify a
+single value that weights how the source pixels are combined with the
+destination input to create the destination output. The listing below shows how
+the same ImageData for the Idea_PureWhite.jpg is used for three separate images.
+The first <img src="images/tag_1.gif" height="13" width="24"> is the
+original, then <img src="images/tag_2.gif" height="13" width="24"> an alpha
+of 128 is used, and finally <img src="images/tag_3.gif" height="13" width="24">
+an alpha of 64. Note that the same ImageData is continually manipulated by
+having its alpha changed before creating each Image, and changing the ImageData
+has no affect on Images already constructed using it. This is because the Image
+is prepared for display on the device from the ImageData at construction time.
+<p><tt>&nbsp;&nbsp;&nbsp; Shell shell = new Shell(display);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; shell.setLayout(new FillLayout());</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; ImageData imageData = new
+ImageData(&quot;C:/temp/Idea_PureWhite.jpg&quot;);</tt><br>
+<img src="images/tag_1.gif" height="13" width="24"><tt> final Image fullImage =
+new Image(display,imageData);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; imageData.alpha = 128;</tt><br>
+<img src="images/tag_2.gif" height="13" width="24"><tt> final Image halfImage =
+new Image(display,imageData);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; imageData.alpha = 64;</tt><br>
+<img src="images/tag_3.gif" height="13" width="24"><tt> final Image quarterImage
+= new Image(display,imageData);</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; Canvas canvas = new
+Canvas(shell,SWT.NO_REDRAW_RESIZE);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; canvas.addPaintListener(new PaintListener() {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void
+paintControl(PaintEvent e) {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+e.gc.drawImage(fullImage,0,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+e.gc.drawImage(halfImage,140,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+e.gc.drawImage(quarterImage,280,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; });</tt>
+<p><img src="images/SingleAlphaChannel.gif" height="137" width="417">
+<h3><a name="Different alpha value per pixel"></a>Different alpha value per
+pixel</h3>
+As well as having a single alpha value that applied to all pixels in the source
+image, ImageData allows each pixel to have its own individual alpha value. This
+is done with the <tt>byte[]</tt> field <tt>alphaData</tt>. This allows effects to be
+achieved, such as having an image fade from its top to bottom.
+<p>The following code creates <img src="images/tag_1.gif" height="13" width="24">
+an alphaData <tt>byte[]</tt>, and then has two loops. The outer loop y <img src="images/tag_2.gif" height="13" width="24">
+is from 0 to the imageData's height, and the inner loop <img src="images/tag_3.gif" height="13" width="24">
+creates a <tt>byte[]</tt> for the width of the imageData and initializes it with
+a value that increases from 0 for the top row through to 255 for the bottom row.
+A System.arrayCopy <img src="images/tag_4.gif" height="13" width="24"> then
+builds up the alphaData <tt>byte[]</tt> with each row.
+<p><tt>&nbsp;&nbsp;&nbsp; ImageData fullImageData = new
+ImageData(&quot;C:/temp/Idea_PureWhite.jpg&quot;);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; int width = fullImageData.width;</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; int height = fullImageData.height;</tt><br>
+<img src="images/tag_1.gif" height="13" width="24"><tt> byte[] alphaData = new
+byte[height * width];</tt><br>
+<img src="images/tag_2.gif" height="13" width="24"><tt> for(int
+y=0;y&lt;height;y++){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] alphaRow = new
+byte[width];</tt><br>
+<img src="images/tag_3.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;
+for(int x=0;x&lt;width;x++){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+alphaRow[x] = (byte) ((255 * y) /height);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<img src="images/tag_4.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;
+System.arraycopy(alphaRow,0,alphaData,y*width,width);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; fullImageData.alphaData = alphaData;</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; Image fullImage = new Image(display,fullImageData);</tt>
+<p>The resulting image is shown below, and the alphaData <tt>byte[]</tt> makes
+the top of the image transparent and the bottom opaque, with a gradual fading
+between the two.
+<p><img src="images/ImageBlended.gif" height="144" width="186">
+<h2><a name="Image Effects"></a>Image effects</h2>
+As well as arbitrary image effects that can be achieved by manipulating image
+data, SWT provides a number of pre-defined ways of creating new images based on
+existing images combined with certain styles. This is used if, for example, you
+have an image being used on a toolbar button and you wish to create a version
+that can be used to indicate that the button is disabled or that it is inactive.
+<p>To create an effect based on an existing image and a style flag use the
+constructor <tt>Image(Display display, Image image, int flag)</tt>. The flag
+argument is a static constant of either SWT.IMAGE_COPY, SWT.IMAGE_DISABLE or
+SWT.IMAGE_GRAY. Copy creates a new image based on the original but with a copy
+of its imageData, whereas Disable and Gray create a new image applying platform
+specific effects. The following code shows the Idea.jpg, together with three
+more images that we created using the style bits <img src="images/tag_1.gif" height="13" width="24">
+IMAGE_DISABLE, <img src="images/tag_2.gif" height="13" width="24">
+IMAGE_GRAY and <img src="images/tag_3.gif" height="13" width="24">
+IMAGE_COPY. To show that IMAGE_COPY creates a new image <img src="images/tag_4.gif" height="13" width="24">
+a GC is used to draw onto it that affects only the copied image, not the
+original.
+<p><tt>&nbsp;&nbsp;&nbsp; Image ideaImage = new Image(display,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getClass().getResourceAsStream(&quot;/icons/Idea.jpg&quot;);</tt><br>
+<img src="images/tag_1.gif" height="13" width="24"><tt> Image
+disabledImage&nbsp; = new Image(display,image,SWT.IMAGE_DISABLE);</tt><br>
+<img src="images/tag_2.gif" height="13" width="24"><tt> Image grayImage = new
+Image(display,image,SWT.IMAGE_GRAY);</tt><br>
+<img src="images/tag_3.gif" height="13" width="24"><tt> Image copyImage = new
+Image(display,ideaImage,SWT.IMAGE_COPY);</tt><br>
+<img src="images/tag_4.gif" height="13" width="24"><tt> GC gc = new
+GC(copyImage);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; gc.drawText(&quot;This is a copy&quot;,0,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; gc.dispose();</tt>
+<h1><img src="images/GraphicsEffects_01.JPG" height="136" width="517"></h1>
+<h1><a name="Animation"></a>GIF Animation</h1>
+Another important topic for images is understanding animation where an image can
+contain a number of frames that are animated in sequence. Image animation is
+supported by GIF images, where a single image file can contain multiple sets of
+ImageData. Web browsers support native animation, and the following image is
+made up of 15 frames showing the pen rotating and writing the words SWT beneath
+the Idea logo.
+<p><img src="images/Idea_SWT_Animation.gif" height="120" width="120">
+<p>While the web browser you're using to read this article should show the Idea_SWT_Animation.gif
+ file as a sequence with the moving pen, this is not true of native SWT controls
+ displaying the graphic. The animation must be done programmatically, and the
+ class <tt>org.eclipse.swt.examples.ImageAnalyzer</tt> shows how this can be
+ achieved. The ImageAnalyzer class can be obtained from the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.examples/">SWT
+ examples project</a> in the Eclipse CVS repository.
+<p>When an animated GIF is loaded by the ImageLoader class, each individual
+frame is a separate element in the data field array typed to ImageData[].&nbsp;
+In the animation sequence each ImageData records how many milliseconds it should
+be displayed for in the int field delayTime. The number of times the sequence
+should repeat can be retrieved from the field loader.repeatCount, a value of -1
+indicates that the animation should repeat indefinitely and
+Idea_SWT_Animation.gif has this value. When switching from one frame to the next
+there are three ways that the new frame can replace the previous one, specified
+by the int field <tt>ImageData.disposalMethod</tt>. This can take the following values
+defined in the constant class <tt>org.eclipse.swt.SWT</tt>.<br>
+&nbsp;
+<table border="1">
+ <tr>
+ <td>DM_FILL_NONE</td>
+ <td>Leave the previous image in place and just draw the image on top.&nbsp;
+ Each frame adds to the previous one.</td>
+ </tr>
+ <tr>
+ <td>DM_FILL_BACKGROUND</td>
+ <td>Fill with the background color before painting each frame. The pixel
+ value for this is defined in the field loader.backgroundPixel</td>
+ </tr>
+ <tr>
+ <td>DM_FILL_PREVIOUS</td>
+ <td>Restore the previous picture&nbsp;</td>
+ </tr>
+ <tr>
+ <td>DM_FILL_UNSPECIFIED</td>
+ <td>No disposal method has been defined</td>
+ </tr>
+</table>
+<p>To conserve on space, animated GIFs are generally optimized to just store the
+delta that needs to be applied to the previous image. In the
+Idea_SWT_Animation.gif above the 15 frames are shown below. Each frame stores a
+delta against the previous image, and this was automatically generated by the
+tool I create the animated GIF with. The disposal method for each frame is
+DM_NONE so the each image should be drawn on top of the previous one. Each
+individual ImageData element has the x and y for its top left corner, as well as
+its width and height. The overall size to use can be obtained from the fields<tt>
+loader.logicalScreenWidth</tt> and <tt>loader.logicalScreenHeight.</tt>
+<p><img src="images/AnimationFrames.gif" height="481" width="481">
+<p>To illustrate how to display an animated GIF in SWT we'll create an <img src="images/tag_1.gif" height="13" width="24">
+initial Image from the first frame and a counter to store which frame is being
+displayed. The image is drawn <img src="images/tag_2.gif" height="13" width="24">
+a paint event on a Canvas, and a GC is created <img src="images/tag_3.gif" height="13" width="24">
+that will be used to draw the subsequent frames onto the image.
+<p><tt>&nbsp;&nbsp;&nbsp; ImageLoader loader = new ImageLoader();</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;
+loader.load(getClass().getResourceAsStream(&quot;Idea_SWT_Animation.gif&quot;));</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; Canvas canvas = new Canvas(shell,SWT.NONE);</tt><br>
+<img src="images/tag_1.gif" height="13" width="24"><tt> image = new
+Image(display,loader.data[0]);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; int imageNumber;</tt><br>
+<img src="images/tag_3.gif" height="13" width="24"><tt> final GC gc = new
+GC(image);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; canvas.addPaintListener(new PaintListener(){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void paintControl(PaintEvent event){</tt><br>
+<img src="images/tag_2.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;
+event.gc.drawImage(image,0,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; });</tt>
+<p>The body of the example will create a thread that iterates through each
+frame, waiting until the <img src="images/tag_4.gif" height="13" width="24">delayTime
+has passed. For each frame the <img src="images/tag_5.gif" height="13" width="24">
+ImageData is retrieved from the loader and a temporary Image created. This is
+then drawn onto the image being displayed on the canvas, at the x and y position
+specified by the frame's ImageData. Because we created the temporary
+frameImage <img src="images/tag_7.gif" height="13" width="24"> we must
+dispose it when it's no longer being used to free up the underlying resource.
+<p><tt>&nbsp;&nbsp;&nbsp; Thread thread = new Thread(){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run(){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long currentTime =
+System.currentTimeMillis();</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int delayTime =
+loader.data[imageNumber].delayTime;</tt><br>
+<img src="images/tag_4.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;
+while(currentTime + delayTime * 10 &gt; System.currentTimeMillis()){</tt><br>
+<tt><font color="#009900">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// Wait till the delay time has passed</font></tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; display.asyncExec(new Runnable(){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run(){</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#009900">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// Increase the variable holding the frame number</font></tt><br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; imageNumber
+ = imageNumber == loader.data.length-1 ? 0 : imageNumber+1;</tt><br>
+<tt><font color="#009900">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// Draw the new data onto the image</font></tt><br>
+<img src="images/tag_5.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ImageData nextFrameData = loader.data[imageNumber];</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Image
+frameImage = new Image(display,nextFrameData);</tt><br>
+<img src="images/tag_6.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+gc.drawImage(frameImage,nextFrameData.x,nextFrameData.y);</tt><br>
+<img src="images/tag_7.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+frameImage.dispose();</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+canvas.redraw();</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; };</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; shell.open();</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; thread.start();</tt>
+<h1><a name="Scaling"></a>Scaling</h1>
+In the examples so far we have loaded an image from a file and drawn it on the
+GUI at its original size. There are times when this will not always be the case
+and you need to stretch or shrink the image, and there are two ways to do achieve
+this. The first is to use the GC to stretch and clip it, using <tt><font color="#000000">GC.drawImage(Image
+image, int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int
+dstWidth, int dstHeight)</font></tt>, and the second is to use <tt>ImageData.scaledTo(int
+width, int height) </tt>to create a new ImageData object based on scaling the
+receiver.
+<p>The following code loads the Idea.jpg image <img src="images/tag_1.gif" height="13" width="24">,
+and scales this to 1/2 and 2 times its original size <img src="images/tag_2.gif" height="13" width="24">
+using the<tt> ImageData.scaledTo(int width, int height)</tt>. The image is also
+resized using <tt>GC.drawImage(...)</tt>, and the example shows two ways to
+achieve this. The first technique<img src="images/tag_3.gif" height="13" width="24">
+is to specify the new width and height as part the paint event. This is
+potentially inefficient because the scaling must be done each time the canvas
+repaints itself. A more optimized technique is to create an image at the final
+desired size, <img src="images/tag_4.gif" height="13" width="24"> construct
+a GC over the this and then paint onto it so a permanent scaled image exists in
+the program.
+<p><font color="#000000">The end result is shown below, and both techniques
+produce almost identical results.</font>
+<p><img src="images/tag_1.gif" height="13" width="24"><tt> final Image image =
+new Image(display,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+getClass(),getResourceAsStream(&quot;Idea.jpg&quot;));</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; final int width = image.getBounds().width;</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; final int height = image.getBounds().height;</tt>
+<p><img src="images/tag_2.gif" height="13" width="24"><tt> final Image scaled050
+= new Image(display,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+image.getImageData().scaledTo((int)(width*0.5),(int)(height*0.5)));</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; final Image scaled200 = new Image(display,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+image.getImageData().scaledTo((int)(width*2),(int)(height*2)));</tt>
+<p><img src="images/tag_4.gif" height="13" width="24"><tt> final Image
+scaledGC200 = new Image(display,(int)(width*2),(int)(height*2));</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; GC gc = new GC(scaledGC200);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;
+gc.drawImage(image,0,0,width,height,0,0,width*2,height*2);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; gc.dispose();</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; canvas.addPaintListener(new PaintListener() {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void paintControl(PaintEvent e) {</tt><br>
+<img src="images/tag_3.gif" height="13" width="24"><tt>&nbsp;&nbsp;&nbsp;&nbsp;
+e.gc.drawImage(image,0,0,width,height,0,0,(int)(width*0.5),(int)(height*0.5));</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.gc.drawImage(scaled050,100,0);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.gc.drawImage(scaledGC200,0,75);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+e.gc.drawImage(scaled200,225,175);</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt><br>
+<tt>&nbsp;&nbsp;&nbsp; });</tt>
+<p><img src="images/ScaledImages_01.gif" height="300" width="425">
+<p>When to use GC scaling, and when to use <tt>ImageData.scaledTo(...)</tt>, depends
+ on the particular scenario. The GC scaling is faster because it is native, however
+ it does assume that you have a GC and an Image to work with. Using just the
+ ImageData means that you don't need to have prepared an Image (that requires
+ a native resource and requires disposing), and an ImageData can be loaded directly
+ from a graphic file (using the constructor <tt>ImageData(String fileName)</tt>
+ or <tt>ImageData(InputStream stream)</tt>). By using raw ImageData you are delaying
+ the point at which you will need native display resources, however you will
+ eventually need to create an Image from the scaled ImageData before it can be
+ rendered onto a device.
+<h1><a name="Cursor"></a>Cursor</h1>
+The final section of this article covers the class <tt>org.eclipse.swt.graphics.Cursor</tt>
+responsible for managing the operating system resource associated with the mouse
+pointer. The reason cursors are covered in an article on images is because you
+can create arbitrary cursors from images, and they illustrate how image masks
+work.
+<p>Cursors can be created in two ways, either from a pre-defined style or using
+source and mask images.
+<h2><a name="Platform cursors"></a>Platform cursors</h2>
+The list of pre-defined styles are SWT constants shown below, together with
+sample images although these will vary depending on the operating system and
+platform settings.<br>
+&nbsp;
+<table border="1">
+ <tr>
+ <td>CURSOR_APPSTARTING</td>
+ <td><img src="images/Image_cursor_appstarting.gif" height="28" width="28"></td>
+ <td>CURSOR_IBEAM</td>
+ <td><img src="images/Image_cursor_ibeam.gif" height="32" width="32"></td>
+ <td>CURSOR_SIZENE</td>
+ <td><img src="images/Image_cursor_NESW.gif" height="32" width="32"></td>
+ </tr>
+ <tr>
+ <td>CURSOR_ARROW</td>
+ <td><img src="images/Image_cursor_arrow.gif" height="32" width="32"></td>
+ <td>CURSOR_NO</td>
+ <td><img src="images/Image_cursor_not.gif" height="32" width="32"></td>
+ <td>CURSOR_SIZENESW</td>
+ <td><img src="images/Image_cursor_NESW.gif" height="32" width="32"></td>
+ </tr>
+ <tr>
+ <td>CURSOR_CROSS</td>
+ <td><img src="images/Image_cursor_cross.gif" height="32" width="32"></td>
+ <td>CURSOR_SIZEALL</td>
+ <td><img src="images/Image_cursor_sizeall.gif" height="27" width="26"></td>
+ <td>CURSOR_SIZENS</td>
+ <td><img src="images/Image_NS.gif" height="32" width="32"></td>
+ </tr>
+ <tr>
+ <td>CURSOR_HAND</td>
+ <td><img src="images/Image_cursor_hand.gif" height="32" width="32"></td>
+ <td>CURSOR_SIZEE</td>
+ <td><img src="images/Image_cursor_E.gif" height="32" width="32"></td>
+ <td>CURSOR_SIZENW</td>
+ <td><img src="images/Image_cursor_NW.gif" height="32" width="32"></td>
+ </tr>
+ <tr>
+ <td>CURSOR_HELP</td>
+ <td><img src="images/Image_cursor_help.gif" height="31" width="32"></td>
+ <td>CURSOR_SIZEN</td>
+ <td><img src="images/Image_cursor_N.gif" height="32" width="32"></td>
+ <td>CURSOR_SIZESNWSE</td>
+ <td><img src="images/Image_cursor_NW.gif" height="32" width="32"></td>
+ </tr>
+ <tr>
+ <td>CURSOR_SIZES</td>
+ <td><img src="images/Image_cursor_S.gif" height="32" width="32"></td>
+ <td>CURSOR_SIZESE</td>
+ <td><img src="images/Image_cursor_SE.gif" height="32" width="32"></td>
+ <td>CURSOR_SIZESW</td>
+ <td><img src="images/Image_cursor_SW.gif" height="32" width="33"></td>
+ </tr>
+ <tr>
+ <td>CURSOR_SIZEWE</td>
+ <td><img src="images/Image_cursor_W.gif" height="32" width="32"></td>
+ <td>CURSOR_UPARROW</td>
+ <td><img src="images/Imagecursor_uparrow.gif" height="40" width="40"></td>
+ <td>CURSOR_WAIT</td>
+ <td><img src="images/Image_cursor_busy.gif" height="32" width="32"></td>
+ </tr>
+</table>
+<p>Every Control can have a cursor associated with it, and when the mouse
+pointer moves over the control it changes to the specified cursor.&nbsp;
+Changing a cursor also affects any child controls, so if you update the cursor
+on a Shell this affects the mouse pointer for anywhere on the shell, although if
+the child control itself has an explicit cursor, or uses its own cursor such as
+an I bean for Text or Combo, this takes precedence over the parent's defined
+cursor. The following code illustrates this, by changing the shell's cursor to
+be hand cursor, and the list's cursor to a cross. When the mouse is over the
+shell (or its childButton that has no explicit cursor) it is a hand, and when it
+is over the list it is a cross.
+<p><tt>List list = new List(shell,SWT.BORDER);</tt><br>
+<tt>Button button = new Button(shell,SWT.NONE);</tt><br>
+<tt>button.setText(&quot;Button&quot;);</tt><br>
+<tt>Cursor handCursor = new Cursor(display,SWT.CURSOR_HAND);</tt><br>
+<tt>shell.setCursor(handCursor);</tt><br>
+<tt>Cursor crossCursor = new Cursor(display,SWT.CURSOR_CROSS);</tt><br>
+<tt>list.setCursor(crossCursor);</tt>
+<p><img src="images/ShellCursors.gif" height="110" width="548">
+<p>Cursors use underlying native resources and should be disposed when they are
+no longer required. In the above code this would be when the shell has been
+disposed and there are no remaining controls using either the handCursor or
+crossCursor fields.
+<h2><a name="Custom cursors"></a>Custom cursors</h2>
+As well as using a pre-defined style, a cursor can be created from images&nbsp;
+using the constructor <tt>Cursor(Device device, ImageData source, ImageData
+mask, int hotspotx, int hotspoty). </tt>The source imagedata argument is the
+graphic for the cursor shape, and the mask is used to specify transparency. The
+following example shows how to create a monochrome custom cursor, where the the
+source and mask image data have a color depth of 1 and indexed palettes with two
+colors. The ImageData’s height and width should be no larger than 32 and it
+does not necessarily have to be square, although the mask and source should be
+the same size. The hotspot is the point on the cursor that represents the
+precise location of the mouse pointer.
+<p>The source and mask image data pixels are combined to determine whether the
+cursor pixel should be white, black or transparent.<br>
+&nbsp;
+<table border="1">
+ <tr>
+ <td>Image</td>
+ <td>Mask</td>
+ <td>Cursor color</td>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>0</td>
+ <td>Transparent</td>
+ </tr>
+ <tr>
+ <td>0</td>
+ <td>0</td>
+ <td>Black</td>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>1</td>
+ <td>Black</td>
+ </tr>
+ <tr>
+ <td>0</td>
+ <td>1</td>
+ <td>White</td>
+ </tr>
+</table>
+<p>The ImageData can be loaded from files, and Eclipse itself does this for some
+of its drag and drop cursors defined in <tt>org.eclipse.ui/icons/full/dnd. </tt>You
+can also directly create and manipulate the image data within your program. The
+code sample below creates an indexed palette with two colors. The source and
+mask ImageData are 32 by 32 with a color depth of 1. The int[] for the source
+and mask define an up arrow, the 0s for the source and 1s for the mask are shown
+in bold to show how the arrow is defined with the arrays. 0 and 1 makes white
+which is the center of the arrow, 1 and 1 is black for the edge of the arrow,
+and 1 and 0 transparent for the remainder. The tip of the arrow is 16,3 so this
+is made the cursor hotspot when it is created.
+<p><tt>PaletteData paletteData = new PaletteData(new RGB[] {</tt><br>
+<tt>&nbsp;new RGB(0,0,0) , new RGB(255,255,255)</tt><br>
+<tt>});</tt><br>
+<tt>ImageData sourceData = new ImageData(32,32,1,paletteData);</tt><br>
+<tt>ImageData maskData = new ImageData(32,32,1,paletteData);</tt>
+<p><tt>int[] cursorSource = new int[] {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0,0,0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0,0,0,0,0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0,0,0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,<b>0</b>,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };</tt>
+<p><tt>int[] cursorMask = new int[] {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1,1,1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,<b>1,1,1</b>,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, };</tt>
+<p><tt>sourceData.setPixels(0,0,1024,cursorSource,0);</tt><br>
+<tt>maskData.setPixels(0,0,1024,cursorMask,0);</tt><br>
+<tt>Cursor cursor = new Cursor(display,sourceData,maskData,16,3);</tt><br>
+<tt>shell.setCursor(cursor);</tt>
+<p><img src="images/CustomCursor.gif" height="107" width="157">
+<p>To keep the code listings narrow the above sample used an <code>int[]</code>
+to define the source and mask imageData. A byte uses less memory than an
+unsigned int, so when creating custom cursors it is more efficient to use a
+byte[] instead, such as:
+<p><tt>byte[] cursorSource = new byte[] {</tt><br>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp; (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x01,
+(byte)0x00, // etc...</tt>
+<p>Custom cursors need to be disposed in just the same way as pre-defined system
+cursors, so when there is no remaining control using the cursor is must be send
+the method <tt>dispose()</tt> to free up the underlying native resource.
+<p>Although the above example is for a monochrome cursor, Eclipse 3.0 supports
+ color cursors on platforms that allow it (such as Windows). Two SWT code snippets
+ showing how to do this are here: <a href="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-swt-home/snippits/snippet118.html">snippet
+ 1</a>, <a href="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-swt-home/snippits/snippet119.html">snippet
+ 2</a>.
+<h1><a name="Conclusion"></a>Conclusion</h1>
+This article has showed how to create and manipulate SWT images.
+Underlying each Image is its ImageData that records the pixel value for each
+coordinate, and the palette that maps this to a specific color. By understanding
+ImageData it is possible to achieve effects such as transparency, alpha
+blending, animation, as well as customized cursors.
+<p><font size="-1">Java and all Java-based trademarks and logos are trademarks
+or registered trademarks of Sun Microsystems, Inc. in the United States, other
+countries, or both.</font>
+<p><font size="-1">Windows is a trademark of Microsoft corporation in the United
+States, other countries, or both.</font>
+<p><font size="-1">Other company, product, and service names may be trademarks or
+service marks of others.</font>
+</body>
+
+</html>
diff --git a/Article-SWT-images/images/AlphaImages.gif b/Article-SWT-images/images/AlphaImages.gif
new file mode 100644
index 0000000..8c87d7a
--- /dev/null
+++ b/Article-SWT-images/images/AlphaImages.gif
Binary files differ
diff --git a/Article-SWT-images/images/AnimationFrames.gif b/Article-SWT-images/images/AnimationFrames.gif
new file mode 100644
index 0000000..f1f0ffe
--- /dev/null
+++ b/Article-SWT-images/images/AnimationFrames.gif
Binary files differ
diff --git a/Article-SWT-images/images/BlendedImage.gif b/Article-SWT-images/images/BlendedImage.gif
new file mode 100644
index 0000000..98dd52e
--- /dev/null
+++ b/Article-SWT-images/images/BlendedImage.gif
Binary files differ
diff --git a/Article-SWT-images/images/BlendedImageOnSplash.gif b/Article-SWT-images/images/BlendedImageOnSplash.gif
new file mode 100644
index 0000000..b60d1fc
--- /dev/null
+++ b/Article-SWT-images/images/BlendedImageOnSplash.gif
Binary files differ
diff --git a/Article-SWT-images/images/ButonLogo.gif b/Article-SWT-images/images/ButonLogo.gif
new file mode 100644
index 0000000..a4802bf
--- /dev/null
+++ b/Article-SWT-images/images/ButonLogo.gif
Binary files differ
diff --git a/Article-SWT-images/images/CustomCursor.gif b/Article-SWT-images/images/CustomCursor.gif
new file mode 100644
index 0000000..ad8301a
--- /dev/null
+++ b/Article-SWT-images/images/CustomCursor.gif
Binary files differ
diff --git a/Article-SWT-images/images/DirectPalette.gif b/Article-SWT-images/images/DirectPalette.gif
new file mode 100644
index 0000000..18e3679
--- /dev/null
+++ b/Article-SWT-images/images/DirectPalette.gif
Binary files differ
diff --git a/Article-SWT-images/images/DirectPalette_01.gif b/Article-SWT-images/images/DirectPalette_01.gif
new file mode 100644
index 0000000..15aa624
--- /dev/null
+++ b/Article-SWT-images/images/DirectPalette_01.gif
Binary files differ
diff --git a/Article-SWT-images/images/DirectPalette_02.gif b/Article-SWT-images/images/DirectPalette_02.gif
new file mode 100644
index 0000000..f87533d
--- /dev/null
+++ b/Article-SWT-images/images/DirectPalette_02.gif
Binary files differ
diff --git a/Article-SWT-images/images/EclipseBannerPic.gif b/Article-SWT-images/images/EclipseBannerPic.gif
new file mode 100644
index 0000000..d8f03fa
--- /dev/null
+++ b/Article-SWT-images/images/EclipseBannerPic.gif
Binary files differ
diff --git a/Article-SWT-images/images/EclipseBannerPic.jpg b/Article-SWT-images/images/EclipseBannerPic.jpg
new file mode 100644
index 0000000..8aefdb8
--- /dev/null
+++ b/Article-SWT-images/images/EclipseBannerPic.jpg
Binary files differ
diff --git a/Article-SWT-images/images/Fonts.gif b/Article-SWT-images/images/Fonts.gif
new file mode 100644
index 0000000..a8b50d9
--- /dev/null
+++ b/Article-SWT-images/images/Fonts.gif
Binary files differ
diff --git a/Article-SWT-images/images/GraphicsEffects_01.JPG b/Article-SWT-images/images/GraphicsEffects_01.JPG
new file mode 100644
index 0000000..7c5eef4
--- /dev/null
+++ b/Article-SWT-images/images/GraphicsEffects_01.JPG
Binary files differ
diff --git a/Article-SWT-images/images/Idea.gif b/Article-SWT-images/images/Idea.gif
new file mode 100644
index 0000000..ad657f5
--- /dev/null
+++ b/Article-SWT-images/images/Idea.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea.jpg b/Article-SWT-images/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-SWT-images/images/Idea.jpg
Binary files differ
diff --git a/Article-SWT-images/images/IdeaTransparency.gif b/Article-SWT-images/images/IdeaTransparency.gif
new file mode 100644
index 0000000..b843e65
--- /dev/null
+++ b/Article-SWT-images/images/IdeaTransparency.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_AndSWTText.gif b/Article-SWT-images/images/Idea_AndSWTText.gif
new file mode 100644
index 0000000..e6c6f84
--- /dev/null
+++ b/Article-SWT-images/images/Idea_AndSWTText.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_EclipseText.gif b/Article-SWT-images/images/Idea_EclipseText.gif
new file mode 100644
index 0000000..7bd38fa
--- /dev/null
+++ b/Article-SWT-images/images/Idea_EclipseText.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_HalfSize.gif b/Article-SWT-images/images/Idea_HalfSize.gif
new file mode 100644
index 0000000..03fc98f
--- /dev/null
+++ b/Article-SWT-images/images/Idea_HalfSize.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original.gif b/Article-SWT-images/images/Idea_Original.gif
new file mode 100644
index 0000000..6ea61c9
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_01.gif b/Article-SWT-images/images/Idea_Original_01.gif
new file mode 100644
index 0000000..d9d5913
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_01.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_A.gif b/Article-SWT-images/images/Idea_Original_A.gif
new file mode 100644
index 0000000..da60c5a
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_A.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_B.gif b/Article-SWT-images/images/Idea_Original_B.gif
new file mode 100644
index 0000000..515683e
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_B.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_C.gif b/Article-SWT-images/images/Idea_Original_C.gif
new file mode 100644
index 0000000..6a02a38
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_C.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_D.gif b/Article-SWT-images/images/Idea_Original_D.gif
new file mode 100644
index 0000000..aa71a52
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_D.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_E.gif b/Article-SWT-images/images/Idea_Original_E.gif
new file mode 100644
index 0000000..c426103
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_E.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_F.gif b/Article-SWT-images/images/Idea_Original_F.gif
new file mode 100644
index 0000000..aa71a52
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_F.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_G.gif b/Article-SWT-images/images/Idea_Original_G.gif
new file mode 100644
index 0000000..f932395
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_G.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_H.gif b/Article-SWT-images/images/Idea_Original_H.gif
new file mode 100644
index 0000000..a4d539f
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_H.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_I.gif b/Article-SWT-images/images/Idea_Original_I.gif
new file mode 100644
index 0000000..89c13f9
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_I.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_J.gif b/Article-SWT-images/images/Idea_Original_J.gif
new file mode 100644
index 0000000..c124906
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_J.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_K.gif b/Article-SWT-images/images/Idea_Original_K.gif
new file mode 100644
index 0000000..8e5282e
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_K.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_L.gif b/Article-SWT-images/images/Idea_Original_L.gif
new file mode 100644
index 0000000..c83891c
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_L.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_M.gif b/Article-SWT-images/images/Idea_Original_M.gif
new file mode 100644
index 0000000..78a9ad9
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_M.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_N.gif b/Article-SWT-images/images/Idea_Original_N.gif
new file mode 100644
index 0000000..a7914e9
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_N.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_O.gif b/Article-SWT-images/images/Idea_Original_O.gif
new file mode 100644
index 0000000..840c88c
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_O.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_P.gif b/Article-SWT-images/images/Idea_Original_P.gif
new file mode 100644
index 0000000..8757f3a
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_P.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Original_Q.gif b/Article-SWT-images/images/Idea_Original_Q.gif
new file mode 100644
index 0000000..083da50
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Original_Q.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Pen.gif b/Article-SWT-images/images/Idea_Pen.gif
new file mode 100644
index 0000000..28f4fde
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Pen.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_SWT_Animation.gif b/Article-SWT-images/images/Idea_SWT_Animation.gif
new file mode 100644
index 0000000..3425f9c
--- /dev/null
+++ b/Article-SWT-images/images/Idea_SWT_Animation.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_Transparent_DrawnOnCanvas.gif b/Article-SWT-images/images/Idea_Transparent_DrawnOnCanvas.gif
new file mode 100644
index 0000000..dfe40d2
--- /dev/null
+++ b/Article-SWT-images/images/Idea_Transparent_DrawnOnCanvas.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_animated.gif b/Article-SWT-images/images/Idea_animated.gif
new file mode 100644
index 0000000..31262da
--- /dev/null
+++ b/Article-SWT-images/images/Idea_animated.gif
Binary files differ
diff --git a/Article-SWT-images/images/Idea_transparent.jpg b/Article-SWT-images/images/Idea_transparent.jpg
new file mode 100644
index 0000000..49065c7
--- /dev/null
+++ b/Article-SWT-images/images/Idea_transparent.jpg
Binary files differ
diff --git a/Article-SWT-images/images/ImageBlended.gif b/Article-SWT-images/images/ImageBlended.gif
new file mode 100644
index 0000000..9c2e054
--- /dev/null
+++ b/Article-SWT-images/images/ImageBlended.gif
Binary files differ
diff --git a/Article-SWT-images/images/ImageEffects.jpg b/Article-SWT-images/images/ImageEffects.jpg
new file mode 100644
index 0000000..4b8cd30
--- /dev/null
+++ b/Article-SWT-images/images/ImageEffects.jpg
Binary files differ
diff --git a/Article-SWT-images/images/Image_NS.gif b/Article-SWT-images/images/Image_NS.gif
new file mode 100644
index 0000000..c3bf995
--- /dev/null
+++ b/Article-SWT-images/images/Image_NS.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_E.gif b/Article-SWT-images/images/Image_cursor_E.gif
new file mode 100644
index 0000000..838d107
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_E.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_N.gif b/Article-SWT-images/images/Image_cursor_N.gif
new file mode 100644
index 0000000..9672f8c
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_N.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_NESW.gif b/Article-SWT-images/images/Image_cursor_NESW.gif
new file mode 100644
index 0000000..bde1bb5
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_NESW.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_NW.gif b/Article-SWT-images/images/Image_cursor_NW.gif
new file mode 100644
index 0000000..93fcda8
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_NW.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_S.gif b/Article-SWT-images/images/Image_cursor_S.gif
new file mode 100644
index 0000000..17cc476
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_S.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_SE.gif b/Article-SWT-images/images/Image_cursor_SE.gif
new file mode 100644
index 0000000..fe4213c
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_SE.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_SW.gif b/Article-SWT-images/images/Image_cursor_SW.gif
new file mode 100644
index 0000000..93461eb
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_SW.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_W.gif b/Article-SWT-images/images/Image_cursor_W.gif
new file mode 100644
index 0000000..527ec38
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_W.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_appstarting.gif b/Article-SWT-images/images/Image_cursor_appstarting.gif
new file mode 100644
index 0000000..ca83f85
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_appstarting.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_arrow.gif b/Article-SWT-images/images/Image_cursor_arrow.gif
new file mode 100644
index 0000000..fbe78f5
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_arrow.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_busy.gif b/Article-SWT-images/images/Image_cursor_busy.gif
new file mode 100644
index 0000000..62e884a
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_busy.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_cross.gif b/Article-SWT-images/images/Image_cursor_cross.gif
new file mode 100644
index 0000000..c2b609e
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_cross.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_hand.gif b/Article-SWT-images/images/Image_cursor_hand.gif
new file mode 100644
index 0000000..c715664
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_hand.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_help.gif b/Article-SWT-images/images/Image_cursor_help.gif
new file mode 100644
index 0000000..74253d9
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_help.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_ibeam.gif b/Article-SWT-images/images/Image_cursor_ibeam.gif
new file mode 100644
index 0000000..0e106d5
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_ibeam.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_not.gif b/Article-SWT-images/images/Image_cursor_not.gif
new file mode 100644
index 0000000..3135164
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_not.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_cursor_sizeall.gif b/Article-SWT-images/images/Image_cursor_sizeall.gif
new file mode 100644
index 0000000..e56652f
--- /dev/null
+++ b/Article-SWT-images/images/Image_cursor_sizeall.gif
Binary files differ
diff --git a/Article-SWT-images/images/Image_size_NE.gif b/Article-SWT-images/images/Image_size_NE.gif
new file mode 100644
index 0000000..a090be4
--- /dev/null
+++ b/Article-SWT-images/images/Image_size_NE.gif
Binary files differ
diff --git a/Article-SWT-images/images/Imagecursor_uparrow.gif b/Article-SWT-images/images/Imagecursor_uparrow.gif
new file mode 100644
index 0000000..12f8edd
--- /dev/null
+++ b/Article-SWT-images/images/Imagecursor_uparrow.gif
Binary files differ
diff --git a/Article-SWT-images/images/IntroductionRelativeIcon.gif b/Article-SWT-images/images/IntroductionRelativeIcon.gif
new file mode 100644
index 0000000..402132d
--- /dev/null
+++ b/Article-SWT-images/images/IntroductionRelativeIcon.gif
Binary files differ
diff --git a/Article-SWT-images/images/IveBeenDrawnOn.gif b/Article-SWT-images/images/IveBeenDrawnOn.gif
new file mode 100644
index 0000000..2752e16
--- /dev/null
+++ b/Article-SWT-images/images/IveBeenDrawnOn.gif
Binary files differ
diff --git a/Article-SWT-images/images/LabelCanvasTransparent.gif b/Article-SWT-images/images/LabelCanvasTransparent.gif
new file mode 100644
index 0000000..e9f3769
--- /dev/null
+++ b/Article-SWT-images/images/LabelCanvasTransparent.gif
Binary files differ
diff --git a/Article-SWT-images/images/Note.gif b/Article-SWT-images/images/Note.gif
new file mode 100644
index 0000000..f6260db
--- /dev/null
+++ b/Article-SWT-images/images/Note.gif
Binary files differ
diff --git a/Article-SWT-images/images/RedGreenImage.gif b/Article-SWT-images/images/RedGreenImage.gif
new file mode 100644
index 0000000..0aa3ba3
--- /dev/null
+++ b/Article-SWT-images/images/RedGreenImage.gif
Binary files differ
diff --git a/Article-SWT-images/images/RelativeLogo.gif b/Article-SWT-images/images/RelativeLogo.gif
new file mode 100644
index 0000000..e381591
--- /dev/null
+++ b/Article-SWT-images/images/RelativeLogo.gif
Binary files differ
diff --git a/Article-SWT-images/images/ScaledGraphics.gif b/Article-SWT-images/images/ScaledGraphics.gif
new file mode 100644
index 0000000..0519c4c
--- /dev/null
+++ b/Article-SWT-images/images/ScaledGraphics.gif
Binary files differ
diff --git a/Article-SWT-images/images/ScaledImages.gif b/Article-SWT-images/images/ScaledImages.gif
new file mode 100644
index 0000000..430b8cd
--- /dev/null
+++ b/Article-SWT-images/images/ScaledImages.gif
Binary files differ
diff --git a/Article-SWT-images/images/ScaledImages_01.gif b/Article-SWT-images/images/ScaledImages_01.gif
new file mode 100644
index 0000000..91be849
--- /dev/null
+++ b/Article-SWT-images/images/ScaledImages_01.gif
Binary files differ
diff --git a/Article-SWT-images/images/ShellCursors.gif b/Article-SWT-images/images/ShellCursors.gif
new file mode 100644
index 0000000..13c773e
--- /dev/null
+++ b/Article-SWT-images/images/ShellCursors.gif
Binary files differ
diff --git a/Article-SWT-images/images/SingleAlphaChannel.gif b/Article-SWT-images/images/SingleAlphaChannel.gif
new file mode 100644
index 0000000..fc3e1da
--- /dev/null
+++ b/Article-SWT-images/images/SingleAlphaChannel.gif
Binary files differ
diff --git a/Article-SWT-images/images/TimesFont.gif b/Article-SWT-images/images/TimesFont.gif
new file mode 100644
index 0000000..5c32e54
--- /dev/null
+++ b/Article-SWT-images/images/TimesFont.gif
Binary files differ
diff --git a/Article-SWT-images/images/TransparentIdea.gif b/Article-SWT-images/images/TransparentIdea.gif
new file mode 100644
index 0000000..38c1333
--- /dev/null
+++ b/Article-SWT-images/images/TransparentIdea.gif
Binary files differ
diff --git a/Article-SWT-images/images/javalogo.gif b/Article-SWT-images/images/javalogo.gif
new file mode 100644
index 0000000..eeeeefa
--- /dev/null
+++ b/Article-SWT-images/images/javalogo.gif
Binary files differ
diff --git a/Article-SWT-images/images/tag_1.gif b/Article-SWT-images/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-SWT-images/images/tag_1.gif
Binary files differ
diff --git a/Article-SWT-images/images/tag_2.gif b/Article-SWT-images/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-SWT-images/images/tag_2.gif
Binary files differ
diff --git a/Article-SWT-images/images/tag_3.gif b/Article-SWT-images/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-SWT-images/images/tag_3.gif
Binary files differ
diff --git a/Article-SWT-images/images/tag_4.gif b/Article-SWT-images/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-SWT-images/images/tag_4.gif
Binary files differ
diff --git a/Article-SWT-images/images/tag_5.gif b/Article-SWT-images/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-SWT-images/images/tag_5.gif
Binary files differ
diff --git a/Article-SWT-images/images/tag_6.gif b/Article-SWT-images/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-SWT-images/images/tag_6.gif
Binary files differ
diff --git a/Article-SWT-images/images/tag_7.gif b/Article-SWT-images/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-SWT-images/images/tag_7.gif
Binary files differ
diff --git a/Article-TVT/eclipse_tvt.zip b/Article-TVT/eclipse_tvt.zip
new file mode 100644
index 0000000..ec1a97a
--- /dev/null
+++ b/Article-TVT/eclipse_tvt.zip
Binary files differ
diff --git a/Article-TVT/how2TestI18n.html b/Article-TVT/how2TestI18n.html
new file mode 100644
index 0000000..8102e60
--- /dev/null
+++ b/Article-TVT/how2TestI18n.html
@@ -0,0 +1,493 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<META name="GENERATOR" content="IBM WebSphere Studio Homepage Builder V6.0.2 for Windows">
+<META http-equiv="Content-Style-Type" content="text/css">
+<title>How to Test your Internationalized Eclipse Plug-In</title>
+<LINK rel="stylesheet" href="../../default_style.css">
+</head>
+<BODY>
+<div align="right"> <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2002 International Business Machines Corp.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><IMG src="images/Idea.jpg" height="86" width="120" align="CENTER"></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">How to Test Your<BR>
+Internationalized Eclipse Plug-In</h1>
+<BLOCKQUOTE>
+<b>Summary</b>
+<br>This article shows you how to validate your internationalized product and prepares you for the types of common problems you can expect during translation testing. It includes an Eclipse plug-in that defines a <i>Properties File Compare</i> view that can help your translation testers find errors more quickly.
+<P><B>By Dan Kehn</b><br>
+IBM Eclipse ISV Enablement
+(Jumpstart) Team</P>
+ <P>August 23, 2002</P>
+ <P>Editor's note: This article reflects Eclipse release 2.0.</P>
+</blockquote>
+<H3><a name="tvt">Translation verification testing</a></H3>
+<p>You followed the internationalization steps outlined in the first article
+of this series, <A href="http://eclipse.org/articles/Article-Internationalization/how2I18n.html">How to Internationalize your Eclipse Plug-in</A>, then sent your national language (NL) resources (*.properties files,
+HTML files, icons, etc.) to a translation center. The items are returned
+and you reintegrated them into your product, but now what? To make all
+that investment in time and money worthwhile, you must verify that your
+product works correctly with the translations and that they are semantically
+correct in the context of actual product usage. This process is known as
+<i>Translation Verification Testing (TVT)</i>.</p>
+<p>TVT can be viewed from two aspects: process and technique. The <i>process</i> that you adopt will likely resemble the one that you have already put in place for your product's functional validation. But the particular <i>techniques</i> that you will employ are quite specific and these choices also impact
+the quality and efficiency of the testing process. This article will outline
+translation verification techniques and classic errors and will provide
+a tool that you can <a href="#tool">download</a> to help your translation testers work more efficiently and effectively.</p>
+<p>Ideally, the national language version (NLV) and domestic version of a product are developed and shipped at the same time, with the translation being tested before the domestic version is shipped. This is more likely the case for the second and subsequent release of an NL-enabled product. However, in the case of the first release, the domestic version may be released with the code already NL-enabled, but before the translations are available. This is often unavoidable since the language translation may take weeks or months, depending on the amount of NL material, during which it serves little purpose to delay the release of the domestic version.</p>
+<p>Subsequent releases can reduce the delay between domestic and international releases since the bulk of the translation and testing carries forward from the prior release. When planning your validation test cycle, weigh the amount of time and personnel that you expect to invest in proportion to the amount of material that was affected by translations. In general, minor changes in the translation materials are usually isolated risks, unlike functional modifications where one bad line of code can disrupt the stability of the entire system. This allows you to scale down the &quot;version two&quot; and subsequent translation efforts considerably, on the order of two-thirds to one-half your version 1.0 investment.</p>
+<H3><a name="basic_tvt">What constitutes a basic translation verification test?</a></H3>
+<p>For best results, your product should be tested in all translated languages using the operating system NL version and representative hardware for the target region. But if you must choose a subset, here are some guidelines on what and how to test your product's NL enablement:</p>
+<ul>
+<li>For single-byte character set testing (SBCS):
+ use the German language, as this language
+ is lengthy compared to English. Besides verifying
+ the proper replacement of the original language,
+ you can check for buffer overflow, message
+ truncation at display time, non-Latin-1 character
+ data entry (for example, &#233;, &#225;, &#228;, etc.), and page layout problems.<br />
+<br />
+</li>
+<li>For double-byte character set testing (DBCS): use the Japanese language,
+ as this language covers a broad range of the DBCS testing problems you
+ might find.<br />
+<br />
+</li>
+<li>For bi-directional character set testing (BIDI): use the Hebrew or Arabic languages. They are representative of the BIDI languages.</li>
+</ul>
+<p>TVT concentrates on detecting:</p>
+<ul>
+<li>Failure to use locale-sensitive functions</li>
+<li>New code problems introduced by the translation</li>
+<li>Hardcoded strings</li>
+<li>Text expansion problems</li>
+<li>Inadvertently translated strings</li>
+<li>Font changes, encoding/codepage problems</li>
+<li>Out-of-context translation errors</li>
+</ul>
+<p>Note that the scope of this article does not permit the treatment of each of these points in depth, but will cover in detail those that are less apparent.</p>
+<H4>A few words of wisdom from the TVT trenches</H4>
+<p>It is very tempting to concentrate all testing efforts on the NL-enabled version of the product in order to get it shipped with the minimum delay. But corrections introduced into the NL version could impact the domestic version. When deciding whether or not to apply a code correction, determine how crucial it is to the finished product. Your translation testers are aware of the relative negative impact of a translation defect in the context of their culture; use them to help prioritize reported problems. Do not push for a correction that could destabilize the domestic edition, however, do not postpone those that make part of the translated product unusable. Trust your judgment and come up with an "absolutely must fix" list of problems.</p>
+<H3><a name="common_problems">Testing for common problems</a></H3>
+<p>All professional function testers have their favorite problem areas on
+which they concentrate, such as bounds testing, stress testing, and common
+path testing. This is also the case for the translation test professional,
+who has mastered the language for which they test and developed a mental
+list of common problem areas. Most of these apply to all target language
+translations, but others are specific to a given language, culture, or
+country. Let's focus on the former, since these points can be addressed
+without first mastering the target language. They can also be applied early
+in the verification test phase, that is, before your translation test experts
+arrive and time and money start to slip away.</p>
+<p><IMG src="images/tip.gif" width="62" height="13" border="0"> <B>Entering accented characters</B><BR clear="">
+Windows support for the US-International Keyboard Layout is helpful for
+entering accented characters on a QWERTY keyboard (go to <B>Control Panel &gt; Keyboard &gt; Input Locales</B>). It enables so-called &quot;dead key&quot; input of accented characters. For example, typing the single quote + the letter you want to accent will result in that letter with the acute accent ('+e = &eacute;, '+a = &aacute;, etc.). Similarly, the caret (^) will add the circumflex (&acirc;), the left grave accent modifier (`) will add the grave accent (&agrave;), and the double-quote (&quot;) will add the dieresis (&auml;).<p>However, while this enables QWERTY keyboard users to enter accented characters,
+it does not assure that the equivalent accented key on a &quot;native&quot;
+keyboard will work. This is true simply because the key scan code sequences
+will be different in the two cases, permitting the possibility that an
+input error is not detected on a non-native keyboard. Input errors for
+double-byte characters are equally problematic. And while Windows does
+support double-byte character input on a non-DBCS machine, the setup is
+more intrusive than simply toggling keyboard layouts -- it involves installing
+DBCS fonts and using multi-stroke key entry.</p>
+<H4>Testing for failure to use locale-sensitive functions</H4>
+<p>This type of problem centers around the locale-specific
+display of data, covered in detail in <A href="http://eclipse.org/articles/Article-Internationalization/how2I18n.html">How to Internationalize your Eclipse Plug-in</A> and the <A href="http://java.sun.com/docs/books/tutorial/i18n/intro/index.html">Java Tutorial: Internationalization</A> trail. Developers can test this in advance by changing their regional
+settings for numbers, currency, time, and dates, then validating that these
+fields are indeed displayed using the current locale and that input is
+accepted as expected. Verify that sorted lists are correct, even if they
+include accented characters. The precise collation order may not be obvious
+to a non-native and thus will have to wait for native translation testers,
+but generally you can expect that unaccented characters and their accented
+counterparts should sort near each other. That is, a failure to use the
+<A href="http://java.sun.com/j2se/1.3/docs/api/java/text/Collator.html">Collator</A> class or its equivalent for sorting is evident
+because a binary compare will typically result
+in the accented equivalent appearing quite
+far from its counterpart (for example, a = \u0061,
+&#225; = \u00e8).</p>
+<p>The good news is that failures to use Java's locale-sensitive classes are
+less common than those problems that are listed further on in this article,
+owing perhaps to the fact that locale-dependent fields are in the minority.
+Programmers also tend to have a more intuitive appreciation for the nature
+of NL problems solved by these classes, as opposed to those introduced
+by the translation process itself. Before moving on to the more subtle
+testing concerns below, remember to consider input field entry. Verify
+that you can enter accented characters and that they are not corrupted
+by codepage transformations (or lack thereof) when re-read from permanent
+storage. Verify that double-byte characters are not corrupted (split) by
+non-Unicode aware manipulations.</p>
+<H4>Testing for new code problems introduced by the translation</H4>
+<p>It is difficult to generalize about the characteristics of this type of problem, but common threads point to the erroneous assumption that the form of NL data adheres to the programmer's native language, or that the data is not NL sensitive at all. Examples include parsing text under the assumption that the separator will be a period or space, or inadvertently using NL data to define or modify character set-sensitive data like database column names without coding appropriate user entry field validation.</p>
+<H4>Testing for hardcoded strings</H4>
+<p>Hardcoding a string is surely the &quot;granddaddy&quot; of all TVT errors, outnumbering all others by far. There are two basic approaches to ferreting them out: the black-box approach and the white-box approach. The <i>white-box approach</i> relies on scanning the Java source code, XML, and HTML looking for hardcoded strings. The <b>External Strings</b> wizard of the Eclipse Workbench Java Development Tooling (JDT) automates the Java source code scanning process.</p>
+<p>The <i>black-box approach</i> is manually intensive, as it relies on executing testcase scenarios that display all the product's user interface elements (views, menus, dialogs, etc.) on a non-US English workstation to a tester who validates all text is translated.</p>
+<p>There is, however, a <i>gray-box approach</i> that falls somewhere in between. It involves translating all the text into an easily recognizable benign string of the same number of characters and words. For example, the information message below:
+</p>
+<blockquote>
+ Import resources from the local file system
+</blockquote>
+<p>becomes</p>
+<blockquote>****** ********* **** *** ***** **** ******</blockquote>
+<p>If your product test team was wise enough to use an automated test tool, their scripts can be modified to detect the cases where strings are hardcoded and were not detected by the black-box approach. These omissions could be because of untranslated third-party products that your product uses, composed strings, etc. If you don't have the benefit of automated testing, this approach will still simplify manual hardcoded string detection. Furthermore, it has the advantage of requiring no specific language skills. Some testers prefer the "Pig Latin" approach. Our example above would then be:</p>
+<blockquote>
+ Importway esourcesray omfray ethay ocallay ilefay ystemsay
+</blockquote>
+<p>This has the advantage of retaining some level of readability while making it equally clear what text has not been translated.</p>
+<H4>Testing for inadvertently translated strings</H4>
+<p>The gray-box approach is perhaps the most rigorous method to validate that all strings have been translated. But it also is helpful in detecting that there are not any inadvertent translations. Consider, for example, an extract of the properties file <code>org.eclipse.jdt.internal.formatter\options.properties</code> below:</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code>style.reuseExistingLayout.number=8
+style.reuseExistingLayout.category=Style
+style.reuseExistingLayout.name=&amp;Reuse existing layout
+style.reuseExistingLayout.possibleValues=2|Reuse|Do not reuse
+style.reuseExistingLayout.description=If the user formatted code a certain way, ...</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>Translating all the apparent user text to asterisks would include the key and value below:</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code>style.reuseExistingLayout.possibleValues=2|*****|** *** *****</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>While this may not cause a run-time bug per se, it is not evident that these values actually represent the key used to persist the user's preference (in other words, "Reuse|Do not reuse" are never displayed to the end user). If the translator unknowingly translated two terms that are different in English into the same word in their target language, it is possible that changing one preference would overwrite an unrelated preference.</p>
+<p>That is the risk of mixing the use of properties files for translatable text and run-time parameterization. This is certainly a valid programming technique, but it requires that the translator be aware of it, at a minimum by adding comments to the properties files itself. Better still, use values that are clearly programmatic. Returning to our example:</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code>style.reuseExistingLayout.possibleValues=2|REUSE_LAYOUT_YES|REUSE_LAYOUT_NO</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>Here it is obvious to both the translator and their translation tools that the values after the equal sign should not be modified.</p>
+<H4>Testing for text expansion problems</H4>
+<p>The average text expansion of English to several European languages is around 40%. Consider these examples. First, one English word translated to two German words:</p>
+<blockquote>
+ Restart -&gt; Neu starten
+</blockquote>
+<p>Not a problem, an expansion of seven characters to eleven. But here's a surprise. Two English words translated to one (long) German word:</p>
+<blockquote>
+ Counter Logs -&gt; Leistungsindikatorenprotokolle
+</blockquote>
+<p>Ouch, an expansion of 12 characters to 30!
+While the German language is well recognized
+for text expansion relative to English, it
+is not the only one. Consider the Acadamie
+Fran&#231;aise's official French language
+equivalent of "air bag": <i>coussin gonflable de s&#233;curit&#233;</i>. To address this in development before a
+translation is available, you can modify
+the text of your properties files to double
+their lengths. To make it obvious that this
+is a testcase, a simple script can double
+each word. Taking our example from above
+once again:</p>
+<blockquote>
+ Import import resources resources from from the the local local file file system system
+</blockquote>
+<p>Now rerun your application and verify that the page layouts are still appropriate, that text is not truncated, etc. If a page is resizable, resize it from each of the four corners. Recognize that even this test has a weakness, since it assumes that phrases will include spaces and can word wrap; this is not true for some non-Latin character based languages.</p>
+<p>For those cases where the layout demands that the translated text be minimal, document the limit in the original language file. For example, adding a comment:</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code># translation note: Text below is limited to approximately 60
+# characters, see testcase 1.13 to validate</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>Here the translator is alerted to the fact that verbosity is not allowed. The testcase reference will allow the translation tester to validate that the text is not truncated, because the choice of letters affects the final text width in proportional fonts. Translators may also need the ability to specify layout constraints, such as a column width in a table, especially those that are not resizable:</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code># translation note: Width in pixels of the &quot;Completed&quot;
+# column. The text is a 'C' in US English, it should
+# be as short as possible in the translation.
+taskList.completedHeading=C
+taskList.completedHeadingWidth=10</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>Here the translator or translation tester can provide an optimal size without resorting to unnaturally terse translations, while taking into consideration the default fonts associated with the language and operating system.</p>
+<p>
+<b>Note:</b> Text truncation implies the inability to access the complete text, even employing alternative user interface mechanisms like scrolling, displaying another dialog, or providing a "More &gt;&gt;" button. Clearly text truncation with no means to visualize it is more serious than simply requiring that the user scroll the viewing area. For these reasons and for reasons of accessibility, avoid creating text areas that cannot scroll or wrap.</p>
+<H4>Testing for font size changes</H4>
+<p>Font pixel size for different operating systems and languages can change in both height and width. The majority of these cases are handled by the base widgets; for example, a text field will resize automatically to accommodate a larger font, or autoscroll if necessary. But if you draw your own graphics and text, the appropriate system metrics must be queried in order to avoid arbitrary text truncation.</p>
+<p>This is especially true for double-byte language
+fonts, where the minimum height is generally
+larger than that of single-byte language
+fonts. As an aside, handling font size changes
+is <i>not required</i> for <A href="http://www.section508.gov">Section 508</A> accessibility compliance, but it is surely
+appreciated by those that wish to choose
+a larger font because of a visual impairment.
+You can perform a quick test on Windows by
+increasing the size of the default font and
+restarting your machine (<b>Display &gt; Settings &gt; Advanced &gt;
+General &gt; Font Size &gt; Large Fonts</b>). You will be surprised how many of the
+applications you use everyday fail this simple
+test. Don't follow their example!</p>
+<H4>Testing for out-of-context translation errors</H4>
+<p>One aspect that directly impacts the quality of these translations is the clarity of the context. This is readily apparent when translating property files:</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code>eojMessage = {0} at {1}</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>This example is fictitious, but it demonstrates the point. What is the context in which this message is displayed? The first parameter could be the date and the second the time. But maybe the first is a resource and the second is the URL of the server where it was stored. Without a comment to indicate, the translator will simply translate it literally to the most likely choice.</p>
+<p>Here is an actual example from the Eclipse Workbench:</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code>WorkbenchPreference.autobuild =
+ Perform build automatically on resource modification</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>In this context, "on" means "when a resource is modified." This may be clear to a Workbench user, but the first translation is done by a central organization without specific product knowledge. Since "resource modification" means little to them, "on" could be interpreted literally, as in, "on top of," or quite narrowly in a programmatic sense, as in, "as a super task."</p>
+<p>Consider adding notes to the property files so translators will know the context of a given message. It is especially important in those cases where the subject is implied, since many languages must explicitly know the subject in order to choose the appropriate adjective and verb forms. Here are a few messages from the JDT that are displayed as markers within the Java source code editor, augmented with example translator-friendly comments:</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code># Note: The error messages below are displayed in the Java source
+# editor with an &quot;X&quot; next to the offending line. They are also
+# displayed in the Task List with a reference back to the file.
+# Double-clicking the error in the Task List will open the editor
+# and scroll to the corresponding line number.
+
+# The subject is a method, i.e., &quot;Method must return a result of type 'x'&quot;
+108 = Must return a result of type {0}
+
+# &quot;Variable (or field) must provide either dimension expressions...
+159 = Must provide either dimension expressions or an array initializer
+
+# &quot;Class must implement the inherited abstract method 'x'&quot;
+400 = Must implement the inherited abstract method {0}
+
+# &quot;This class overrides deprecated method from 'its superclass'&quot;
+412 = Overrides deprecated method from {0}</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>Nobody expects a developer writing such a message to be aware of the subtle interpretations of a phrase. The examples above demonstrate that even given the developer's best efforts, there is no substitute for translation testing.</p>
+<H4>Testing for missed translations</H4>
+<p>In addition to performing the TVT on the running version of the translated product, you can use the <i>Property Files Compare</i> view to speed up the testing cycle and detect common errors, resulting in a higher quality NL version of your product.</p>
+<p>Briefly, the objectives of the tool are two-fold:</p>
+<ul>
+<li>Allow a speedy verification of the translation by displaying the content of the translated file side-by-side with its corresponding original language file. This is an "out of context" verification, but gives the testers a chance to rapidly review the translation and guarantee that 100% of the files are translated and converted to the correct codepage.</li>
+<li>Ensure your NL product, once released, will not throw an exception due to missing keywords from the translated files.</li>
+</ul>
+<p>Remember there is a gap of time between the moment the original source language files were sent for translation and the time TVT started. It is during this period that the code -- as well as some of the original source language files -- could have changed. New keywords may have been added to them that are not in the translation, resulting in a run-time error.</p>
+<p>To resolve this situation, use this view to compare side-by-side the source language files against their corresponding translated files. The tool flags missing keywords and gives you a chance to correct the files.</p>
+<H3><a name="summary">Summary</a></H3>
+<p>It is both costly and time-consuming to enable
+your product to the world market. But if
+worldwide software sales are any indicator,
+ignoring this requirement carries its own
+costs. With the how-to presented in the <A href="http://eclipse.org/articles/Article-Internationalization/how2I18n.html">first
+article of this series</A> and the testing hints
+and tools in this one, you should be on your
+way to <i>pr&#233;senter votre produit en n'importe
+quelle langue comme si c'&#233;tait sa
+langue maternelle</i> (presenting your product in any language
+as if it were its native language)!</p>
+<H3><a name="tool">Appendix A: Tool for comparing property files side-by-side</a></H3>
+<p>Translation verification testing involves a language expert actually executing the product in order to correct the previously discussed translation errors. This process is time consuming, sometimes tedious, and error prone. As a means to alleviate some of these costs, improve productivity, and increase the quality of the final result, I wrote a simple view that displays two property files side-by-side, using run-time formatting and parameter substitution. This enables the language expert to quickly validate the initial translation and see the messages formatted in the same fashion as in the running product itself. <A href="eclipse_tvt.zip">Download the code</A> for this tool.</p>
+<p>More precisely, here are the problems that the <i>Property Files Compare</i> tool addresses:</p>
+<ul>
+ <li>Enables the language expert to quickly validate the initial translation.
+ Remember, the first translation is generally done "in bulk" by translators
+ who have no product experience. They employ translation tools that help assure
+ the consistency of the translation, but this is no substitute for on-site
+ verification. Translation verification testers are aware of the product metaphors
+ and are capable of quickly reviewing translations in a side-by-side fashion
+ in order to catch obvious gaffes.<br />
+ <br />
+ </li>
+ <li>Visualizes the messages formatted in the same fashion as in the running
+ product itself, including parameter substitution. This helps detect common
+ errors like missing or extraneous quotes, missing closing braces, etc.
+ While most of these errors will show up in the source language, others
+ are introduced during translation. Extraneous or missing single quotes
+ are a notorious example, even in English (for example, &quot;The process
+ didnt complete&quot; has a missing apostrophe, &quot;The process didn''t
+ complete&quot; has an extra apostrophe). See <a href="#appendix_b">One
+ or two quotes?</a> below for more details.<br />
+ <br />
+ </li>
+ <li>Assures that the messages are displayable. As simple as this might sound,
+ encoding/conversion errors are not uncommon (refer to <A href="http://eclipse.org/articles/Article-Internationalization/how2I18n.html">How
+ to Internationalize your Eclipse plug-in</A> for details). A quick display
+ of a properties file in the actual run-time environment is a good "sanity"
+ check.<br />
+ <br />
+ </li>
+ <li>Assures that all the keys defined in the source language exist in the target
+ language property file, and visa-versa. Mismatches occur when keys from source
+ language are added or deleted and the appropriate correction is not propagated
+ to the target language files, as well as when keys are inadvertently deleted
+ from the target language files.<br />
+ <br />
+ </li>
+ <li>Flags untranslated text.</li>
+</ul>
+<p>Once its plug-in is installed, open it by selecting <b>Perspectives &gt; Show View &gt; Java &gt; Properties Files Compare</b>. Then enter the name of the directories
+containing your source and target languages;
+pressing Enter while the <i>Source Language Directory</i> or <i>Target Language Directory</i> field has the focus will start a search
+for all *.properties files. Selecting one
+of the property files on the left will attempt
+to auto-select its corresponding target on
+the right by matching the same partial file
+specification, starting at the last occurrence
+of "eclipse" in the directory path.</p>
+<p>
+<b>Figure 1. Properties file comparison view</b><br />
+<IMG src="images/tool.jpg" width="681" height="524" alt="Properties file comparison view"></p>
+<p>For example, if the Eclipse Workbench is installed in <code>x:\eclipse2.0</code>, the Eclipse install root is a subdirectory directly beneath it called, unsurprisingly, <code>eclipse</code>. The view assumes that you (a) maintain native language property files in separate subdirectory trees by language, or that (b) the original language (source) files have no country suffix and the target files have a suffix based on the country code returned by the operating system. For example:
+</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code>(a) Languages separated by directory
+x:\english\eclipse\plugins\org.eclipse.core.jdt\plugin.properties
+x:\french\eclipse\plugins\org.eclipse.core.jdt\plugin.properties
+x:\german\eclipse\plugins\org.eclipse.core.jdt\plugin.properties
+
+(b) Languages separated by country-specific file suffix
+x:\eclipse\plugins\org.eclipse.core.jdt\plugin.properties
+x:\eclipse\plugins\org.eclipse.core.jdt\plugin_fr.properties
+x:\eclipse\plugins\org.eclipse.core.jdt\plugin_de.properties</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>So entering <code>x:\english</code> in the first directory field and pressing
+Enter will initiate a search starting from
+the English subdirectory. Entering <code>x:\french</code> in the second directory field will initiate a search starting from the French subdirectory. Selecting a properties file found in the list of <i>Source Language</i> list will automatically select the corresponding file in the <i>Target Language</i> list, and display their contents sorted by key.</p>
+
+<p>
+<b>Note:</b> Another tool, called <A href="http://www.alphaworks.ibm.com/tech/rbmanager">RBManager</A>, is available on <A href="http://www.alphaworks.ibm.com/">IBM's alphaWorks site</A>. According to the description there, &quot;<i>RBManager</i> (Resource Bundle Manager) is a tool that automates many of the tedious tasks associated
+with creating, updating, and managing resource
+bundle files; it also prevents most common
+mistakes from being propagated across bundles.
+This tool is helpful for development teams
+working on internationalized applications
+and Web-based services."</p>
+<p>RBManager doesn't include a side-by-side property files view (yet?), however
+ it definitely helps manage the many resource files that are typically involved
+ in a translation. RBManager includes good documentation and a tutorial.</p>
+<H3><A name="appendix_b">Appendix B: One or two quotes?</A></H3>
+<p>How you plan to format your property file messages has an impact on the way that single quotes should be entered, that is, are they doubled or entered only once. To illustrate the problem, consider the code below:</p>
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td>
+ <pre><code>package com.ibm.jumpstart.messageformattest;
+import java.text.MessageFormat;
+
+public class MessageFormatTest {
+ public static void main(String[] args) {
+ String msg1 = &quot;This is a ''{0}'' program and it''s not ready for production.&quot;;
+ String msg2 = &quot;This is a beta program and it's not ready for production.&quot;;
+ String msg3 = &quot;This is a beta program and it's not ready for {0}.&quot;;
+
+ System.out.println(MessageFormat.format(msg1, new String[] {&quot;beta&quot;}));
+ System.out.println(MessageFormat.format(msg2, new String[0]));
+ System.out.println(msg2);
+
+ System.out.println(MessageFormat.format(msg3, new String[] {&quot;production&quot;}));
+ System.out.println(msg3);
+ }
+}</code></pre>
+ </td>
+ </tr>
+
+</table>
+<p>
+The output is below:
+<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#CCCCCC">
+
+ <tr>
+ <td><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This is a 'beta' program and it's not ready for production.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This is a beta program and its not ready for production.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This is a beta program and it's not ready for production.<br>
+<IMG src="images/tag_4.gif" height="13" width="24" align="CENTER">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This is a beta program and its not ready for {0}.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This is a beta program and it's not ready for {0}.
+</code>
+ </td>
+ </tr>
+
+</table>
+<p>The fourth line (<IMG src="images/tag_4.gif" width="24" height="13">) is particularly
+ troubling, because not only is the apostrophe missing, but so is the substitution
+ parameter! These differences stem from the fact that <A href="http://java.sun.com/j2se/1.3/docs/api/java/text/MessageFormat.html">MessageFormat</A>
+ expects a quote to be entered twice if it is to be included in the result. No
+ problem, but what if some programmers use MessageFormat, some write their own
+ version for parameter substitution, and others don't use it at all unless there
+ are substitution parameters? The translator obviously does not know what code
+ will manipulate the translated text, so they must know how to enter required
+ single quotes / apostrophes.</p>
+<p>Here are the conventions that were adopted for required quotes during the Eclipse Workbench version 1.0 TVT:</p>
+<ul>
+<li>If there are no substitution parameters, enter only one quote </li>
+<li>If there are any substitution parameters (like {0}), enter two quotes</li>
+</ul>
+<p>This is in acceptance of the observation that practically all programmers used MessageFormat only for those cases where there were substitution parameters. To avoid this programming inconsistency, version 2.0 of the Eclipse JDT includes an <B>Externalize Strings</B> wizard to help centralize message retrieval and parameter substitution. Consider adopting this strategy, or systematically using MessageFormat so your translators will only have one rule for required quotes.</p>
+<DL>
+ <DT>This potential stumbling block is noted in the <A href="http://java.sun.com/j2se/1.3/docs/api/java/text/MessageFormat.html">MessageFormat</A>
+ documentation:
+</DL>
+<DL>
+ <DD>&quot;The rules for using quotes within message format patterns unfortunately have shown to be somewhat confusing. In particular, it isn't always obvious to localizers whether single quotes need to be doubled or not. Make sure to inform localizers about the rules, and tell them (for example, by using comments in resource bundle source files) which strings will be processed by MessageFormat. Note that localizers may need to use single quotes in translated strings where the original version doesn't have them.&quot;</DD>
+</DL>
+<h3><A name="author">About the author</A><BR>
+</H3>
+<P><B>Dan Kehn</B> is a Senior Software Engineer at IBM in Research Triangle Park, North
+Carolina. His interests in object-oriented programming go back to 1985,
+long before it enjoyed the acceptance it has today. He has a broad range
+of software experience, having worked on development tools like VisualAge
+for Smalltalk, operating system performance and memory analysis, and user
+interface design. Dan worked as a consultant for object-oriented development
+projects throughout the U.S. as well as four years in Europe. His recent
+interests include object-oriented analysis/design, programming tools, and
+Web programming with the WebSphere Application Server. Last year he joined
+the Eclipse Jumpstart team, whose primary goal is to help ISVs to create
+commercial offerings based on the Eclipse Platform. In another life, Dan
+authored several articles about diverse Smalltalk topics like meta-programming,
+team development, and memory analysis. You can find them on <A href="http://www.ibm.com/software/ad/smalltalk/discussion/index.html">Eye on SmallTalk</A>.
+
+</BODY>
+</html>
diff --git a/Article-TVT/images/Idea.jpg b/Article-TVT/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-TVT/images/Idea.jpg
Binary files differ
diff --git a/Article-TVT/images/linux_only.gif b/Article-TVT/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-TVT/images/linux_only.gif
Binary files differ
diff --git a/Article-TVT/images/tag_1.gif b/Article-TVT/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-TVT/images/tag_1.gif
Binary files differ
diff --git a/Article-TVT/images/tag_2.gif b/Article-TVT/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-TVT/images/tag_2.gif
Binary files differ
diff --git a/Article-TVT/images/tag_3.gif b/Article-TVT/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-TVT/images/tag_3.gif
Binary files differ
diff --git a/Article-TVT/images/tag_4.gif b/Article-TVT/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-TVT/images/tag_4.gif
Binary files differ
diff --git a/Article-TVT/images/tag_5.gif b/Article-TVT/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-TVT/images/tag_5.gif
Binary files differ
diff --git a/Article-TVT/images/tag_6.gif b/Article-TVT/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-TVT/images/tag_6.gif
Binary files differ
diff --git a/Article-TVT/images/tag_7.gif b/Article-TVT/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-TVT/images/tag_7.gif
Binary files differ
diff --git a/Article-TVT/images/tip.gif b/Article-TVT/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-TVT/images/tip.gif
Binary files differ
diff --git a/Article-TVT/images/tool.jpg b/Article-TVT/images/tool.jpg
new file mode 100644
index 0000000..f783ff7
--- /dev/null
+++ b/Article-TVT/images/tool.jpg
Binary files differ
diff --git a/Article-TVT/images/tryit.gif b/Article-TVT/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-TVT/images/tryit.gif
Binary files differ
diff --git a/Article-TVT/images/win_only.gif b/Article-TVT/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-TVT/images/win_only.gif
Binary files differ
diff --git a/Article-Table-viewer/TableViewerExamplePlugin.zip b/Article-Table-viewer/TableViewerExamplePlugin.zip
new file mode 100644
index 0000000..4fea214
--- /dev/null
+++ b/Article-Table-viewer/TableViewerExamplePlugin.zip
Binary files differ
diff --git a/Article-Table-viewer/images/Idea.jpg b/Article-Table-viewer/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Table-viewer/images/Idea.jpg
Binary files differ
diff --git a/Article-Table-viewer/images/linux_only.gif b/Article-Table-viewer/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Table-viewer/images/linux_only.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tableViewer.gif b/Article-Table-viewer/images/tableViewer.gif
new file mode 100644
index 0000000..79e7d4b
--- /dev/null
+++ b/Article-Table-viewer/images/tableViewer.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tag_1.gif b/Article-Table-viewer/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Table-viewer/images/tag_1.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tag_2.gif b/Article-Table-viewer/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Table-viewer/images/tag_2.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tag_3.gif b/Article-Table-viewer/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Table-viewer/images/tag_3.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tag_4.gif b/Article-Table-viewer/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Table-viewer/images/tag_4.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tag_5.gif b/Article-Table-viewer/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Table-viewer/images/tag_5.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tag_6.gif b/Article-Table-viewer/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Table-viewer/images/tag_6.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tag_7.gif b/Article-Table-viewer/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Table-viewer/images/tag_7.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tip.gif b/Article-Table-viewer/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Table-viewer/images/tip.gif
Binary files differ
diff --git a/Article-Table-viewer/images/tryit.gif b/Article-Table-viewer/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Table-viewer/images/tryit.gif
Binary files differ
diff --git a/Article-Table-viewer/images/win_only.gif b/Article-Table-viewer/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Table-viewer/images/win_only.gif
Binary files differ
diff --git a/Article-Table-viewer/table_viewer.html b/Article-Table-viewer/table_viewer.html
new file mode 100644
index 0000000..b6fdf41
--- /dev/null
+++ b/Article-Table-viewer/table_viewer.html
@@ -0,0 +1,500 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Building and delivering a table editor with SWT/JFace</title>
+<link rel="stylesheet" href="../default_style.css">
+</head>
+
+<body link="#0000ff" vlink="#800080" bgcolor="#FFFFFF">
+
+<div align="right">
+ &nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright © 2003
+ Mirasol Op'nWorks inc.</font>
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP" colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="images/Idea.jpg" align="CENTER" width="120" height="86"></h1>
+</div>
+<p>&nbsp;</p>
+<h1 align="CENTER">Building and delivering a table editor with SWT/JFace</h1>
+<blockquote>
+ <b>Summary</b><br>
+ The JFace API provides several classes that can be used to build editable table
+ views. In this article, we present a fairly extensive example that exercises
+ the JFace and SWT classes needed to implement a table with cell editors for
+ check-boxes, free text and combo-boxes. We also show how to package and deliver
+ the classes into a stand-alone (non-Eclipse) Java application.
+ <p><b>By Laurent Gauthier, Mirasol Op'nWorks, <a href="mailto:lgauthier@opnworks.com">lgauthier@opnworks.com<br>
+ </a></b>July 3<font size="-1">, 2003</font></p>
+</blockquote>
+<hr width="100%">
+<h2>Introduction</h2>
+<p>Users of business software take many things for granted from modern GUI
+applications. Their reference consists of office automation software such as
+word processing and spreadsheet applications and they rightly expect other
+programs to exhibit similar look and feel. They certainly do not want to hear
+that because the application was written using this or that technology, they
+should not expect the same behavior from the application as the one they are
+used to. They do not understand, do not want to understand and should not even
+have to be confronted with such an issue. The Eclipse team and more
+specifically, the folks who worked on the SWT and JFace APIs fully understand
+this and have done a tremendous job in providing Java developers with a toolset
+that can be used to quickly build robust native applications. In this article,
+we examine a small part of the SWT/JFace API, namely the constructs that allow
+us to program a table with editable cells and sortable columns.</p>
+<p>The example we use for this article is a task list editor. It is by no means
+a truly useful application and the GUI design was driven essentially by the need
+to provide examples of the use of cell editors. The code presented here can be a
+useful starting point for projects that need the functionality of a table view
+with editable cells.</p>
+<h2>Installation</h2>
+<p>The project and code described herein was designed and implemented as a standalone
+ SWT/JFace application. In other words, it was meant to run outside the Eclipse
+ environment per say although it has dependencies on some core Eclipse APIs.
+ I have wrapped the main class in a plug-in so that it can be conveniently installed
+ into Eclipse. This also shows how one can build an application that is meant
+ to run both as a standalone Java application and as an Eclipse extension. But
+ that could be the subject of another article.</p>
+<p><img src="images/tryit.gif" width="61" height="13">The reader can install the
+executable and source code by extracting the contents of the <a href="TableViewerExamplePlugin.zip">TableViewerExamplePlugin.zip</a>
+file into the <i>plugins</i> directory of an Eclipse 2.1 installation and start
+(or restart) Eclipse.</p>
+<h2>Running the example</h2>
+<p><img src="images/win_only.gif" width="49" height="13">To run the example,
+simply open the sample view through the following menu item: Window -&gt; Show
+View -&gt; Other... -&gt; Examples -&gt; TableViewerExample view. You may also
+want to import the Java source code into an Eclipse project. To run the example
+as a standalone Java application inside the Eclipse workbench, simply run the <code>TableViewerExample</code>
+class making sure you specify the following VM runtime variable:</p>
+<pre><font color="#4444cc">-Djava.library.path=ECLIPSE_HOME\plugins\org.eclipse.swt.win32_2.1.0\os\win32\x86</font></pre>
+<p>where ECLIPSE_HOME is your eclipse home installation folder (the above is for
+Eclipse v2.1 on Win32, for other versions and other platforms, the path and file
+name will be different).</p>
+<h2>The Task List Editor</h2>
+<p>A Task List editor window is shown below. The first column is used to
+indicate whether the task is completed or not. The other columns and buttons are
+self explanatory. The user can toggle the &quot;completed&quot; cell, edit in
+place the &quot;Description&quot; and &quot;% Complete&quot; cells, change the
+&quot;Owner&quot; cell through the use of a combo box, change the sort order by
+clicking on a column header and add and delete tasks by clicking on the
+corresponding button.</p>
+<p><img src="images/tableViewer.gif" width="630" height="292"></p>
+<h2>The ExampleTask and ExampleTaskList classes</h2>
+<p>The example uses two simple classes that play the role of the model in our
+MVC design. The <code>ExampleTask</code> is a simple business object
+representing a task with getters and setters for the following <code></code>properties:</p>
+<pre> <font color="#4444cc">private boolean completed = false;
+ private String description = &quot;&quot;;
+ private String owner = &quot;?&quot;;
+ private int percentComplete = 0;</font></pre>
+<p>The <code>ExampleTaskList</code> is used to hold, as the name implies, a
+collection of <code>ExampleTask</code> instances. It also knows about the list
+of possible task owners.</p>
+<h2>Building the TableViewerExample class</h2>
+<p>Here we get into the substance of our subject matter: how do we go about
+building and implementing the view and behavior described above? We do this with
+a combination of SWT and JFace constructs. SWT provides an interface to the
+native platform widgetry while JFace provides a high-level abstraction to build
+rich GUIs. In other words, we could implement the example by using only SWT
+objects but that would represent much more work and more complicated code.</p>
+<p>So lets start by examining our <code>TableViewerExample</code> class. It
+inherits from <code>Object</code> and the <code>main()</code> method simply
+creates a new instance, calls the <code>open()</code> method on the window and
+runs until the user tells the window to close itself.</p>
+<pre> <font color="#4444cc">/**
+ * Main method to launch the window
+ */
+ public static void main(String[] args) {
+<img src="images/tag_1.gif" width="24" height="13"> Shell shell = new Shell();
+ shell.setText(&quot;Task List - TableViewer Example&quot;);
+
+ // Set layout for shell
+ GridLayout layout = new GridLayout();
+ shell.setLayout(layout);
+
+ // Create a composite to hold the children
+<img src="images/tag_2.gif" width="24" height="13"> Composite composite = new Composite(shell, SWT.NONE);
+<img src="images/tag_3.gif" align="baseline" width="24" height="13"> TableViewerExample tableViewerExample = new TableViewerExample(composite);
+
+ // Open the shell and run until a close event is detected
+ shell.open();
+ tableViewerExample.run(shell);
+ }</font></pre>
+<p>We first <font color="#4444cc"><img src="images/tag_1.gif" width="24" height="13"></font>
+create and configure a SWT <code>Shell</code> object. Then, <font color="#4444cc"><img src="images/tag_2.gif" width="24" height="13"></font>
+we create a <code>Composite</code> to hold the widgets (table and buttons) and <font color="#4444cc"><img src="images/tag_3.gif" align="baseline" width="24" height="13"></font>
+instantiate our class passing the composite to the constructor. We could have
+done things differently but passing the composite to the constructor makes it
+easy to wrap our class in an Eclipse view for example.</p>
+<p>Adding widgets to the composite is done in the <code>addChildControls()</code>
+ method. The more interesting part of this method is in the following code fragment:</p>
+<pre> <font color="#4444cc">// Create the table
+<img src="images/tag_1.gif" width="24" height="13"> createTable(composite);
+
+ // Create and setup the TableViewer
+<img src="images/tag_2.gif" width="24" height="13"> createTableViewer();
+<img src="images/tag_3.gif" align="baseline" width="24" height="13"> tableViewer.setContentProvider(new ExampleContentProvider());
+ tableViewer.setLabelProvider(new ExampleLabelProvider());
+ // The input for the table viewer is the instance of ExampleTaskList
+ tableViewer.setInput(taskList);</font></pre>
+<p>We first <font color="#4444cc"><img src="images/tag_1.gif" width="24" height="13"></font>
+create a <code>org.eclipse.swt.widgets.Table</code> and then <font color="#4444cc"><img src="images/tag_2.gif" width="24" height="13"></font>
+create a <code>org.eclipse.jface.viewers.TableViewer</code> on that table. We
+then <font color="#4444cc"><img src="images/tag_3.gif" align="baseline" width="24" height="13"></font>
+set the content provider, label provider and input for the <code>TableViewer</code>.
+We will come back to these later. Let's first look at the <code>createTable()</code>
+method. It starts by instantiating a <code>Table</code> object and sets its
+parent, style and layout attributes. It then creates each of the four columns in
+turn. As an example, the second column is created with the following fragment:</p>
+<pre> <font color="#4444cc">// 2nd column with task Description
+<img src="images/tag_1.gif" width="24" height="13"> column = new TableColumn(table, SWT.LEFT, 1);
+ column.setText(&quot;Description&quot;);
+ column.setWidth(400);
+ // Add listener to column so tasks are sorted by description when clicked
+<img src="images/tag_2.gif" width="24" height="13"> column.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent e) {
+ tableViewer.setSorter(
+ new ExampleTaskSorter(ExampleTaskSorter.DESCRIPTION));
+ }
+ });</font></pre>
+<p>Here, we <img src="images/tag_1.gif" align="CENTER" width="24" height="13">
+create a <code>TableColumn</code> object for the <code>Table</code>, set some of
+its attributes and <img src="images/tag_2.gif" align="CENTER" width="24" height="13">
+add a selection listener that sets the sorter object for the <code>TableViewer</code>
+object when the column header is clicked. We will look at column sorting later.</p>
+<p>The rest of the method is concerned with setting up the other columns using
+the same approach. The creation of the <code>TableViewer</code> is also of
+particular interest to us. The method is outlined below (less important code was
+omitted):</p>
+<pre><font color="#4444cc"> /**
+ * Create the TableViewer
+ */
+ private void createTableViewer() {
+<img src="images/tag_1.gif" align="baseline" width="24" height="13"> tableViewer = new TableViewer(table);
+ tableViewer.setUseHashlookup(true);
+<img src="images/tag_2.gif" align="baseline" width="24" height="13"> tableViewer.setColumnProperties(columnNames);
+
+ // Create the cell editors
+<img src="images/tag_3.gif" align="baseline" width="24" height="13"> CellEditor[] editors = new CellEditor[columnNames.length];
+
+ // Column 1 : Completed (Checkbox)
+<img src="images/tag_4.gif" align="baseline" width="24" height="13"> editors[0] = new CheckboxCellEditor(table);
+
+ // Column 2 : Description (Free text)
+<img src="images/tag_4.gif" align="baseline" width="24" height="13"> TextCellEditor textEditor = new TextCellEditor(table);
+ ((Text) textEditor.getControl()).setTextLimit(60);
+ editors[1] = textEditor;
+
+ // Column 3 : Owner (Combo Box)
+<img src="images/tag_4.gif" align="baseline" width="24" height="13"> editors[2] = new ComboBoxCellEditor(table, taskList.getOwners(),
+ SWT.READ_ONLY);
+
+ // Column 4 : Percent complete (Text with digits only)
+ textEditor = new TextCellEditor(table);
+ ((Text) textEditor.getControl()).addVerifyListener(
+
+<img src="images/tag_5.gif" align="baseline" width="24" height="13"> new VerifyListener() {
+ public void verifyText(VerifyEvent e) {
+ e.doit = &quot;0123456789&quot;.indexOf(e.text) &gt;= 0;
+ }
+ });
+ editors[3] = textEditor;
+
+ // Assign the cell editors to the viewer
+<img src="images/tag_6.gif" align="baseline" width="24" height="13"> tableViewer.setCellEditors(editors);
+ // Set the cell modifier for the viewer
+ tableViewer.setCellModifier(new ExampleCellModifier(this));
+ // Set the default sorter for the viewer
+<img src="images/tag_7.gif" align="baseline" width="24" height="13"> tableViewer.setSorter(
+ new ExampleTaskSorter(ExampleTaskSorter.DESCRIPTION));
+ }</font>
+</pre>
+<p><br>
+ We <img src="images/tag_1.gif" align="CENTER" width="24" height="13"> first
+ construct the <code>TableViewer</code> object, passing along our <code>Table</code>
+ instance since a <code>TableViewer</code> always operates on a table. We then
+ <font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font>
+ set the column properties that will be used in callbacks to recognize the column
+ on which we will want to operate. We <font color="#4444cc"><img src="images/tag_3.gif" align="baseline" width="24" height="13"></font>
+ initialize an array of <code>CellEditor</code> objects and we <font color="#4444cc"><img src="images/tag_4.gif" align="baseline" width="24" height="13"></font>
+ build editors for each column. For the checkbox editor, we do not need to do
+ anything special. For column 2, we set the text length limit of the free text
+ editor while for column 3, we specify the items used in the combo box editor.
+ We obtain these from our <code>ExampleTaskList</code> object. In the case of
+ column 4, we <font color="#4444cc"><img src="images/tag_5.gif" align="baseline" width="24" height="13"></font>
+ add a validator (a <code>VerifyListener</code>) to makes sure we accept only
+ digits.</p>
+<p>We finish setting up our <code>TableViewer</code> by <font color="#4444cc"><img src="images/tag_6.gif" align="baseline" width="24" height="13"></font>
+setting it's cellEditors and cellModifier properties and by <font color="#4444cc"><img src="images/tag_7.gif" align="baseline" width="24" height="13"></font>
+specifying the default sorter. The <code>ExampleCellModifier</code> is described
+in detail below.</p>
+<h2>Specifying Content and Label Providers</h2>
+<p>Coming back to the <code>TableViewerExample.open()</code> method, we now have
+a <code>TableViewer</code> instance for which we can set the content and label
+providers. The content provider is implemented as an inner class of the <code>TableViewerExample</code>
+class. This allows us to implement both the <code>IStructuredContentProvider</code>
+and the <code>ITaskListViewer</code> without &quot;polluting&quot;, so to speak,
+our model with JFace dependencies. This class does several things. It handles
+the <code><font color="#4444cc"><img src="images/tag_1.gif" align="baseline" width="24" height="13"></font>
+inputChanged() </code>and <codee><font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font>
+dispose()</codee> calls by registering (or deregistering) itself as a change
+listener for the model. It <font color="#4444cc"><img src="images/tag_3.gif" align="baseline" width="24" height="13"></font>
+relays the <code>getElements()</code> request to our model (a <code>TaskList</code>
+object) and packages the result into an array of <code>Object</code> instances.
+Finally, it implements the <code><font color="#4444cc"><img src="images/tag_4.gif" align="baseline" width="24" height="13"></font>
+addTask()</code>, <code><font color="#4444cc"><img src="images/tag_5.gif" align="baseline" width="24" height="13"></font>
+removeTask()</code> and <code><font color="#4444cc"><img src="images/tag_6.gif" align="baseline" width="24" height="13"></font>
+updateTasks()</code> callbacks specified by <code>ITaskListViewer</code>. The
+general principle here is that one should not assume that the model
+&quot;feeds&quot; a single view. Hence, views should register and deregister
+their interest in model changes (in our case, task additions, removals and
+changes).</p>
+<pre><font color="#4444cc"> /**
+ * InnerClass that acts as a proxy for the ExampleTaskList
+ * providing content for the Table. It implements the ITaskListViewer
+ * interface since it must register changeListeners with the
+ * ExampleTaskList
+ */
+ class ExampleContentProvider
+ implements IStructuredContentProvider, ITaskListViewer {
+<img src="images/tag_1.gif" align="baseline" width="24" height="13"> public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+ if (newInput != null)
+ ((ExampleTaskList) newInput).addChangeListener(this);
+ if (oldInput != null)
+ ((ExampleTaskList) oldInput).removeChangeListener(this);
+ }
+
+<img src="images/tag_2.gif" align="baseline" width="24" height="13"> public void dispose() {
+ taskList.removeChangeListener(this);
+ }
+
+ // Return the tasks as an array of Objects
+<img src="images/tag_3.gif" align="baseline" width="24" height="13"> public Object[] getElements(Object parent) {
+ return taskList.getTasks().toArray();
+ }
+
+ /* (non-Javadoc)
+ * @see ITaskListViewer#addTask(ExampleTask)
+ */
+<img src="images/tag_4.gif" align="baseline" width="24" height="13"> public void addTask(ExampleTask task) {
+ tableViewer.add(task);
+ }
+
+ /* (non-Javadoc)
+ * @see ITaskListViewer#removeTask(ExampleTask)
+ */
+<img src="images/tag_5.gif" align="baseline" width="24" height="13"> public void removeTask(ExampleTask task) {
+ tableViewer.remove(task);
+ }
+
+ /* (non-Javadoc)
+ * @see ITaskListViewer#updateTask(ExampleTask)
+ */
+<img src="images/tag_6.gif" align="baseline" width="24" height="13"> public void updateTask(ExampleTask task) {
+ tableViewer.update(task, null);
+ }
+ }</font></pre>
+<p>For the label provider, we chose to use a top-level class (the <code>ExampleLabelProvider</code>
+class). An <code>org.eclipse.jface.viewers.ITableLabelProvider</code> must
+implement two methods: <code><font color="#4444cc"><img src="images/tag_1.gif" align="baseline" width="24" height="13"></font>
+getColumnText()</code> and <font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font><code>
+getColumnImage()</code>. As the names imply, these methods must return the label
+text and image for a given column of a given element and are implemented using
+the following code:</p>
+<pre><font color="#4444cc"><code><font color="#4444cc"><img src="images/tag_1.gif" align="baseline" width="24" height="13"></font></code> public String getColumnText(Object element, int columnIndex) {
+ String result = &quot;&quot;;
+ ExampleTask task = (ExampleTask) element;
+ switch (columnIndex) {
+ case 0: // COMPLETED_COLUMN
+ break;
+ case 1 :
+ result = task.getDescription();
+ break;
+ case 2 :
+ result = task.getOwner();
+ break;
+ ...code omitted...
+ }
+ return result;
+ }
+
+<code><font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font></code> public Image getColumnImage(Object element, int columnIndex) {
+ return (columnIndex == 0) ? // COMPLETED_COLUMN?
+ getImage(((ExampleTask) element).isCompleted()) :
+ null;
+ }</font></pre>
+<p>These methods are called by the <code>TableViewer</code> whenever a table element
+ needs to be refreshed. Our <code>ITableLabelProvider</code> extends <code>org.eclipse.jface.viewers.LabelProvider</code>.
+ This way, we benefit from the behavior defined in the superclass. Internally,
+ our class manages an image registry (for the checkboxes) so we had to put in
+ place the mechanics to load and manage instances of <code>org.eclipse.jface.resource.ImageDescriptor</code>
+ and <code>org.eclipse.jface.resource.ImageRegistry</code>. The details of this
+ can be assessed by looking at the source code for the class. In SWT, platform
+ resources such as images and fonts must be disposed of when the application
+ exits. However, an <code>ImageRegistry</code> owns all of the image objects
+ registered with it and automatically disposes of them when the SWT Display is
+ disposed so we do not need to explicitly do so.</p>
+<h2>Supporting cell editors with an ICellModifier</h2>
+<p>We now have in place all the parts to display our task list in a table. What
+we need to add is the componentry to support cell editing. For this, we
+implement an <code>org.eclipse.jface.viewers.ICellModifier</code>. The later
+must define the <code>canModify()</code>, <code>getValue()</code> and <code>modify()</code>
+methods. The first one returns a <code>boolean</code> given an element (a table
+row) and a column name. The second method returns a cell value (given an element
+and a column name). Part of its implementation is shown below:</p>
+<pre><font color="#4444cc"> public Object getValue(Object element, String property) {
+
+ // Find the index of the column
+<code><font color="#4444cc"><img src="images/tag_1.gif" align="baseline" width="24" height="13"></font></code> int columnIndex = tableViewer.getColumnNames().indexOf(property);
+
+ Object result = null;
+<code><font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font></code> ExampleTask task = (ExampleTask) element;
+
+<code><font color="#4444cc"><img src="images/tag_3.gif" align="baseline" width="24" height="13"></font></code> switch (columnIndex) {
+ case 0 : // COMPLETED_COLUMN
+ result = new Boolean(task.isCompleted());
+ break;
+ case 1 : // DESCRIPTION_COLUMN
+ result = task.getDescription();
+ break;
+<code><font color="#4444cc"><img src="images/tag_4.gif" align="baseline" width="24" height="13"></font></code> case 2 : // OWNER_COLUMN
+ String stringValue = task.getOwner();
+ String[] choices = tableViewer.getChoices(property);
+ int i = choices.length - 1;
+ while (!stringValue.equals(choices[i]) &amp;&amp; i &gt; 0)
+ --i;
+ result = new Integer(i);
+ break;
+ ...code omitted...
+ }
+ return result;
+ }</font></pre>
+<p><code></code>First, <code><font color="#4444cc"><img src="images/tag_1.gif" align="baseline" width="24" height="13"></font></code>
+we obtain the column index for the property. <code></code>Second, <code><font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font></code>
+we cast the contents of <code>element</code> into a <code>ExampleTask</code>
+object so we can directly address its interface. Finally, <code><font color="#4444cc"><img src="images/tag_3.gif" align="baseline" width="24" height="13"></font></code>
+we <code></code>switch to the proper block of code based on the column index.
+Cases 0 and 1 are self explanatory. In <code><font color="#4444cc"><img src="images/tag_4.gif" align="baseline" width="24" height="13"></font></code>
+case 2, we must return the index for the combo box. Hence, we match the <code>stringValue</code>
+to one of the choices and return an <code>Integer</code> representing the
+current selection.</p>
+<p>The <code>modify()</code> method is somewhat symmetrical to the previous one.
+It is where the actual modification of the <code>ExampleTask</code> takes place.</p>
+<pre><font color="#4444cc"> public void modify(Object element, String property, Object value) {
+
+ // Find the index of the column
+ ...code omitted...
+
+ switch (columnIndex) {
+<code><font color="#4444cc"><img src="images/tag_1.gif" align="baseline" width="24" height="13"></font></code> case 0 : // COMPLETED_COLUMN
+ task.setCompleted(((Boolean) value).booleanValue());
+ break;
+ case 1 : // DESCRIPTION_COLUMN
+ task.setDescription(((String) value).trim());
+ break;
+ ...code omitted...
+ }
+<code><font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font></code> tableViewerExample.getTaskList().taskChanged(task);
+ }</font></pre>
+<p>As an example, for the <code><font color="#4444cc"><img src="images/tag_1.gif" align="baseline" width="24" height="13"></font></code>
+&quot;completed&quot; column, we <code></code>convert the passed value into a <code>boolean</code>
+and use the resulting value as an argument to the <code>ExampleTask.setCompleted()</code>
+method. We implement an equivalent behavior for each column. The <code><font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font></code>
+final line asks the <code>TableViewerExample </code>for its model (an <code>ExampleTaskList</code>)
+and notifies the model that a given task was changed. The model in turn notifies
+this change to each of its registered views.</p>
+<h2>Adding and Deleting Table Items</h2>
+<p>Editing existing tasks is useful but we also want to add and remove tasks
+using the GUI. The following code attaches the proper behavior to the
+&quot;Add&quot; button (very similar code is used for the &quot;Delete&quot;
+button):</p>
+<pre><font color="#4444cc"> </font><font color="#4444cc">// Create and configure the &quot;Add&quot; button
+<code><font color="#4444cc"><img src="images/tag_1.gif" align="baseline" width="24" height="13"></font></code> Button add = new Button(parent, SWT.PUSH | SWT.CENTER);
+ add.setText(&quot;Add&quot;);
+
+ GridData gridData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING);
+ gridData.widthHint = 80;
+ add.setLayoutData(gridData);
+<code><font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font></code> add.addSelectionListener(new SelectionAdapter() {
+
+ // Add a task to the ExampleTaskList and refresh the view
+ public void widgetSelected(SelectionEvent e) {
+ taskList.addTask();
+ }
+ });</font>
+</pre>
+<p>In the above code fragment, we <code><font color="#4444cc"><img src="images/tag_1.gif" align="baseline" width="24" height="13"></font></code>
+layout the button and <code><font color="#4444cc"><img src="images/tag_2.gif" align="baseline" width="24" height="13"></font></code>
+specify a selection listener that invokes the model's <code>addTask()</code>
+method. This later method notifies all its active views that a task was added
+using the following implementation:</p>
+<pre><font color="#4444cc"> public void addTask() {
+ ExampleTask task = new ExampleTask(&quot;New task&quot;);
+ tasks.add(tasks.size(), task);
+ Iterator iterator = changeListeners.iterator();
+ while (iterator.hasNext())
+ ((ITaskListViewer) iterator.next()).addTask(task);
+ }</font>
+</pre>
+<p>This pretty much closes the loop for cell and table editing. Through
+relatively simple implementations of <code>ICellModifier</code>, <code>ITableLabelProvider</code>
+and <code>IStructuredContentProvider</code>, we have a sophisticated and robust
+GUI supporting in-place edition of table cells and a viewer that will always
+reflect the current state of the model.<br>
+</p>
+<h2>Supporting column-wise sorting</h2>
+<p>As hinted above, adding column-wise sorting is almost trivial. To achieve
+this, we extend the <code>org.eclipse.jface.viewers.ViewerSorter</code> class
+and override the <code>compare()</code> public method with one that knows how to
+compare tasks based on its preset criteria. We leave it up to the reader to look
+up the class implementation. Specifying a sorter for our table viewer is done
+using the following pattern:</p>
+<pre><font color="#4444cc"> tableViewer.setSorter(
+ new ExampleTaskSorter(ExampleTaskSorter.PERCENT_COMPLETE))</font></pre>
+<p>We construct a sorter using one of its exposed criteria and use the result as
+an argument to the <code>TableViewer.setSorter()</code> method. On selection of
+a column header, we tell the <code>TableViewer</code> to use a different sorter
+and table lines get resorted &quot;automagically&quot;!</p>
+<h2>Packaging the table viewer as a stand-alone application</h2>
+<p>This table viewer/editor is all very nice but how and where can I make use of
+it in applications? One answer is, obviously, within an Eclipse plugin. But more
+than that, as others have described, SWT and JFace can be used to build
+applications that live outside the Eclipse framework. This is actually very
+simple: One simply has to put the following files in the same folder: <b>TableViewerExample.jar</b>
+(contains the application class and image files), <b>swt.jar</b>, <b>jface.jar</b>,<b>
+runtime.jar</b> and <b>boot.jar</b>. In addition, in a Win32 environment, you
+will need the <b>swt-win32-2133.dll</b> file which contains the &quot;glue&quot;
+allowing Java objects to communicate with Windows native widgets and APIs. On
+other platforms, the Java to native code will be found in a different file so
+you would need to somehow make sure your Java VM can find it.</p>
+<p><img src="images/win_only.gif" width="49" height="13"> On Windows, to launch
+the TableViewerExample application, you need to execute the following command:</p>
+<pre><font color="#4444cc">java -classpath TableViewerExample.jar;swt.jar;jface.jar;runtime.jar;boot.jar
+ -Djava.library.path=. com.opnworks.tableviewer.example.TableViewerExample</font></pre>
+<p>You would typically but such a command inside a .bat file. You can also
+achieve a clickable icon result on Windows and on other platforms by using a
+Java aware packager/installer application, some of which are free to use even
+for commercial purposes. With such a packaging, users will never know they are
+using Java technology! Not that there is anything to be shy about, it is just
+that most users really don't care and why should they?</p>
+<h2>Wrap-up</h2>
+<p>With the popularity of the web, it seems people and programmers have been
+shying away from building GUI applications. In addition, Java programmers and
+software development managers are often convinced that Java does not cut it on
+the client and that it cannot be used to build &quot;native&quot; applications.
+You can convince them of the contrary by rapidly prototyping and packaging a
+native application using the SWT and JFace APIs.<br>
+</p>
+
+</body>
+
+</html>
diff --git a/Article-UI-Guidelines/Contents.html b/Article-UI-Guidelines/Contents.html
new file mode 100644
index 0000000..e98bfea
--- /dev/null
+++ b/Article-UI-Guidelines/Contents.html
@@ -0,0 +1,5839 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="Author" content="Nick Edgar, Kevin Haaland, Jin Li and Kimberley Peter">
+<meta name="keywords" content="Eclipse UI Guidelines, User Interface, Guidelines, HCI, User Experience, Usability, Human Factors">
+<title>Eclipse User Interface Guidelines</title>
+<link HREF="default_style.css" REL="stylesheet">
+<style type="text/css">
+<!--
+.tocstyle { font-family: Arial, Helvetica, sans-serif; font-size: 10px}
+-->
+</style>
+</head>
+<body>
+
+<div align="right"> Copyright&copy; 2001-2004 International Business Machines Corp.&nbsp;
+ <table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Guidelines</font></font></b></td>
+ </tr>
+ </table>
+ </div>
+
+<h1>
+<img src="images/Idea.gif" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+Eclipse User Interface Guidelines<BR>Version 2.1
+</h1>
+<p><a href="Index.html" target="_top">View with table of contents</a></p>
+</center>
+
+<br>
+<center>
+<p><br><b><font color="#000000">Nick Edgar, Kevin Haaland, Jin Li and Kimberley Peter</font></b>
+ <p><b><font color="#000000">Last Updated: February 2004</font></b>
+</center>
+
+
+<h3>
+<font color="#000000">Notice</font></h3>
+<font color="#000000">Your feedback can influence the ideas and guidelines described here.&nbsp; If you have suggestions,
+<A href="mailto:platform-ui-dev@eclipse.org?subject=UI Guidelines v2.1 Feedback">please provide us with your feedback here.<BR>
+</A></font>
+
+<br>
+<br>
+<h2>
+<a NAME="Introduction"></a>Introduction</h2>
+In this document the Eclipse user interface guidelines are defined.
+<p>Eclipse is a universal tool platform - an open, extensible IDE for anything,
+but nothing in particular. The real value comes from tool plug-ins that
+"teach" Eclipse how to work with things - Java&trade; files, Web content, graphics,
+video - almost anything you can imagine. Eclipse allows you to independently
+develop tools that integrate with other people's tools so seamlessly, you
+won't know where one tool ends and another starts. The very notion of a
+tool, as we know it, disappears completely.
+<p>The platform is very flexible and extensible, but this flexibility has
+a serious drawback.&nbsp; In particular, there is no way within the program
+to ensure user interface consistency between the registered components
+within the platform.&nbsp; This document attempts to reconcile this problem,
+by defining standard user interface guidelines for the creation of new
+components.&nbsp; If these guidelines are adopted within your own tools,
+it will lead to greater consistency with the platform and other tools,
+and an easier learning curve for your customers.
+<p>These guidelines are intended for use by designers and implementors
+of an Eclipse user interface extension.
+<br>&nbsp;
+<h3>
+<a NAME="The Workbench"></a>The Workbench</h3>
+To start out, let's take a look at the Eclipse workbench user interface, and the
+various components within it.
+<p>The workbench is a collection of windows.&nbsp; Each window contains
+a menu bar, a toolbar, a shortcut bar and one or more perspectives.
+
+
+<p><img src="images/workbench_decomposed.gif" hspace="40" height=713 width=794>
+
+<p>
+A perspective
+is a visual container for a set of views and content editors.&nbsp; The views
+exist wholly within the perspective and are not shared, but any opened content
+editors are shared across perspectives.&nbsp; If two or more perspectives have the same view opened, they share the same instance of the view although its layout may differ in the perspectives. For perspectives in different Workbench windows, neither editors nor views are shared. A perspective
+is like a page within
+a book.&nbsp; It exists within a window along with any number of other
+perspectives and, like a page within a book, only one perspective is visible
+at any time.
+
+<p>The Workbench's main menu bar usually contains the File, Edit, Navigate, Project, Window, Help top-level menus. Other top-level menus that are in between
+the Edit and Project menu are typically context specific, based on the
+current active perspective, front most editor (whether active or not), and active view..
+
+<p>In the File menu you will find a New submenu, which contains menu items
+for Project, Folder, and File creation.&nbsp; The File menu also contains
+menu items for Import and Export, which are used to import files into the
+Workbench, and export them out again.&nbsp; In the Edit menu, you will
+find familiar commands like Cut, Copy, Paste, and Delete.&nbsp; These commands
+are known as global commands, and target the active part.
+In other words, if the Delete command is invoked with
+the Navigator active, the actual implementation is performed by the Navigator.
+&nbsp; In the Project menu, you will find project related commands such as Open project,
+Close project and Rebuild project are available.&nbsp; In the Run menu,
+you will find commands related to running and debugging application code,
+and launching external tools such Ant scripts.&nbsp;
+In the Window menu, you will find the Open Perspective submenu to open different
+perspectives to suit to needs of your development tasks.&nbsp; You will find perspective
+layout management menu items.&nbsp; You will also find the
+Show View submenu to add views to the current Workbench window.&nbsp;
+In addition, you will find the Preferences menu item, which is used to modify the functional
+preferences of the Workbench.
+<p>As a plug-in developer, you can contribute new views, editors, wizards,
+menu, and tool items to the platform.&nbsp; These contributions are defined
+using XML, and once registered, integrate seamlessly with the components
+which already exist in the platform.
+<h3>
+<a NAME="Projects, Folder and Files"></a>Projects, Folders and Files</h3>
+Eclipse can be used to create many different kinds of content - Java files, Web content, graphics,
+video - almost anything you can imagine.&nbsp; These objects are stored
+as regular files within the Eclipse workspace.&nbsp; The workspace consists
+of one or more top level projects.&nbsp; Each project contains a collection
+of folders and files.&nbsp; These objects are known as <i>resources</i>.
+<br>&nbsp;
+<p>
+
+<h2>
+<a NAME="Getting Started"></a>Getting Started</h2>
+For most developers, an introduction to the platform can be overwhelming,
+and you may ask "where do I get started?".&nbsp; Here are a few basic guidelines
+which will help you.
+
+<p>This document is intended for UI designers and developers.&nbsp; With this audience
+in mind, we can talk about the two main layers of any application: the
+model layer and the user interface layer.&nbsp; In the model layer of Eclipse,
+known as the Workspace, is a collection of resources (projects, folders
+and files).&nbsp; The user interface, or the Workbench, defines the presentation
+for those resources.
+
+<p>As a UI developer, you will also have a model and a presentation.&nbsp;
+If we assume that your goal is to make the model visible, through some
+presentation, most developers will start out by adding a new view or editor
+to the workbench.
+<p><font color="#000000">In Eclipse, an editor is used to contain the primary content, such as a document or data object, which users interact with.&nbsp;In every case, this content is the primary focus of attention and a reflection
+of the primary task.&nbsp; To illustrate this concept, let's look at some
+common examples.</font>
+
+<p><font color="#000000">To do Java programming, the primary task is to
+create, edit, and debug Java code. The primary focus is the Java code,
+so an editor is used to interact with that code.&nbsp; The navigator, outline,
+and properties view exist to support the primary task, but rarely hold
+your attention for an extended period of time while you are writing Java
+code.</font>
+
+<p><font color="#000000">To read email, the primary task is to create,
+send, read, and reply to email. The primary focus is a particular email
+message, so an editor is used to view or reply to an email message.&nbsp;
+A view may be used to select an email message to read, and open an editor.</font>
+
+<p><font color="#000000">To communicate using instant messaging, the primary
+task is the conversation.&nbsp; The primary focus is a particular conversation,
+so an editor is used to carry on that conversation.&nbsp; A view may be
+used to list people with whom you can initiate a conversation.</font>
+
+<p><font color="#000000">To browse the Web, the primary task is reading.
+The primary focus is a particular Web page, so an editor is used to browse
+the Web page.</font>
+
+<p><font color="#000000">In each case, the primary task determines the primary
+focus of attention. As the primary focus of attention, it deserves a primary
+position in the UI</font> <font color="#000000">(as an editor), and can contribute
+commands to the workbench's main menu bar and toolbar.</font>
+
+<p><font color="#000000">A view may be used to save your favorite links, and reopen
+them.&nbsp; At any time, you may decide to edit the page you are looking at.&nbsp;
+This causes a new editor to open. Views are used to support the primary task.&nbsp; You
+use them to navigate a hierarchy of information, open an editor, or view properties
+for the active part.&nbsp; Each view may have its own local toolbar and local menu bar.</font>
+
+<p>Once you have added a view or editor, an interesting question arises.&nbsp;
+Where did this model come from?&nbsp; In Eclipse, most data is created
+using a creation wizard.&nbsp; You may want to add a creation wizard too.
+And once an object exists, you may need a way to edit the properties for
+that object using a properties page, or the properties dialog.
+
+<p>All of these ideas will be discussed, in detail, in the following sections.
+<p>
+
+<br>
+<h2>
+<a NAME="General UI Guidelines"></a>General UI Guidelines</h2>
+
+
+<br>This document defines UI guidelines that are unique and specific to
+the Eclipse platform. It is a supplement to the other standard UI guidelines
+such as Microsoft&reg; User Experience, Macintosh Human Interface Guidelines,
+and Java Look and Feel Guidelines. You should continue to consult those
+guidelines for basic UI design and implementation recommendations.
+<p>It is expected that you already have a basic understanding of the Eclipse
+UI architecture and APIs, and the basic UI design principles: user in control,
+directness, consistency, forgiveness, feedback, aesthetics, and simplicity.
+If you do not currently have the prerequisite knowledge, please read the
+relevant documentation first.
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<font color="#09448D"><b>Guideline 1.1</b></font>
+<blockquote><font color="#09448D">Follow and apply good user interface
+design principles: user in control, directness, consistency, forgiveness,
+feedback, aesthetics, and simplicity.</font></blockquote>
+</p>
+
+<hr>
+
+<h3>
+<a NAME="The Spirit of Eclipse"></a>The Spirit of Eclipse</h3>
+At its heart, Eclipse is a platform for tool plug-ins.&nbsp; These plug-ins
+may be developed by a single team or by a partnership of teams, or the
+user may assemble a set of plug-ins from diverse sources.&nbsp; In either
+case, the usability of an individual tool, and Eclipse as a whole, will
+be positively influenced by user interface consistency.
+<p>If you're in doubt about the appropriate look and feel for a tool, look
+to the platform first, then the Java development tooling and the Plug-in Development Environment (PDE) in Eclipse for
+guidance. In many cases, the workflow you imagine may already exist in
+Eclipse.&nbsp; If so, adopt the platform's workflow and user interface
+conventions. This will lead to greater consistency with the platform and
+other plug-ins, and an easier learning curve for your customers.
+
+<p>In some scenarios, it may be tempting to ignore the workflow of Eclipse and
+implement a "custom" user interface.&nbsp; This interface will almost certainly
+stand out like a sore thumb in an integrated environment, where other tools
+adopt the platform conventions.&nbsp; You lose the benefit of past experience,
+and force your customers to learn new ideas.
+
+<p>Consult the <A href="#Best Practices" target="_right">Best Practices</A> section for examples and more information.
+
+</P>
+<P>Also, visit the <A
+ href="http://www.eclipse.org/newsgroups/index.html" target="_blank">Eclipse
+platform newsgroups</A> to share information with the community.</P>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.2</font></b>
+<blockquote><font color="#006699">Follow the platform lead for user interface
+conventions.</font></blockquote>
+<hr>
+</p>
+
+If you decide to reuse the conventions of Eclipse, be careful not to misappropriate
+Eclipse specific UI conventions.&nbsp; For instance, the active part in
+a workbench window is indicated by a shaded title.&nbsp; The use of shaded
+titles within an editor (see below) may be one way to indicate where the
+focus is, within that part, but it will also blur the concept of part activation
+in the window.
+<p><img src="images/badHilight.gif" hspace="40" height=423 width=702>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.3</font></b>
+<blockquote><font color="#09448D">Be careful not to mix UI metaphors.&nbsp;
+It may blur the original concept, and your own application.</font></blockquote>
+<hr>
+</p>
+
+Eclipse is an open source project.&nbsp; If you feel your ideas are generally
+useful, join the Eclipse community, write a proposal, and work with the
+Eclipse community to make Eclipse a better platform for product development
+and increase customer satisfaction.
+<p>Visit <A href="http://www.eclipse.org" target="_blank">www.eclipse.org</A> and join the Eclipse UI mailing list <B>platform-ui-dev</B>.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.4</font></b>
+<blockquote><font color="#09448D">If you have an interesting idea, work
+with the Eclipse community to make Eclipse a better platform for all.</font></blockquote>
+<hr>
+</p>
+
+<h3>
+<a NAME="Capitalization"></a>Capitalization</h3>
+Consistent capitalization of text within a plug-in leads to a more polished
+feel, and greater perception of quality.&nbsp; Within a dialog or window,
+headline capitalization should be applied to all titles, menus, tooltip, tabs, and push buttons.&nbsp;For example, &quot;Run to Line&quot; can be used as a menu item label.
+<P>Sentence style capitalization should
+be applied to all check boxes, radio buttons, and group labels.
+For example, &quot;Choose an option for the Java file&quot; can be used as a group label.</P>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b> <font color="#09448D">Guideline
+1.5</font></b>
+<blockquote><font color="#09448D">Use Headline style capitalization for
+menus, tooltip and all titles, including those used for windows, dialogs, tabs, column headings
+and push buttons. Capitalize the first and last words, and all nouns, pronouns,
+adjectives, verbs and adverbs.&nbsp; Do not include ending punctuation.</font></blockquote>
+
+<img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.6</font></b>
+<blockquote><font color="#09448D">Use Sentence style capitalization for
+all control labels in a dialog or window, including those for check boxes,
+radio buttons, group labels, and simple text fields.&nbsp; Capitalize the
+first letter of the first word, and any proper names such as the word Java.</font></blockquote>
+<hr>
+</p>
+
+
+
+
+
+<h3>
+<a NAME="Language"></a>Language</h3>
+Eclipse is available on a variety of different platforms, in a variety of
+locales.&nbsp; In reflection of the different languages and numeric formats
+in each, a localization strategy should be adopted for the text and images
+within each plug-in.&nbsp; This involves the separation of all resources
+from the source code of a plug-in itself, so that those resources can be
+translated to a new locale.
+<P>Consult the <A href="#Best Practices" target="_right">Best Practices</A> section for examples and more information.</P>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.7</font></b>
+<blockquote><font color="#09448D">Create localized version of the resources within your plug-in.</font></blockquote>
+
+<hr>
+<h3>
+<a NAME="Error Handling"></a>Error Handling</h3>
+If an error occurs in Eclipse, the appropriate response will be dependent
+on the context of the error.
+<p>Please refer to <A href="#Wizards">Wizards</A>
+section for guidelines on how to handle user input errors in a wizard.
+<p>Please refer to <A href="#Editors">Editors</A>
+section for guidelines on how to handle errors occur in an editor, .
+<p>When an error occurs which requires either an explicit user input or
+immediate attention from users, a modal dialog should be used to communicate
+the error to the user.&nbsp; This forces the user to notice, and deal with
+the problem.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+1.8</font></b>
+<blockquote><font color="#09448D">When an error occurs which requires either
+an explicit user input or immediate attention from users, communicate the
+occurrence with a modal dialog.</font></blockquote>
+
+<hr>
+<P>
+If a programming error occurs in the product, an error dialog should be
+used to communicate the occurrence to the user.&nbsp; The error should
+also be logged using the workbench error logging facility.&nbsp; This gives
+the user an opportunity to restart the platform, uninstall the corresponding feature,
+and contact their system administrator.
+<p>The plug-in should provide the following information in the detail area
+of the error dialog:
+<ul>
+<li>
+Provider name</li>
+
+<li>
+Plug-in name (user friendly name)</li>
+
+<li>
+Plug-in ID</li>
+
+<li>
+Version</li>
+</ul>
+<img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+1.9</font></b>
+<blockquote><font color="#09448D">If a programming error occurs in the
+product, communicate the occurrence with a dialog, and log it.</font></blockquote>
+
+<br>
+<h2><a NAME="Introduction_VDG"></a>Visual Design</h2>
+
+<p>
+All visual user interface elements created for Eclipse follow a common style called the
+<strong><i>Eclipse visual style</i></strong> or <strong><i>Eclipse style</i></strong>.
+In these guidelines you will find basic design information, as well as specifications for
+implementing Eclipse style icons and wizard graphics in tools based on the Eclipse framework.
+
+<p>
+Following these guidelines will help ensure consistency of visual user interface elements and their implementation
+across the Eclipse tools and plug-ins. Consistency of these elements includes visual semantic, style, and
+implementation considerations. These topics are covered in the following sections.
+
+
+
+<!-- CONSISTENCY SECTION STARTS -->
+<!-- Consistency -->
+
+<p>
+<h3><a NAME="Consistency_VDG">Consistency</a></h3>
+<p>
+In the development of the Eclipse style icons, a visual language was formed to describe a variety of concepts in the
+user interface. These concepts are now represented by a large selection of tiny visual signs that many have come to know
+through using Eclipse tools.</p>
+<p>In order to ensure a consistent visual experience, understanding of concepts across the tools, and minimize
+confusion for the user, we encourage you to re-use Eclipse style graphical elements whenever possible.</p>
+
+<br>
+<h4><a NAME="ConsistencyConcept_VDG">Icon Reuse</a></h4>
+<p>
+A great many icons have already been created in the Eclipse visual style so there is a good chance many of the icons or
+graphical elements you may need already exist. A sample of the core concepts is shown in the following table. Each of these
+elements carries with it a specific meaning, so care should be taken when using them to ensure that consistent meaning
+is maintained.</p>
+
+<p><IMG height="423" alt="metaphor example" src="images/metaphor_concepts.gif" hspace="40" width="658" border="0"></p>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.1</font></b>
+<blockquote><font color="#09448D">Re-use the core visual concepts to maintain consistent representation and meaning
+across Eclipse plug-ins.</font></blockquote></p>
+
+<br>
+
+<!-- ICON SPECIFICATION SECTION STARTS -->
+<!-- Icon Specifications / Icon Palettes -->
+<br>
+<h3><a NAME="IconSpecsPal_VDG">Icon Palettes</a></h3>
+<p>Various palettes used in creating Eclipse style icons.
+There are 3 different palettes used to create the 3 different icon states, as follows:</p>
+<ul>
+<li>
+<strong>256 Color Palette</strong> for the active or selected &mdash; also referred to as "color"&mdash; state of all icon types
+</li>
+<li>
+<strong>8 Color Grayscale Palette</strong> for the enabled state of perspective, view, toolbar, toolbar wizard, and local toolbar icons
+</li>
+<li>
+<strong>2 Color Grayscale Palette</strong> for the disabled state of toolbar, toolbar wizard, and local toolbar icons
+</li>
+</ul>
+
+<br>
+<h4>256 Color Palette</h4>
+<p>
+Eclipse style icons should be designed using a special 256 color palette that consists of
+20 standard colors and 236 custom colors, as shown below.
+<p>
+<IMG alt="newwin256.act" src="images/256palette.gif" hspace="40" width="194" height="193" border=0>
+</p>
+
+<p><strong>NOTE:</strong>&nbsp;
+Although the color palette shown is based on the standard windows .aco
+color palette that comes with Adobe Photoshop, these two palettes are NOT the same and ONLY the
+shown color palette should be used when creating Eclipse style icons.
+</p>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.2</font></b>
+<blockquote><font color="#09448D">Use the Eclipse 256 color palette for creating the active or selected state of
+all icon types.</font></blockquote></p>
+<hr>
+
+<br>
+<h4>8 Color Grayscale Palette</h4>
+<p>To create grayscale, enabled versions of your full color icons, you will need to use another
+palette that consists of the 8 colors shown below:</p>
+<br>
+<IMG height=80 alt="enabled colors" src="images/enabledcolors.gif" hspace="40" width="401" border="0">
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.3</font></b>
+<blockquote><font color="#09448D">Use the Eclipse 8 color palette for creating the enabled state of perspective,
+view, toolbar, toolbar wizard, and local toolbar icons.</font></blockquote></p>
+<hr>
+
+<br>
+
+<p><h4>2 Color Grayscale Palette</h4></p>
+<p>To create grayscale, disabled versions of your full color and enabled icons, you will need to use
+a subset of the 8 color palette, that consists of the 2 colors shown below:
+</p>
+<br>
+<IMG alt="disabled colors" src="images/disabledcolors.gif" hspace="40" width="158" height="50" border="0" >
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.4</font></b>
+<blockquote><font color="#09448D">Use the Eclipse 2 color palette for creating the disabled state of toolbar,
+toolbar wizard, and local toolbar icons.</font></blockquote></p>
+<hr>
+
+<!-- Icon Specifications / Icon Types -->
+<br>
+<br>
+<h3><a NAME="IconSpecsTypes_VDG">Icon Types</a></h3>
+
+<p>
+The Eclipse style icons have been categorized into separate types so that each can be optimized for its specific
+location within the user interface. Below is a breakdown of these types and where they are located.
+</p>
+
+<br>
+<IMG height=345 alt="icon types" src="images/icon_types.gif" hspace="40" width =539 border=0>
+<br>
+<p>
+<STRONG><FONT size=4>A&nbsp;&nbsp;&nbsp;</FONT>Product</STRONG>
+<br>The Product icon represents the branding of the product, and is always located on the far left
+of the window title bar before the perspective, document, and product name.
+</p>
+
+<p>
+<strong><font size=4>B&nbsp;&nbsp;&nbsp;</font>Perspective and Fastview</strong>
+<br>Perspective and fastview icons are found down the left side of the workbench. These icons allow the user to quickly
+switch between different opened perspectives, or to invoke different views
+that have been created as fastviews.
+<br></p>
+
+<p>
+<STRONG><FONT size=4>C&nbsp;&nbsp;&nbsp;</FONT>Toolbar</STRONG>
+<BR>Toolbar icons are found on the main toolbar across the top of the workbench. These icons invoke
+an command, either globally or within the editor.
+<br></p>
+
+<p>
+<STRONG><FONT size=4>D&nbsp;&nbsp;&nbsp;</FONT>Toolbar Wizard</STRONG>&nbsp;
+<BR>Toolbar wizard&nbsp;icons are found on the main toolbar across the top of the workbench.
+They are easily recognized by their wand and sparkle. Selecting one of these
+icons will launch a wizard.
+<br></p>
+
+<p><strong><font size=4>E&nbsp;&nbsp;&nbsp;</font>View</strong>
+<br>
+View icons are found on the left side of the titlebar of
+each view within the workbench. These icons indicate each view’s function.
+<br></p>
+
+<p>
+<STRONG><FONT size=4>F&nbsp;&nbsp;&nbsp;</FONT>Local (View) Toolbar</STRONG>
+<br>Local toolbar icons are found to the right of the view icon on the titlebar of each view
+within the workbench. These icons invoke an command on objects in that view only. Local toolbar icons
+are also found in all menus, including main, pull down, and context menus.
+<br></p>
+
+<p>
+<STRONG><FONT size=4>G&nbsp;&nbsp;&nbsp;</FONT>Model Object</STRONG>
+<br> Model Object icons are found in tree views, list views, and on Editor Tabs within the the workbench
+(such as files, folders, projects and so on).
+<br></p>
+
+<p>
+<STRONG><FONT size=4>H&nbsp;&nbsp;&nbsp;</FONT>Object Overlay</STRONG>
+<br>Object overlay icons are also found in tree or list views. They are appended to the various
+corners of model object icons as signifiers of some sort of change.
+</p>
+
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.5</font></b>
+<blockquote><font color="#09448D">Use the appropriate icon type in the location it is designed for within the
+user interface.</font></blockquote></p>
+<hr>
+
+
+<!-- Icon Specifications / Icon Size & Placement -->
+<br>
+<br>
+<h3><a NAME="IconSpecsSize_VDG">Icon Size &amp; Placement</a></h3>
+<p>
+With few exceptions, Eclipse style icons are designed within an area of 16 x 16 pixels. Within that area, a 15 x 15 pixel
+space is reserved for the image itself, leaving both a vertical and horizontal line of empty pixels to allow for proper
+placement of the image within the interface. Note the location of the empty pixels in the samples below. The icons are
+cut with the specific placement shown to ensure alignment in the user interface.
+</p>
+
+<P>The diagrams below show the proper sizing of the separate types of icons, and their proper placement within the
+allotted screen space.</P>
+
+<table cellpadding="0" cellspacing="0" border="0" width="100%">
+
+<tr><td valign="top" width="200">
+<IMG height="185" alt="view real estate" src="images/view_realestate.gif" hspace="40" width="180" border="0" >
+</td>
+<td valign="top">
+<p>
+<b>View Icons</b>
+<br>
+Maximum 16 pixels wide x 16 pixels high, always centered.<br>
+Empty pixels must be on the left, and bottom.</p>
+
+</td></tr>
+
+<tr><td valign="top">
+<IMG height="185" alt="perspective real estate" src ="images/perspective_realestate.gif" hspace="40" width=180 border=0 >
+</td>
+<td valign="top">
+<p>
+<b>Perspective Icons</b>
+<br>
+<b>Fastview Icons</b>
+<br>
+Maximum 16 pixels wide x 16 pixels high, always centered.<br>
+Empty pixels must be on the right, and bottom.</p>
+
+</td></tr>
+
+<tr><td valign="top">
+<IMG height="185" alt="toolbar real estate" src ="images/toolbar_realestate.gif" hspace="40" width=180 border=0 >
+</td>
+<td valign="top">
+<p>
+<b>Toolbar Icons</b>
+<br>
+<b>Toolbar Wizard Icons</b>
+<br>
+<b>Local Toolbar Icons</b>
+<br>
+Maximum 16 pixels wide x 16 pixels high, always centered.<br>
+Empty pixels should be on the left, and top.</p>
+
+</td></tr>
+
+<tr><td valign="top">
+<IMG height="185" alt="view real estate" src ="images/view_realestate.gif" hspace="40" width=180 border=0 >
+</td>
+<td valign="top">
+<p>
+<b>Model Object Icons</b>
+<br>
+Maximum 16 pixels wide x 15 pixels high, always centered.<br>
+Model Object icons must be no greater than 15 pixels high.
+<p></p>
+</td></tr>
+
+<tr><td valign="top">
+<IMG height="105" alt="overlay real estate" src ="images/overlay_realestate.gif" hspace="40" width=180 border=0 >
+</td>
+<td valign="top">
+<p>
+<b>Object Overlay Icons</b>
+<br>
+Object Overlays are one of the exceptions to the 16 x 16 pixel size.
+<br>
+Maximum 7 pixels wide x 8 pixels high, always centered.<br>
+Icon should have a white outside keyline around it to separate it from the icon it is being appended to.
+<br>
+See the next section on Icon Positioning for using the keyline on different types of Object Overlay icons.</p>
+</td>
+</tr>
+</td>
+</tr>
+</table>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.6</font></b>
+<blockquote><font color="#09448D">Follow the specific size specifications for each type of icon.</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.7</font></b>
+<blockquote><font color="#09448D">Cut the icons with the specific placement shown to ensure alignment in the user interface.</font></blockquote></p>
+<hr>
+
+
+<!-- Icon Specifications / Icon Positioning -->
+<br>
+<br>
+<h3><a NAME="IconSpecsPos_VDG">Icon Positioning</a></h3>
+<p>
+To follow from the specific size and placement of the different types of icons within their allotted screen space, the
+following positioning guidelines will help with the alignment of these elements relative to one another, and will aid
+in creating a well organized and aesthetically integrated user interface. (All measurements are in pixels.)
+</p>
+
+<br>
+<h4>Overview</h4>
+<IMG hspace="40" height="350" alt="overview image of the four different icon position areas detailed below" src="images/iconposition_main.gif" border=0>
+<br>
+<br>
+<br>
+
+<h4>1. Toolbar icons</h4>
+<p class="sub">(Includes Toolbar and Toolbar Wizard Icons)
+</p>
+<p>
+<IMG hspace="40" height="260" alt="toolbar specifications" src="images/toolbar_specs.gif" border="0">
+</p>
+
+<table cellspacing="2" cellpadding="4" border="0">
+<!-- 1st row : table categories -->
+ <tr>
+ <td rowspan="12" width="40px"></td>
+ <td></td>
+ <td><strong>Item</strong></td>
+ <td><strong>Positioning and Spacing</strong></td>
+ </tr>
+
+ <!-- 2nd row : beginning of table contents -->
+ <tr>
+ <td><strong>A</strong></td>
+ <td>Toolbar</td>
+ <td>22 pixels high</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td>Between left margin and handle</td>
+ <td>4 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>C</strong></td>
+ <td>Between handle and first icon</td>
+ <td>7 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>C</strong></td>
+ <td>Between icon and top of toolbar</td>
+ <td>3 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>C</strong></td>
+ <td>Between icon and bottom of toolbar</td>
+ <td>3 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>C</strong></td>
+ <td>Between icon and twisty</td>
+ <td>7 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>D</strong></td>
+ <td>Between twisty and hard rule</td>
+ <td>7 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>E</strong></td>
+ <td>Between hard rule and icon</td>
+ <td>6 pixels</td>
+ </tr>
+
+ <tr>
+ <td><strong>F</strong></td>
+ <td>Between icons</td>
+ <td>7 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>G</strong></td>
+ <td>Between icon and hard rule</td>
+ <td>10 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>H</strong></td>
+ <td>Between hard rule and handle</td>
+ <td>2 pixels</td>
+ </tr>
+ </table>
+<br>
+<br>
+
+<h4>2. Titlebar icons</h4>
+<p class="sub">(Includes View and Local Toolbar Icons)</p>
+
+<IMG hspace="40" height="162" alt="titlebar specifications" src="images/titlebar_specs.gif" border=0 >
+<br>
+<table cellspacing="2" cellpadding="4" border="0">
+ <tr>
+ <td rowspan="9" width="40px"></td>
+ <td></td>
+ <td><strong>Item</strong></td>
+ <td><strong>Positioning and Spacing</strong></td>
+ </tr>
+ <tr>
+ <td><strong>A</strong></td>
+ <td>Title bar</td>
+ <td>22 pixels high</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+
+ <td>Between left margin and view icon</td>
+ <td>4 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td>Between view icon and text label</td>
+ <td>3 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td>Between title bar icons and top of title bar</td>
+ <td>3 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td>Between title bar icons and bottom of title bar</td>
+ <td>3 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>C</strong></td>
+ <td>Between local toolbar icons</td>
+ <td>7 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>D</strong></td>
+ <td width="320">Between last local toolbar icon and closing window 'x'</td>
+ <td>7 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>E</strong></td>
+ <td>Between closing window 'x' and right margin</td>
+ <td>4 pixels</td>
+ </tr>
+ </table>
+ <br>
+ <br>
+
+ <h4>3. Perspective icons</h4>
+ <p class="sub">(Includes Perspective and Fastview Icons)
+ </p>
+
+
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr valign="top">
+ <!-- TD 1 begins -->
+ <td>
+ <IMG hspace="40" height="500" alt="perspective specifications" src="images/perspective_specs.gif" border="0" >
+ </td>
+
+ <!-- TD 2 begins -->
+ <td valign="top">
+ <p><h4>Perspective Icons</h4></p>
+
+ <!-- TD 2 : Table 1 begins -->
+ <table width="500" cellspacing="2" cellpadding="2" border="0">
+ <tr valign="top">
+ <td></td>
+ <td width="300"><strong>Item</strong></td>
+ <td width="200"><strong>Positioning and Spacing</strong></td>
+ </tr>
+ <tr valign="top">
+ <td><strong>A</strong></td>
+ <td>Perspective bar</td>
+ <td>27 pixels wide</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>B</strong></td>
+ <td>Between left margin and icon</td>
+ <td>5 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>B</strong></td>
+ <td>Between icon and right margin</td>
+ <td>6 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>B</strong></td>
+ <td>Between top of perspective section and first icon</td>
+ <td>3 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>B</strong></td>
+ <td>Between icon and hard rule</td>
+ <td>6 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>C</strong></td>
+ <td>Between hard rule and top of icon</td>
+ <td>6 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>D</strong></td>
+ <td>Vertically between icons</td>
+ <td>6 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>E</strong></td>
+ <td>Between icon and hard rule</td>
+ <td>6 pixels</td>
+ </tr>
+ </table>
+ <!-- TD 2 : Table 2 begins -->
+ <h4>Fastview Icons</h4>
+ <table width="500" cellspacing="2" cellpadding="2" border="0">
+ <tr valign="top">
+ <td></td>
+ <td width="300"><strong>Item</strong></td>
+ <td width="200"><strong>Positioning and Spacing</strong></td>
+ </tr>
+ <tr valign="top">
+ <td><strong>D</strong></td>
+ <td>Vertically between icons (same as perspective icons)</td>
+ <td>6 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>E</strong></td>
+ <td>Between icon and hard rule</td>
+ <td>6 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>F</strong></td>
+ <td>Between left margin and icon</td>
+ <td>5 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>F</strong></td>
+ <td>Between top of fastview section and first icon</td>
+ <td>3 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>F</strong></td>
+ <td>Between icon and right margin</td>
+ <td>6 pixels</td>
+ </tr>
+ </table>
+ </td>
+</tr>
+</table>
+
+
+ <h4>4. Tree View icons</h4>
+ <p class="sub">(Model Object Icons)</p>
+
+ <IMG hspace="40" height="190" alt="treeview specification" src="images/treeview_specs.gif" border=0 >
+ <br>
+ <br>
+ <table border="0" cellspacing="2" cellpadding="4">
+ <tr>
+ <td rowspan="8" width="40px"></td>
+ <td></td>
+ <td width="350"><strong>Item</strong></td>
+ <td width="200"><strong>Positioning and Spacing</strong></td>
+ </tr>
+ <tr>
+ <td><strong>A</strong></td>
+ <td>Between &ldquo;+/-&rdquo; widget and left of window</td>
+ <td>4 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>A</strong></td>
+ <td>Between &ldquo;+/-&rdquo; widget and top of window</td>
+ <td>4 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td>Between top of window and first icon</td>
+ <td>0 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td>Vertically between icons</td>
+ <td>0 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td>Between horizontal treeview branch and icon</td>
+ <td>0 pixels</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td>Between icon and text label</td>
+ <td>3 pixels</td>
+ </tr>
+ <tr valign="top">
+ <td><strong>C</strong></td>
+ <td>Text is nested within the text label</td>
+ <td width="200">3 pixels each on left and top, 2 pixels on right, 4 pixels on bottom (length varies)</td>
+ </tr>
+ </table>
+ <br>
+
+<!-- Icon Specifications / Icon Overlays -->
+<br>
+<h3><a NAME="IconSpecsOvr_VDG">Icon Overlays</a></h3>
+<p>
+ As stated under Icon Size &amp; Placement, all overlays are consistently the same size: 7 x 8 pixels.
+ An additional white border keyline is included on Project Nature and Java Overlay types to visually separate them
+ from the underlying Model Object icon. The keyline location varies depending on the overlay's placement on the
+ underlying icon.
+</p>
+
+<strong>Project Nature Overlay</strong>
+ <p>The project nature overlays are displayed in the Navigator and the Package views.
+ They are completely superimposed on the model object at the top right corner
+ of the 16 x 16 icon space.
+ </p>
+ <p>
+ Only a few project nature overlay icons have been created to prevent crowding in the interface.
+ Project nature overlays quickly identify the various <strong>types</strong> of projects that can be contained in
+ the Navigator and mirroring views.
+ </p>
+ <p>
+ The white keyline border is applied around the image to enhance legibility.
+ </p>
+ <p>
+ <img src="images/ovr_projectnature.gif" hspace="40" width="180" height="180"
+ alt="size and location of the project nature overlay in the upper right corner of the model object icon" border="0">
+ &nbsp;&nbsp;&nbsp;
+ <img src="images/ovr_projectnature_sample.gif" hspace="40" width="180" height="180"
+ alt="sample of a project nature overlay in the upper right corner of the model object icon"
+ border="0">
+ </p>
+
+<br>
+<strong>Auxiliary Overlay</strong>
+ <p>The auxiliary overlays are displayed in all tree views. This type of overlay is completely superimposed
+ on the model object at the bottom left corner of the 16 x 16 icon space.</p>
+ <p><img src="images/ovr_auxiliary.gif" hspace="40" width="180" height="180" alt="" border="0"></p>
+ <p>
+ The auxiliary overlay quickly identifies the <strong>status</strong> of an object. Examples of auxiliary overlays are
+ <em>warning</em>, <em>error</em>, <em>failure</em>, and <em>success</em>.
+ </p>
+
+<br>
+<strong>Java Overlay</strong>
+<p>The Java overlays are displayed in the Outline, Hierarchy, and Package views.
+The Java overlays are appended to the model object icon, so they extend
+the 16x16 icon space. They are placed to the right of a model object icon, overlapping the 16x16 model object space by 3 pixels.
+A maximum of 3 java overlays can be put on the model object.</p>
+<p>The order in which an overlay appears depends on the order in which it has been assigned. In designing Java overlays, it is
+important to make sure the base object icon can support the addition of overlays without compromising readability. Note that there
+are two Java overlays that always display at the bottom right corner &mdash; 'C' position in the layout shown below &mdash; of the
+model object:
+<img src="images/synch_co.gif" width="7" height="8" alt="" border="0">
+<strong>synchronized</strong> (method) and <img src="images/run_co.gif" width="7" height="8" alt="" border="0">
+<strong>run</strong> (class).</p>
+<p><img src="images/ovr_java.gif" hspace="40" width="276" height="218"
+alt="size and location of the java overlays to the right of the model object icon" border="0">
+&nbsp;&nbsp;&nbsp;
+<img src="images/ovr_java_sample1.gif" hspace="40" width="276" height="218"
+alt="sample of java overlays to the right of the model object icon" border="0">
+</p>
+
+ <p>
+ Java overlays identify <strong>attributes</strong> of an object. Examples of Java overlays are
+ <em>static</em>, <em>final</em>, <em>abstract</em>, and <em>synchronized</em>.
+ </p>
+
+<p><strong>Note:</strong> In the Hierarchy and Outline views, the Java overlays are appended to the right of the model object
+as shown, but in the Package view they are stacked over the model object.</p>
+
+<br>
+<strong>Version Control Overlay</strong>
+ <p>Version control overlays are displayed in the Navigator view and in the Structure View of the Merge Editor in CVS.
+ When they are displayed in the Navigator view, the overlay is completely superimposed on the model object at the right
+ of the 16 x 16 icon space.
+ </p>
+
+ <p><img src="images/ovr_versioncontrol.gif" hspace="40" width="180" height="180"
+ alt="size and location of the version control overlays in the Navigator view in the lower right corner of the model object icon"
+ border="0"></p>
+
+ <p>When the version control overlays are displayed in the Structure View of the Merge Editor in CVS, they are
+ appended to the model object, so they extend the 16x16 space. They are placed to the right of a model object icon,
+ overlapping the 16x16 model object space by 3 pixels.
+ In CVS there is a maximum of 2 overlays on the right of the object.</p>
+
+ <p><img src="images/ovr_versioncontrol_cvs.gif" hspace="40" width="216" height="209"
+ alt="size and location of the version control overlays in the Structure view of the Merge Editor in CVS at the right of the model object icon"
+ border="0">&nbsp;&nbsp;&nbsp;
+ <img src="images/ovr_versioncontrol_cvs_samp.gif" hspace="40" width="216" height="209"
+ alt="sample of the version control overlays in the Structure view of the Merge Editor in CVS at the right of the model object icon"
+ border="0">
+ </p>
+<br>
+
+ <p>
+ Version control overlays identify a <strong>transition-state</strong> of an object. Examples of CVS overlays are
+ <em>incoming</em>, <em>outgoing</em>, <em>in conflict</em>, <em>added</em>, <em>deleted</em>, and <em>changed</em>.
+ </p>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.8</font></b>
+<blockquote><font color="#09448D">Follow the positioning guidelines for the different types of icons for optimal alignment
+of these elements relative to one another.</font></blockquote></p>
+
+<!-- ICON SPECIFICATION SECTION ENDS -->
+
+
+<!-- WIZARD SPECIFICATION SECTION BEGINS -->
+<!-- Wizard Specifications / Wizard Palette -->
+<br>
+<h3><a NAME="WizSpecsPal_VDG">Wizard Palette</a></h3>
+<p>The Wizard Palette section shows the
+the special blue 183 color palette you will need to create your wizard graphics.
+<br>
+Eclipse style wizard banner graphics should be designed using a special blue 183 color palette,
+as shown below.</P>
+<p>
+<img src="images/wizban183.gif" hspace="40" width="194" height="145" alt="" border="0">
+</p>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.9</font></b>
+<blockquote><font color="#09448D">Use the Eclipse special blue 183 color palette for creating wizard graphics.</font></blockquote></p>
+<hr>
+
+<!-- Wizard Specifications / Wizard Size & Placement -->
+<br>
+<br>
+<h3><a NAME="WizSpecsSize_VDG">Wizard Size &amp; Placement</a></h3>
+<p>The Wizard Sizing section gives the sizing guidelines for
+creating wizard banner graphics.
+<br>
+All wizard banner graphics are designed to fit within a specified screen space that is
+75 pixels wide x 58 pixels high, in the top, right corner of the wizard.
+</p>
+
+<br>
+<br>
+<p>
+<img src="images/wizban.gif" hspace="40" width="395" height="175" alt="" border="0">
+</p>
+<br>
+<br>
+<p>
+The actual size of each wizard banner graphic will vary depending on the elements involved, but should not exceed
+55 pixels wide x 45 pixels high.
+</p>
+<p>
+Within the wizard banner space allocation,
+there is no firm rule for where to place the wizard banner graphic.
+Generally, the graphic is centered vertically,
+and off-center to the left horizontally.
+</p>
+<br>
+<br>
+<img src="images/wizbans.gif" hspace="40" width="366" height="140" alt="" border="0">
+<br>
+<br>
+<br>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.10</font></b>
+<blockquote><font color="#09448D">Follow the specific size specifications for wizard graphics.</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.11</font></b>
+<blockquote><font color="#09448D">Cut the wizard graphics with the specific placement shown to ensure alignment
+in the wizard banner area.</font></blockquote></p>
+<!-- WIZARD SPECIFICATION SECTION ENDS -->
+
+
+<!-- IMPLEMENTATION CONVENTIONS SECTION BEGINS -->
+
+<!-- Implementation Ready -->
+<h3><a NAME="ConsistencyImp_VDG">Implementation Conventions</a></h3>
+<p>
+Eclipse provides a set of directory names and structure for storing and accessing user interface graphics
+easily in any plug-in. This section describes the naming conventions and directory path used in Eclipse. If followed,
+the predefined directory names and path allow for the icon and wizard graphic files to be implemented directly into the
+plug-in structure without any need for modifications.
+</p>
+<p>
+From icon request to delivery, the naming and structure is the same. If you use a different user interface
+directory name or more than one directory to store graphics than that specified at request time, notify your visual
+design contact of these changes so that they can maintain a parallel system. Further, keeping the number of directories
+in which you store your graphics to a minimum, will reduce unnecessary duplication of graphics and ease resource
+management issues considerably.
+</p>
+
+<br>
+
+<h4>Directory Names and Structure</h4>
+<p>
+Once your icons have been conceptualized, designed, approved and cut, they are stored using the directory naming
+convention and structure described below.
+</p>
+<ol type="A">
+<li>The name of the first level directory refers to the Eclipse platform: Icons used in an Eclipse plug-in are
+called <strong>org.eclipse.pluginname.ui_0.0.0</strong>. Where <strong>pluginname</strong> is substituted with the name
+of the plug-in and <strong>_0.0.0</strong> is substituted with the Eclipse version number, for example,
+<strong>org.eclipse.debug.ui_2.1.0</strong>
+<br>
+<br>
+</li>
+<li>Each plug-in that manages user interface elements for a tool set contains a second level directory
+called <strong>icons</strong>.
+<br>
+<br>
+</li>
+<li>
+Within the <strong>icons</strong> directory, there are separate folders with names that indicate the state, type and
+size of the icons, as follows:
+<ol>
+<li>
+The first letter of the folder name indicates the icon state. The letter <strong>c</strong> for color,
+<strong>d</strong> for disabled, and <strong>e</strong> for enabled.
+<br>
+</li>
+<li>The next 3 to 6 letters signify the icon type: toolbar (tool), local toolbar (lcl),
+view or perspective (view), model object (obj), overlay (ovr), wizard banner (wizban).
+<br>
+</li>
+<li>The last two digits of the folder name indicate the size of the icons within. Usually it
+will be <strong>16</strong> (to indicate the 16 pixel by 16 pixel size), but there might be others
+(for example, <strong>32</strong> would indicate the 32 x 32 size) depending on the plug-in requirements.
+</li>
+</ol>
+</li>
+</ol>
+<p>The following image shows a complete directory structure for a plug-in.</p>
+<p><img src="images/impready_folderstructure.gif" hspace="40" width="483" height="230"
+alt="Image showing the complete directory structure for user interface graphics a plug-in, as described in text above"
+border="0">
+</p>
+
+<p><strong>NOTE:</strong>&nbsp;
+<ol>
+<li>
+For many plug-ins, inside the <strong>icons</strong> directory, there is a folder called "<strong>full</strong>"
+which then contains these icon type folders. This <strong>full</strong> folder is being phased out of the icon directory
+structure for new plug-ins. The structure shown above is the recommended icon directory structure.
+</li>
+<li>
+Your plug-in may not require all types of icons shown in the sample. The sample illustrates the complete set of icon types
+that you may need in your plug-in. In addition, there are sometimes exceptions to this list of types in plug-ins that have
+a special type of icon that is not covered by this standard set. This is rare, however, and we encourage you to get to know
+the different types and their respective states, and use the structure as shown.
+</li>
+<li>When an icon has multiple states, the file name is the same across each of the active (color), enabled, and disabled
+state folders. Because of this organization, using the states provided is important, and will prevent you from having
+to rename the states of your icons if all were stored in the same folder.
+</li>
+</ol>
+</p>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.12</font></b>
+<blockquote><font color="#09448D">Follow the predefined directory structure and naming convention.</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.13</font></b>
+<blockquote><font color="#09448D">Keep the original directory names provided.</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.14</font></b>
+<blockquote><font color="#09448D">Minimize duplication of graphics within a plugin by keeping all graphics in one, or few, first level user interface directories.</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.15</font></b>
+<blockquote><font color="#09448D">Use the active, enabled, and disabled states provided.</font></blockquote></p>
+<hr>
+
+<br>
+<h4>File Names</h4>
+<p>Establishing file names before the icons are designed will help ensure appropriately descriptive names for the concepts
+they represent, and may prevent misuse of icons for purposes not intended and duplicate file names. If the names are well
+considered in advance, you will appreciate being able to quickly make the distinction between icon types and find concepts
+more readily, especially as the volume of your graphic resources increases.
+</p>
+
+<h4>Suggestions for File Name Suffixes</h4>
+<p>File suffixes are useful for making the distinction between types of user interface elements. They can be used to denote
+the location or function of an icon or wizard graphic. The following table shows how suffixes are being used for image file
+names in Eclipse:
+</p>
+<table cellspacing="2" width="100%" cellpadding="2" border="0">
+<tr bgcolor="#c0c0c0">
+ <td><strong>Filename Suffix</strong></td>
+ <td><strong>Used for icons with the following function or location:</strong></td>
+ <td><strong>Icon Type and Location</strong></td>
+</tr>
+<tr valign="top" bgcolor="#e4e4e4">
+ <td>*_wiz.gif</td>
+ <td>invoke a wizard, or are graphics within a wizard</td>
+ <td>Wizard banner graphics: used in wizard dialog windows.<br>
+ Wizard icons: used on wizard toolbars.</td>
+</tr>
+<tr valign="top">
+ <td>*_exec</td>
+ <td>invoke executable files</td>
+ <td>Toolbar icons: used in cascading menus, and global toolbars.</td>
+</tr>
+<tr valign="top" bgcolor="#e4e4e4">
+ <td>*_edit</td>
+ <td>are in an editor view</td>
+ <td>Toolbar icons: used in cascading menus, and global toolbars.</td>
+</tr>
+<tr valign="top">
+ <td>*_nav</td>
+ <td>are in a navigator view</td>
+ <td>Toolbar icons: used in cascading menus, and global toolbars.<br>
+ Local toolbar icons: found on the far right of the title area of a view. <br>
+ View and perspective icons: found in the top, left corner of a view. </td>
+</tr>
+<tr valign="top" bgcolor="#e4e4e4">
+ <td>*_misc</td>
+ <td>do no fit into any of the other categories</td>
+ <td>Toolbar icons: used in cascading menus, and global toolbars.<br>
+ View and perspective icons: found in the top, left corner of a view.</td>
+</tr>
+<tr valign="top">
+ <td>*_tsk</td>
+ <td>represent tasks that user can do</td>
+ <td>Local toolbar icons: found on the far right of the title area of a view.<br>
+ Overlay icons: placed on top of a model object icon to indicate a change in condition.<br>
+ Object icons: used in the tree view, list view, and properties view.<br>
+ View and perspective icons: found in the top, left corner of a view.
+ </td>
+</tr>
+<tr valign="top" bgcolor="#e4e4e4">
+ <td>*_mode</td>
+ <td>toggles the working mode of the view</td>
+ <td>Local toolbar icons: found on the far right of the title area of a view.
+ </td>
+</tr>
+<tr valign="top">
+ <td>*_menu</td>
+ <td>are found in a menu</td>
+ <td>Local toolbar icons: found on the far right of the title area of a view.
+ </td>
+</tr>
+<tr valign="top" bgcolor="#e4e4e4">
+ <td>*_ps</td>
+ <td>are found in a property sheet</td>
+ <td>Local toolbar icons: found on the far right of the title area of a view.<br>
+ View and perspective icons: found in the top, left corner of a view.
+ </td>
+</tr>
+<tr valign="top">
+ <td>*_obj</td>
+ <td>represent model objects</td>
+ <td>Model object icons: used in the tree view, list view, and properties view.</td>
+</tr>
+<tr valign="top" bgcolor="#e4e4e4">
+ <td>*_pal</td>
+ <td>are model object icons on object palettes</td>
+ <td>Model object icons: used on object palettes</td>
+</tr>
+<tr valign="top">
+ <td>*_co</td>
+ <td>is for commands that engage the system, e.g. build command</td>
+ <td>Toolbar icons: used in cascading menus, and global toolbars.<br>
+ Local toolbar icons: found on the far right of the title area of a view.
+ </td>
+</tr>
+<!-- Use the following table row if the last row of data has a white background. It provides
+a line to define the table information from the rest of the text. If the last row of data has
+the dark gray background, you don't need it, so comment it out. -->
+<tr height="1" valign="top" bgcolor="#e4e4e4">
+ <td></td>
+ <td></td>
+ <td></td>
+</tr>
+</table>
+
+<br>
+</td>
+</tr>
+</table>
+
+<p>To aid you in choosing your file names, we offer the following guidelines:</p>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.16</font></b>
+<blockquote><font color="#09448D">Abbreviate file name instead of using the full icon name,
+e.g. New Interface becomes "newint".</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.17</font></b>
+<blockquote><font color="#09448D">Use lower case characters in your file names, e.g. DTD becomes "dtd".</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.18</font></b>
+<blockquote><font color="#09448D">Use 10 characters or less in your file names if possible (underscores count as a character).</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.19</font></b>
+<blockquote><font color="#09448D">Use a file name suffix that describes its location or function in the tool,
+e.g. newint_wiz.</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.20</font></b>
+<blockquote><font color="#09448D">Use transparent *.gif format for all user interface icons and wizard graphics,
+unless the context requires a different file format.</font></blockquote></p>
+<hr>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16">
+<b><font color="#09448D">Guideline 2.21</font></b>
+<blockquote><font color="#09448D">Keep the original file names provided.</font></blockquote></p>
+
+<!-- IMPLEMENTATION CONVENTIONS SECTION ENDS -->
+<!-- END OF VISUAL DESIGN CONTENT -->
+
+<br>
+<h2>
+<a NAME="Component Development"></a>Component Development</h2>
+
+<h3>
+<a NAME="Commands"></a>Commands</h3>
+A command, which is invoked by a user to carry out some specific functions, may appear as an item in a menu, or an item in a toolbar.&nbsp;
+In reflection of this, it has attributes for the menu or tool item label,
+tooltip, and image.
+<p>As a plug-in developer, you can contribute commands to the window menu
+bar and toolbar, or to individual views and editors.&nbsp; Contribution
+to the window is performed using an action set, a set of task oriented
+commands which the user can show or hide.&nbsp; Contribution to a view or
+editor is performed using individual command.
+<p>Here is an illustration of the main areas of contribution.
+
+<p><img src="images/actionExamples.gif" hspace="40" height="664" width="789">
+
+<p>In this section we'll look at general command guidelines.&nbsp; For information
+on window, view, or editor specific guidelines, see <a href="#Windows">Windows</a>,
+<a href="#Views">Views</a>,
+and <a href="#Editors">Editors</a>.
+<h4>
+Appearance</h4>
+Each command must have a label, tool tip, and image.&nbsp; If the command
+appears in a toolbar, the command image will be displayed on all platforms.&nbsp;
+If the command appears in a menu, the image will only be displayed on some
+platforms, such as Windows&reg; 2000.&nbsp; The label and tool tip should use
+Headline style capitalization, as defined in General UI Guidelines.
+<p>Each command must provide one full color image.&nbsp; This image will
+be displayed if the mouse is placed over the command.&nbsp; It will also
+be used to generate the enabled, disabled, and pressed images which appear
+in normal command use.&nbsp; Commands which are contributed in code also
+have the option to define explicit images for enabled, disabled, and roll
+over.&nbsp; This option can be used for greater control over image appearance.
+<p>The following snapshot shows the valid use of Headline capitalization
+in a toolbar.
+<p><img src="images/tooltipCaps.gif" height=141 width=244>
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+3.1</font></b>
+<blockquote><font color="#09448D">Each command must have a label, tool tip,
+and full color image.&nbsp; The label and tool tip must use Headline style
+capitalization.</font></blockquote>
+<hr>
+<p>
+The tool tips for a command should describe the <i>behavior which occurs</i>
+if the command is invoked, independent of the current state.&nbsp;For push buttons, the label should decribe the result of users pushing the button.
+For toggle buttons, it should describe its effect when the item is toggled on, and the label should not change depending on the state of the button. In Eclipse version 2.1, it is recommended that the tool tip for a command uses the same text as that for the command label.
+For instance, in the following snapshot
+the behavior of the Show Type Hierarchy button is shown using one tool tips text.
+
+<p><img src="images/goodTooltips.gif" hspace="40" height=169 width=213>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+3.2</font></b>
+<blockquote><font color="#09448D">The command tooltip should describe the
+result of the command, not the current state of the command. Use the text same as that for the command label.</font></blockquote>
+<hr>
+<p>
+For consistency, any command which has a similar behavior to existing commands
+in the workbench, should adopt the same terminology.
+<p>When creating a resource, the term "New" should be used in an command
+or wizard.&nbsp; For instance, "New File", "New Project" and "New Java
+Class".&nbsp; The term "Delete" should be used when deleting an existing
+resource.
+<p>When creating an object inside a resource (e.g., a tag in an XML file;
+a method or field in a Java class), the term "Add" should be used; the
+user is adding something to an existing resource.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+3.3</font></b>
+<blockquote><font color="#09448D">Adopt the labeling terminology of the
+workbench for New, Delete and Add commands.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Enablement</h4>
+An command should only be enabled if it can be completed successfully.&nbsp;
+If this is not the case, the command should be disabled.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+3.4</font></b>
+<blockquote><font color="#09448D">An command should only be enabled if it
+can be completed successfully.</font></blockquote>
+<hr>
+<p>
+Command enablement should be quick to calculate.&nbsp; If it is too expensive
+to calculate the enablement of an command, the command should be optimistically
+enabled.&nbsp; If the command is invoked, it should calculate the real enablement,
+and show a dialog to the user if it is not available.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+3.5</font></b>
+<blockquote><font color="#09448D">Command enablement should be quick.&nbsp;
+If command enablement cannot be quick, enable the command optimistically
+and display an appropriate message if the command is invoked, but cannot
+be completed.</font></blockquote>
+
+<p>
+
+<h3>
+<a NAME="Dialogs"></a>Dialogs</h3>
+A dialog is used for modal interaction with the user.&nbsp; It can be used
+to solicit information, or provide feedback.
+<br>&nbsp;
+<h4>
+Initialization</h4>
+When a dialog first opens, the initial focus should be given to the first
+control where information is required from the user.&nbsp; This control
+can be determined by the tab order of controls until a control is found
+where information is required.&nbsp; If the dialog provides simple feedback,
+or requires simple confirmation from the user, the initial focus may also
+be assigned to the default button.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 4.1</font></b>
+<blockquote><font color="#09448D">When a dialog opens, set the initial
+focus to the first input control in the container. If there are no input controls, the initial focus should
+be assigned to the default button.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Multiple Item Selection</h4>
+Slush Bucket widgets (also known as the Twin Box design) should flow from
+the left to the right with the source objects on the left and selected
+files on the right.
+<p>Slush Buckets should also have the following control buttons, in this
+order, for moving objects from the source the selected buckets.
+<br>&nbsp;
+<table class="indent" border="1" cellspacing="0" cellpadding="3">
+<tr>
+<td><b>Button</b></td>
+
+<td><b>Function</b></td>
+</tr>
+
+<tr>
+<td>></td>
+
+<td>Add whatever is selected on the left to the right</td>
+</tr>
+
+<tr>
+<td>&lt;</td>
+
+<td>Remove selected items from the right</td>
+</tr>
+
+<tr>
+<td>>></td>
+
+<td>Add all (whether they are selected or not)</td>
+</tr>
+
+<tr>
+<td>&lt;&lt;</td>
+
+<td>Remove&nbsp; all</td>
+</tr>
+</table>
+
+<p><img src="images/slushBucket.gif" hspace="40" height=278 width=533>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 4.2</font></b>
+<blockquote><font color="#09448D">Slush Bucket widget (or Twin Box) should
+flow from left to right with the source objects on the left hand side.
+It should have the >, &lt;, >>, &lt;&lt; control buttons in this order.</font></blockquote>
+
+<p>
+
+<h3>
+<a NAME="Wizards"></a>Wizards</h3>
+In Eclipse, a wizard is commonly used for the creation of new resources,
+resource import, or resource export.&nbsp; It can also be used for the
+execution of any task involving a sequential series of steps.&nbsp; A wizard
+should be used if there are many steps in the task, and they must be completed
+in a specific order.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.1</font></b>
+<blockquote><font color="#09448D">Use a wizard for any task consisting
+of many steps, which must be completed in a specific order.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Appearance</h4>
+At the top of each wizard is a header, containing a banner graphic and
+a text area.&nbsp; The banner graphic contains an image representing the
+wizard task, and should be created with a white to blue, gray scale palette
+for consistency with other banners in Eclipse.&nbsp; These colors also
+avoid distracting the user from the important fields of the wizard.&nbsp;
+The text area is used to prompt the user for information which is absent,
+and display error messages if information is invalid.&nbsp; The presence
+of the header, with banner graphic and text area, creates a more polished
+feel, and greater perception of quality to the wizard.
+<p>At the bottom of each wizard, a Back, Next, Finish, and Cancel button
+should appear.
+<p><img src="images/wizardAppearance.gif" hspace="40" height=390 width=500>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.2</font></b>
+<blockquote><font color="#09448D">Each wizard must contain a header with
+a banner graphic and a text area for user feedback.&nbsp; It must also
+contain Back, Next, Finish, and Cancel buttons in the footer.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Initialization</h4>
+When a wizard first opens, the focus should be placed in the first field
+requiring information (see Guidelines 3.1).&nbsp; The header should be
+used to prompt the user for the first piece of required information.
+<p><img src="images/goodWizardInit.gif" height=122 width=570>
+<p>It is not appropriate to display an error message.&nbsp; At this point,
+the user hasn't done anything yet.
+<p><img src="images/badWizardInit.gif" height=124 width=576>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.3</font></b>
+<blockquote><font color="#09448D">Start the wizard with a prompt, not an
+error message.</font></blockquote>
+<hr>
+<p>
+The initial state of the wizard should be derived from the context where
+it is opened.&nbsp; For instance, in the New File wizard, the current workbench
+selection is examined.&nbsp; If it points to a valid project or folder,
+the wizard will pre-populate the parent field with the parent project or
+folder name, and put cursor focus in the next field requiring user input.&nbsp;
+If the user's selection does not point to a valid parent project or folder,
+the wizard will not pre-populate the folder name. Instead, it will leave
+the field blank and put the cursor focus in the field.&nbsp;&nbsp; When
+the user's selection is on a file, a wizard may also go through these calculations
+using the parent folder or project of the file.
+<p><img src="images/wizardFieldPopulation.gif" height=300 width=533>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.4</font></b>
+<blockquote><font color="#09448D">Seed the fields within the wizard using
+the current workbench state.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Validation of Data</h4>
+Information validation within a wizard should be done in tab order.&nbsp;
+If the first required field is empty, an informative prompt should be shown
+in the text area, directing the user to fill in the field.&nbsp; If the
+first required field is in error, an error message should be shown in the
+text area.&nbsp; If the first required field is valid, check the next field,
+and so on.&nbsp; The text area should not be used to display more than
+one prompt or error at a time.
+<p>If dialog information is absent or invalid, the Next or Finish buttons
+should be disabled until the situation is resolved.&nbsp; When resolution
+occurs, and all of the information has been provided, the Next or Finish
+buttons may be enabled.
+<p><img src="images/wizardErrorMsgs.gif" height=527 width=540>
+<p>Error messages should only be displayed when user input is invalid.
+<p><img src="images/wizardErrorMsgs2.gif" height=199 width=454>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.5</font></b>
+<blockquote><font color="#09448D">Validate the wizard data in tab order.&nbsp;
+Display a prompt when information is absent, and an error when information
+is invalid.</font></blockquote>
+<img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.6</font></b>
+<blockquote><font color="#09448D">Only enable the Next / Finish buttons
+if all required information in the dialog is present and valid.</font></blockquote>
+<hr>
+<p>
+The error messages in a wizard should be intended for the end user, not
+the developer.&nbsp; With this in mind, message IDs should never be presented
+as part of the error text in the wizard's header area.
+<p><img src="images/wizardMsgs.gif" height=98 width=543>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.7</font></b>
+<blockquote><font color="#09448D">Remove all programming message ID's from
+wizard text.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Browse Buttons</h4>
+An edit field and "Browse..." button combination should be used whenever
+an existing object is referenced within a wizard.&nbsp; The edit field
+is used for direct input of the existing object, and the Browse button
+is used to browse and select the object from a list of all possible choices.
+<p>For instance, in the New Java Class wizard, a "Browse..." button is
+placed beside the "Super Class" edit field.&nbsp; If the browse button
+is pressed, a Browse Dialog will appear, and the user can select a super
+class.&nbsp; This pattern should be used whenever a link will be established
+between a new object and an old one.&nbsp; The "Browse..." button should
+be located to the right of the edit field.
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.8</font></b>
+<blockquote><font color="#09448D">Use a Browse Button whenever an existing
+object is referenced in a wizard.</font></blockquote>
+<hr>
+<p>
+In the Browse Dialog, invalid choices should not appear.&nbsp; When the
+dialog is closed, and focus returns to the parent control, refresh the
+enablement state of controls within the dialog.&nbsp; In particular, refresh
+the enablement of Next, Finish, and OK buttons.
+<p>An example of valid and invalid filtering is shown in the following
+snapshot.
+<p><img src="images/folderSelection.gif" height=1220 width=611>
+<br>&nbsp;
+<h4>
+Wizard Completion</h4>
+The New Resource and Import Wizards commonly create new files, folders,
+and projects within the workbench.&nbsp; If a single file is created, the
+wizard should open the file in an editor in the active page.&nbsp; If more
+than one file is created, open the most important, or central file.&nbsp;
+This makes it easier to modify and save the file.
+<p>Have a readme.html file for every example project, and open that
+readme.html automatically upon project creation.&nbsp; This will give users
+an immediate overview of the example: what it does, prerequisites, limitations,
+steps to take, and so on.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.9</font></b>
+<blockquote><font color="#09448D">If a new file is created, open the file
+in an editor.&nbsp; If a group of files are created, open the most important,
+or central file in an editor. Open the readme.html file upon creation of
+an example project.</font></blockquote>
+<hr>
+<p>
+If a new project is created, the wizard should change the active perspective
+within the workbench to one which is appropriate for the new project type.
+In Eclipse v2.1, users are prompted to confirm the switch to the preferred perspective when creating a new project.
+To avoid loss of context, plug-ins should use this, and not automatically switch without prompting.
+If users want to switch automatically in the future, they can choose &quot;Do not show this message again&quot; in
+the confirmation dialog.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.10</font></b>
+<blockquote><font color="#09448D">If a new project is created, prompt users and change the
+active perspective to suit the project type.</font></blockquote>
+<hr>
+<p>
+In either case, where a file, folder, or project is created, the wizard
+should select and reveal the new object in the appropriate view.&nbsp;
+This provides concrete evidence to the user that, yes, the new object was
+created and now exists.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.11</font></b>
+<blockquote><font color="#09448D">If a new object is created, select and
+reveal the new object in the appropriate view.</font></blockquote>
+<hr>
+<p>
+In many situations, the creation of a resource may involve the creation
+of a project or folder to contain the resource.&nbsp; If the containing
+project or folder can be created from within the wizard (with a very reasonable
+set of defaults), the wizard should allow it. If the creation of such resources
+requires detailed user interaction in order for parent project or folder
+to be set up correctly, the wizard should not attempt to do this. Instead,
+the wizard error text should instruct the user that "The specified project
+does not exist".
+<p>The EAR Import wizard in IBM's WebSphere Studio is an example where allowing the user to specify
+the name of the parent project in place makes for a much more usable interaction.
+In this case, based on the user provided name, the wizard goes off and
+creates not only the EAR project itself, but also any web projects, etc.,
+that may be needed as well.
+<p><img src="images/goodParentCreation.gif" height=299 width=506>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.12</font></b>
+<blockquote><font color="#09448D">Create folder objects in a wizard if
+reasonable defaults can be defined.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Terminology</h4>
+Within a creation wizard, if the item being created must be a Project (not
+a folder below a project), the term "Project" should be used.&nbsp; If it can be a folder below the project, the term
+"Folder" should be used.&nbsp; In addition, use the &quot;name&quot; suffix (uncapitalized) and no other prefix for the input field label. For example, use &quot;Project name&quot; or &quot;Folder name&quot; but not &quot;Project Name&quot; or &quot;Server Project name&quot;.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+5.13</font></b>
+<blockquote><font color="#09448D">Use the term "Project name" for the input field label when the
+item must be a Project; otherwise, use the term "Folder name". Do not qualify
+the term.</font></blockquote>
+
+<p>
+
+<h3>
+<a NAME="Editors"></a>Editors</h3>
+An editor is a visual component within a workbench page. It is
+<FONT color="#000000">used to interact with the primary content, which
+may be a document or data object.&nbsp; In every case, this content is
+the primary focus of attention and a reflection of the primary task.</FONT>
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.1</font></b>
+<blockquote><font color="#09448D">Use an editor to edit or browse a file,
+document, or other primary content.</font></blockquote>
+<hr>
+<p>
+Modifications made in an editor follow an open-save-close lifecycle model.&nbsp;
+When an editor first opens, the editor contents should be unmodified (clean).&nbsp;
+If the contents are modified, the editor should communicate this change
+to the platform.&nbsp; In response, an asterisk will appear in the editor
+tab.&nbsp; The modifications should be buffered within the edit model,
+until such a time as the user explicitly saves them.&nbsp; At that point,
+the modifications should be committed to the model storage.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.2</font></b>
+<blockquote><font color="#09448D">Modifications made in an editor must
+follow an open-save-close lifecycle model.</font></blockquote>
+<hr>
+<p>
+An editor is document or input-centric.&nbsp; Each editor has an input,
+and only one editor can exist for each editor input within a page.&nbsp;
+This policy has been designed to simplify part management.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.3</font></b>
+<blockquote><font color="#09448D">Only one instance of an editor may exist,
+for each editor input, within a perspective.</font></blockquote>
+<hr>
+<p>
+In addition, it should be possible to open a separate instance of an editor
+for each different input.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.4</font></b>
+<blockquote><font color="#09448D">It must be possible to open a separate
+instance of an editor for each different input.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Appearance</h4>
+The editor should be labeled with the name of the resource being edited;
+not with the name of the editor.
+<p><img src="images/editorTitles.gif" height=84 width=562>
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.5</font></b>
+<blockquote><font color="#09448D">The editor should be labeled with the
+name of the file, document, or input being edited.</font></blockquote>
+<hr>
+<p>
+If the editor contains more than one page, a tab control should be used
+for page activation.&nbsp; The use of this control is demonstrated by the
+plugin file and html editors.
+<p>Tab labels should be kept to one word, and two words at most.
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.6</font></b>
+<blockquote><font color="#09448D">In multipage editors, use a tab control
+for page activation.Tab labels should be kept to one word, and two words
+at most.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Menus</h4>
+An editor may contribute items directly to the window menu bar.&nbsp; All
+of the commands available in the editor should be displayed in the window
+menu bar, for accessibility and clarity.
+Exceptions are for the obvious commands, e.g. basic navigations such as next / previous character, line, word.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.7</font></b>
+<blockquote><font color="#09448D">All of the commands, except for the obvious commands, available in the editor
+should be added to the window menu bar.</font></blockquote>
+<hr>
+<p>
+The following format is recommended, to ensure consistency across Eclipse
+and better ease of use.
+<br>&nbsp;
+<table class="indent" border="1" cellspacing="0" cellpadding="3" width="80%" cols="4">
+<tr>
+<td>Edit</td>
+
+<td>(one or more editor specific menus)</td>
+
+<td>Window</td>
+</tr>
+
+<tr>
+<td>Add any object centric commands here</td>
+
+<td>(commands belong to the specific menus)</td>
+
+<td>Actions to control what you see in the editor.</td>
+</tr>
+</table>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.8</font></b>
+<blockquote><font color="#09448D">Use the standard format for editor contributions
+in the window menu bar.</font></blockquote>
+<hr>
+<p>
+The window menu bar contains a number of global commands, such as Cut, Copy,
+and Paste in the Edit menu.&nbsp; These commands target the active part,
+as indicated by a shaded title area.&nbsp; If these commands are supported
+within an editor, the editor should hook these window commands, so that
+selection in the window menu bar or toolbar produces the same result as
+selection of the same command in the editor.&nbsp; The editor should not
+ignore these commands, and contribute duplicate commands to the window menu
+bar or toolbar.
+<p>A complete list of the global commands is declared in the IWorkbenchActionConstants.java
+(see below).
+<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * From IWorkbenchActionConstants.</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Standard global
+commands in a workbench window.</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final
+String [] GLOBAL_ACTIONS = {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+UNDO,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+REDO,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CUT,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+COPY,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+PASTE,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+PRINT,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+DELETE,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+FIND,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+SELECT_ALL,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+BOOKMARK</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</tt>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.9</font></b>
+<blockquote><font color="#09448D">If an editor has support for Cut, Copy,
+Paste, or any of the global commands, these commands must be executable from
+the same commands in the window menu bar and toolbar.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Toolbars</h4>
+An editor may contribute commands directly to the window toolbar.&nbsp;
+The toolbar is used to expose the
+<I>most commonly used</I>
+commands in an editor.&nbsp;
+Any command which appears in the toolbar must also appear in the menu, but
+there is no need to duplicate every command in the menu within the toolbar.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.10</font></b>
+<blockquote><font color="#09448D">Fill the editor toolbar with the most
+commonly used items in the view menu.</font></blockquote>
+<hr>
+<p>
+The use of a local toolbar within an editor is contrary to the design of
+the workbench.&nbsp; Within the workbench, the toolbar for an editor is
+shared with editors of the same type.&nbsp; This reduces the flash which
+occurs when you switch between editors, reduces the number of images and
+commands in the product, and creates a better feel of integration.
+<h4>
+Context Menus</h4>
+A context menu should be used for context sensitive interaction with the
+objects in an editor.&nbsp; If an object is selected in an editor, and
+the context menu is opened, the context menu should only contain commands
+which are appropriate for the selection.&nbsp; Commands which affect the
+presentation of the view should not appear in the context menu.
+<p>In a text editor, you may assume that there is only one type of selection:
+text.&nbsp; In this case, the contents of the context menu will remain
+consistent for any selection in the editor.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.11</font></b>
+<blockquote><font color="#09448D">Fill the context menu with selection
+oriented commands.</font></blockquote>
+<hr>
+<p>
+For consistency with other editors in Eclipse, each editor should adopt
+a common order for commands within the context menu.&nbsp; This format is
+shown in the following table.&nbsp; Within this table, each item represents
+a category of commands.&nbsp; The categories within the context menu should
+be kept distinct from one another through the use of separators.
+<br>&nbsp;
+<table class="indent" border="1" cellspacing="0" cellpadding="3" width="200" cols="1">
+<tr>
+<td>Undo / Redo</td>
+</tr>
+
+<tr>
+<td>Add</td>
+</tr>
+
+<tr>
+<td>Show In</td>
+</tr>
+
+<tr>
+<td>Cut Copy Paste</td>
+</tr>
+
+<tr>
+<td>Delete</td>
+</tr>
+
+<tr>
+<td>Other Plugin Additions</td>
+</tr>
+
+<tr>
+<td>Save</td>
+</tr>
+</table>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.12</font></b>
+<blockquote><font color="#09448D">Use the standard format for editor context
+menus.</font></blockquote>
+<hr>
+<p>
+For good spatial navigation, fill the context menu with a fixed set of
+commands for each selection type.&nbsp; Once the contents have been defined,
+the enablement state of each command should be determined using the selected
+object state.&nbsp; In doing so, you establish a consistency which makes
+the menu more predictable, and easier to navigate.
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.13</font></b>
+<blockquote><font color="#09448D">Fill the context menu with a fixed set
+of commands for each selection type, and then enable or disable each to
+reflect the selection state.</font></blockquote>
+<hr>
+<p>
+One of the primary goals for the platform UI is extensibility.&nbsp; In
+fact, it is this extensibility which gives you the freedom to add new views,
+editors, perspectives, and actions to the platform.&nbsp; Of course, extensibility
+is a two way street.&nbsp; While you may wish to extend the platform, others
+may wish to extend your view or editor.&nbsp; It is common for one plug-in
+to add actions to the menu, toolbar, or context menu of an editor from
+another plugin.
+<p>In the platform, the menu and toolbar for an editor are automatically extended
+ by the platform.&nbsp; In contrast, context menu extension is supported in collaboration
+ between the editor and the platform.&nbsp; To achieve this collaboration, an
+ editor must register each context menu it contains with the platform.&nbsp;
+ It should also define an command filter for each object type in the editor.&nbsp;
+ An command filter makes it easier for one plug-in to add an command to objects
+ in an editor defined by another plug-in.&nbsp; The target is described using
+ object type and attributes.&nbsp;&nbsp; For more information on the implementation
+ of this concept, refer to <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+ an Eclipse View.</a>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.14</font></b>
+<blockquote><font color="#09448D">Register all context menus in the editor
+with the platform.</font></blockquote>
+<img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.15</font></b>
+<blockquote><font color="#09448D">Implement an Command Filter for each object
+type in the editor.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Resource Deletion</h4>
+When a resource is deleted from one of the navigators (e.g., Navigator
+view, J2EE view, Data view, or DBA Explorer view in IBM's WebSphere Studio), the handling of any
+editor that is currently open on that resource depends on whether the editor has any unsaved changes.
+<p>If the editor does not contain any changes since the resource was last
+saved then the editor should be immediately closed.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.16</font></b>
+<blockquote><font color="#09448D">If the input to an editor is deleted,
+and the editor contains no changes, the editor should be closed.</font></blockquote>
+<hr>
+<p>
+If the editor contains changes to the resource since the resource was last
+saved (i.e., it is "dirty"), the editor should give the user a chance to
+save their changes to another location, and then close.&nbsp; Here is a
+sample of the dialog which should be displayed:
+<p><img src="images/fileDeletedDialog.gif" hspace="40" height=124 width=436>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.17</font></b>
+<blockquote><font color="#09448D">If the input to an editor is deleted,
+and the editor contains changes, the editor should give the user a chance
+to save their changes to another location, and then close.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Unsaved Changes</h4>
+If the editor contains changes to the resource since the resource was last
+saved (i.e., it is "dirty"), an asterisk should be used to prefix the resource
+name presented in the editor tab:
+<p><img src="images/dirtyEditor.gif" hspace="40" height=331 width=334>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.18</font></b>
+<blockquote><font color="#09448D">If the resource is dirty, prefix the resource
+name presented in the editor tab with an asterisk.</font></blockquote>
+<hr>
+<p>
+
+
+<h4>
+Read Only Files</h4>
+With a name like "editor", it's not surprising that the issue of read-only
+files may cause confusion.&nbsp; If it's read-only, how can you edit it?&nbsp;
+In this case, you should fall back to first principles.
+<blockquote>A view is typically used to navigate a hierarchy of information,
+open an editor, or display properties for the active editor.&nbsp; An editor
+is typically used to edit or browse a file, document or other input object.</blockquote>
+This statement is appropriate whether a file is read-only or not.&nbsp;
+In either case, the user should be able to select the file, open it, and
+browse the contents within an editor. If the file is read-only, the File
+> Save command should be disabled and the File > Save As should be enabled.
+In the status bar area, "Read-only" should be shown instead of the default
+"Writable" message.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.19</font></b>
+<blockquote><font color="#09448D">Treat read-only editor input as you would
+any other input.&nbsp; Enable the Save As if possible. Display "Read-only"
+in the status bar area.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Integration with Other Views</h4>
+In Eclipse, there is a special relationship between each editor and the
+Outline view.&nbsp; When an editor is opened, the Outline view will connect
+to the editor, and ask it for an outline model.&nbsp; If the editor answers
+an outline model, that model will be displayed in the Outline view whenever
+the editor is active.&nbsp; The outline is used to navigate through the content, or interact with the edit data at a higher level of abstraction.
+<p>For instance, if you open a .java file in an editor, the structure of
+the class is displayed in the Outline view.&nbsp; If you select a method
+or field in the outline, the text declaration of that item will be selected
+and revealed in the editor.&nbsp;&nbsp; If you select a method or field,
+and open the context menu, you can interact with the item as a conceptual
+unit, rather than just a bunch of text.
+<p>In general, an editor should provide an outline model to the Outline
+view if the data within the editor is too extensive to see on a single
+screen, and will yield a structured outline.&nbsp; This structured outline
+makes it very easy to navigate through objects like a java file or html
+file.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.20</font></b>
+<blockquote><font color="#09448D">If the data within an editor is too extensive
+to see on a single screen, and will yield a structured outline, the editor
+should provide an outline model to the Outline view.</font></blockquote>
+<hr>
+<p>
+
+<p><br>When an editor has an interaction with the Outline view, notification
+about location should be two-way. That is, the user should be able to select
+something in the outline and have the editor position updated, and the
+user should be able to select something in the editor pane and have the
+outline view updated.
+<p>A context&nbsp; menu should be available, as appropriate, in the outline
+view which should support creation operations as appropriate.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.21</font></b>
+<blockquote><font color="#09448D">Notification about location between an
+editor and the Outline view should be two-way. A context menu should be available
+in the Outline view as appropriate.</font></blockquote>
+<hr>
+<p>
+
+<p><br>If the edit model contains errors or warnings, they should be indicated
+in the Outline view.&nbsp; An error or warning image should be added to
+the item with the error or warning respectively.&nbsp; A container should have a red X if it there are errors on the container itself, a gray X if any of its descendents have errors (but not the container itself), and no X if neither the container nor any of its descendents have errors. For instance, in the
+following line, the addFastView method has an error, so an error image
+is added to the item and its parent.
+<br>&nbsp;
+<p><img src="images/errorsInOutline.gif" hspace="40" height=284 width=223>
+<br>&nbsp;
+<p>For this to work, care must be taken to design icons with overlay in
+mind, so that glyphs can be applied to the ancestor's icon.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.22</font></b>
+<blockquote><font color="#09448D">An error or warning image should be added
+to items with the error or warning respectively. A container should have a red X if it there are errors on the container itself, a gray X if any of its descendents have errors (but not the container itself), and no X if neither the container nor any of its descendents have errors.</font></blockquote>
+<hr>
+<p>
+In an editor, task objects are commonly used to mark a location within
+a document.&nbsp; Once a task has been created, it appears in the Task
+view.&nbsp; If the task is selected, you may reopen the editor at the location
+defined in the Task.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.23</font></b>
+<blockquote><font color="#09448D">If appropriate, implement the "Add Task"
+feature in your editor.</font></blockquote>
+<hr>
+<p>
+A bookmark object can also be used mark a location within a document.&nbsp;
+Once a bookmark has been created, it appears in the Bookmarks view.&nbsp;
+If the bookmark is selected, you may reopen the editor at the location
+defined in the Task.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.24</font></b>
+<blockquote><font color="#09448D">If appropriate, implement the "Add Bookmark"
+feature in your editor.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Line Numbers</h4>
+Editors with source lines of text should have line numbers, and optionally
+column numbers.&nbsp; Editors should also support Navigate -> Goto Line...
+menu allowing users to quickly jump to a desired
+line.&nbsp; The current line and column numbers should be shown in the status line (column number is optional). It's optional for the editor to show line numbers for each line in the editor itself.
+<BR>
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.25</font></b>
+<blockquote><font color="#09448D">Editors with source lines of text should show the current line and optionally column numbers the status line. It's optional for the editor to show line numbers for each line in the editor itself.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Table Cell Editors</h4>
+<P>If the editor contains tables with editable cells, a single-click over a cell should select the current item and put the cell
+into edit mode. In edit mode, any dropdowns, buttons, or other controls
+in the cell should be rendered upon the single-click.</P><p><img src="images/cellTableEditor.gif" hspace="40" height=383 width=284>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.26</font></b>
+<blockquote><font color="#09448D">Table cell editors should support the
+single-click activation model, and in edit mode, they should render complex
+controls upon single-click.</font></blockquote>
+<hr>
+<p>
+
+<p><br>In addition, changes should be committed once a user clicks off
+the cell or hits ENTER.
+<p>The following are examples of good behaviour for a table cell editor:
+<p>- when put in edit mode, drop-down appears with current selection active
+&amp; highlighted
+<br><img src="images/cell1.gif" hspace="40" height=17 width=114>
+<p>- when cursoring through drop-down using arrow keys, it is possible
+to move up and down any number of choices and the drop-down stays visible
+until user makes an explicit selection
+<br><img src="images/cell2.gif" hspace="40" height=97 width=56>
+<p>- first letter navigation is supported as a cursoring technique when
+the drop-down is visible
+<br>- supports the "Enter" key as a way of making an explicit selection
+via the keyboard when the drop-down is visible
+<br>- supports the "Esc" key as a way of canceling a selection via the
+keyboard when the drop-down is visible
+<br>- when put in edit mode, the drop-down control (the down-arrow image) appears with current selection active
+&amp; highlighted
+<br><img src="images/cell3.gif" hspace="40" height=17 width=114>
+<p>- when put in edit mode, it is possible to arrow key through the choices
+to make a selection without needing to invoke the drop-down
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.27</font></b>
+<blockquote><font color="#09448D">Changes made in a table cell editor should
+be committed when a user clicks off the cell or hits the "Enter" key. Selection
+should be cancelled when user hits the "Esc" key.First letter navigation
+should be supported as a cursoring mechanism within a cell.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Error Notification</h4>
+If you are doing keystroke by keystroke validation in an editor, use red squiggles to underline the invalid content. When users move the mouse over the red squiggles, display the error text in a fly-over pop up box.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.28</font></b>
+<blockquote><font color="#09448D">When performing fine-grain error validation
+in an editor, use red squiggles to underline the invalid content. When users move the mouse over the red squiggles, display the error text in a fly-over pop up box.</font></blockquote>
+<hr>
+<p>
+When the Save command is invoked in an editor, use the Task view for showing
+errors which are persisted.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.29</font></b>
+<blockquote><font color="#09448D">Use the Task view to show errors found
+when the Save command is invoked.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Interaction With External Editors</h4>
+While a resource is opened within the workbench, if modifications are made
+to it outside of the workbench, we recommend the following approach to
+handle this situation. When the Save command is invoked in the editor, users
+should be prompted to either override the changes made outside of the workbench,
+or back out of the Save operation.
+If desired, this user prompt can be invoked sooner such as when the editor regains the focus.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+6.30</font></b>
+<blockquote><font color="#09448D">If modifications to a resource are made
+outside of the workbench, users should be prompted to either override the
+changes made outside of the workbench, or back out of the Save operation
+when the Save command is invoked in the editor.</font></blockquote>
+
+
+<h3>
+<a NAME="Views"></a>Views</h3>
+A view is a visual component within a workbench page.&nbsp; It is<font color="#000000">
+used in a support role for the primary task.&nbsp; You use them to navigate
+a hierarchy of information, open an editor, or view properties for the
+active editor.</font>
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.1</font></b>
+<blockquote><font color="#09448D">Use a view to navigate a hierarchy of
+information, open an editor, or display the properties of an object.</font></blockquote>
+<hr>
+<p>
+Modifications made in a view should be saved immediately.&nbsp; For instance,
+if a file is modified in the Navigator, the changes are committed to the
+workspace immediately.&nbsp; A change made in the Outline view is committed
+to the edit model of the active editor immediately.&nbsp; For changes made
+in the Properties view, if the property is a property of an open edit model,
+it should be persisted to the edit model. If it is a property of a file,
+persist to file.
+<p>In the past, some views have tried to implement an editor style lifecycle,
+with a Save command.&nbsp; This can cause confusion.&nbsp; The File menu
+within a workbench window contains a Save command, but it only applies to
+the active editor.&nbsp; It should not target the active view.&nbsp; This
+leads to a situation where the File > Save command is in contradiction to
+the Save command within the view.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.2</font></b>
+<blockquote><font color="#09448D">Modifications made within a view must
+be saved immediately.</font></blockquote>
+<hr>
+<p>
+Within a perspective, only one instance of a particular view can be opened.&nbsp;
+This policy is designed to simplify part management for a user.&nbsp; The
+user opens a view by invoking Perspective > Show View.&nbsp; If, for any
+reason, they lose a view, or forget about its existence, they can simply
+invoke Perspective > Show view again to make the view visible.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.3</font></b>
+<blockquote><font color="#09448D">Only one instance of a view may exist
+in a perspective.</font></blockquote>
+<hr>
+<p>
+In a multi-tasking world, humans often perform more than one task at a
+time.&nbsp; In Eclipse, task separation can be achieved by creating a separate
+perspective for each task.&nbsp; In reflection of this, a view must be able to be opened in more than one perspective.&nbsp; If only one
+instance of a view may exist, the ability to multi-task is taken away.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.4</font></b>
+<blockquote><font color="#09448D">A view must be able to be opened in more than one perspective.</font></blockquote>
+<hr>
+<p>
+A view can be opened in two ways: by invoking Window > Show View >
+X menu, where X is the name of the view, or by invoking another command
+within the workbench.&nbsp; For instance, if you select a class in the
+Packages view, and invoke Open Type Hierarchy, a Hierarchy view opens with
+the class hierarchy for the selection.
+<p>It should be possible to open any view from the Window > Show View
+menu, either as an explicit item within the menu, or as an item within
+the Window > Show View > Other... dialog.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.5</font></b>
+<blockquote><font color="#09448D">A view can be opened from the Window
+> Show View menu.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Appearance</h4>
+A view consists of a title area, a toolbar, a pulldown menu, and an embedded
+control.
+<p>The view label in the title bar must be prefixed with label of the view
+in Perspective > Show View menu.&nbsp; Given that it is impossible to change
+the entry in the Show View menu, this means you cannot change the name
+of a view.&nbsp; However, you can add additional text to the view label,
+to clarify the state of the view.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.6</font></b>
+<blockquote><font color="#09448D">The view label in the title bar must
+be prefixed with the label of the view in the Perspective > Show View menu.</font></blockquote>
+<hr>
+<p>
+In most cases, a view will contain a single control or viewer.&nbsp; However,
+it is possible to embed more than one viewer or control in the view.&nbsp;
+If these controls are linked, such that selection in one control changes
+the input of another, it may be better to separate the view into two. Users
+will have greater freedom to open one of the results views, as their needs
+arise. Special relationships can also be set up between these views to
+support the user task. In addition, this makes it easier for users to create
+a new perspective with a diverse set of views.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.7</font></b>
+<blockquote><font color="#09448D">If a view contains more than one control,
+it may be advisable to split it up into two or more views.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Initialization</h4>
+When a view is opened, the input of the view should be derived from the
+state of the perspective.&nbsp; The view may consult the window input
+or selection, or the state of another view.&nbsp; For instance, if the
+Outline view is opened, it will determine the active editor, query the
+editor for an outline model, and display the outline model.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.8</font></b>
+<blockquote><font color="#09448D">When a view first opens, derive the view
+input from the state of the perspective.</font></blockquote>
+<hr>
+<p>
+If the view is used to navigate a hierarchy of resources (i.e., the Navigator
+or Packages view), the input of the view may be derived from the window
+input.&nbsp; The window input defines the scope of visible resources
+within the perspective, and is defined by the user if they select a resource
+in the Navigator and invoke Open in New Window.&nbsp; For instance, if the
+Navigator view is opened, it will ask its perspective for the window
+input.&nbsp; The result is used as the initial input for the view.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.9</font></b>
+<blockquote><font color="#09448D">If a view displays a resource tree, consider
+using the window input as the root of visible information in the view.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Menus</h4>
+<P>Use the view pulldown menu for presentation commands, not
+selection-oriented commands.&nbsp;
+These are commands which affect the presentation of the view, but not the
+objects within the view.&nbsp;Do not put presentation commands in the context menu. For instance, the Sort and Filter commands
+within the Navigator view affect the presentation of resources, but do
+not affect the resources themselves.
+</P><p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.10</font></b>
+<blockquote><font color="#09448D">Use the view pulldown menu for presentation commands, not
+selection-oriented commands.</font></blockquote>
+<hr>
+<p>
+For consistency with other views in Eclipse, each view should adopt a common
+order for commands within the pulldown menu.&nbsp; This order is shown
+in the following table.
+<br>&nbsp;
+<table class="indent" border="1" cellspacing="0" cellpadding="3" cols="1" width="654">
+<tr>
+<td width="415">View modes (e.g. the 3 modes in the Hierarchy view)</td>
+</tr>
+
+ <TR>
+ <TD width="415" height="38">[separator required]</TD>
+ </TR>
+ <TR>
+ <TD width="415" height="35">Working sets (e.g. Select/Deselect/Edit Working Set, used in Navigator and Package Explorer)</TD>
+ </TR>
+ <TR>
+ <TD width="415" height="33">[separator required]</TD>
+ </TR>
+ <TR>
+ <TD width="415">Sorting</TD>
+ </TR>
+ <TR>
+ <TD width="415">[optional separator]</TD>
+ </TR>
+ <TR>
+ <TD width="415">Filtering</TD>
+ </TR>
+ <TR>
+ <TD width="415">[optional separator]</TD>
+ </TR>
+ <TR>
+ <TD width="415">View layout (e.g. Horizontal vs. Vertical in Hierarchy view)</TD>
+ </TR>
+ <tr>
+<td width="415">[optional separator]</td>
+</tr>
+
+ <TR>
+ <TD width="415">Link with Editor</TD>
+ </TR>
+ <TR>
+ <TD width="415">[separator required]</TD>
+ </TR>
+ <tr>
+<td width="415">Other presentation commands from the view itself</td>
+</tr>
+
+ <TR>
+ <TD width="415">[separator required]</TD>
+ </TR>
+ <TR>
+ <TD width="415">Presentation commands from other plug-ins</TD>
+ </TR>
+</table>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.11</font></b>
+<blockquote><font color="#09448D">Use the standard order of commands for view pulldown
+menus.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Toolbars</h4>
+The toolbar is used to expose the most commonly used commands in a view.&nbsp;
+Any command which appears in the toolbar must also appear in the menu (either the context menu or the view menu), but
+there is no need to duplicate every command in the menu within the toolbar.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.12</font></b>
+<blockquote><font color="#09448D">Put only the most commonly used commands on the toolbar. Any command on a toolbar must also appear in a menu, either the context menu or the view menu.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Context Menus</h4>
+A context menu should be used for context sensitive interaction with the
+objects in a view.&nbsp; If an object is selected in a view, and the context
+menu is opened, the context menu should only contain actions which are
+appropriate for the selection.&nbsp; Actions which affect the presentation
+of the view should not appear in the context menu.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.13</font></b>
+<blockquote><font color="#09448D">Fill the context menu with selection
+oriented actions, not presentation actions.</font></blockquote>
+<hr>
+<p>
+For consistency with other views in Eclipse, each view should adopt a common
+order for commands within the context menu.&nbsp; This order is shown in
+the following table.&nbsp; Within this table, each item represents a category
+of commands.&nbsp; The categories within the context menu should be kept
+distinct from one another through the use of separators.
+<br>&nbsp;
+
+<table class="indent" border="1" cellspacing="0" cellpadding="3" width="477" cols="1">
+<tr>
+<td>New</td>
+</tr>
+
+<tr>
+<td>Open</td>
+</tr>
+
+<tr>
+<td>Navigate + Show In</td>
+</tr>
+
+<tr>
+<td>Cut, Copy, Paste, Delete, Move, Rename and other refactoring commands</td>
+</tr>
+
+<tr>
+<td>Other Plugin Additions</td>
+</tr>
+
+<tr>
+<td>Properties</td>
+</tr>
+</table>
+
+<p>The New category contains actions which create new objects.&nbsp; The
+Open category contains actions which open the selection in an editor.&nbsp;
+Navigate contains actions to refocus the view input, or reveal the view
+selection in another view.&nbsp; And the other categories are self explanatory.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.14</font></b>
+<blockquote><font color="#09448D">Use the standard order of commands for view context
+menus.</font></blockquote>
+<hr>
+<p>
+For good spatial navigation of the menu, fill the context menu with a fixed set of
+commands for each selection type.&nbsp; Once the contents have been defined,
+the enablement state of each command should be determined using the selected
+object state.&nbsp; In doing so, you establish a consistency which makes
+the menu more predictable, and easier to navigate.
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.15</font></b>
+<blockquote><font color="#09448D">Fill the context menu with a fixed set
+of commands for each selection type, and then enable or disable each to
+reflect the selection state.</font></blockquote>
+<hr>
+<p>
+An object in one view may be visible in many other views or editors.&nbsp;
+For instance, a .java file is visible in the Navigator, the Hierarchy view,
+and the Packages view.&nbsp; To the user, these objects are all the same,
+regardless of location, so the context menu for the .java file should be
+the same in each.
+<p>Implementation tip:<BR>
+To achieve a consistent context menu, plug-in developers which introduce
+a new object type should contribute commands to the context menu using an
+action group(ActionGroup class), a Java class which populates the context menu.&nbsp; If
+this approach is used, the action group can be reused by other views where the
+same objects appear.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.16</font></b>
+<blockquote><font color="#09448D">If an object appears in more than one
+view, it should have the same context menu in each.</font></blockquote>
+<hr>
+<p>
+One of the primary goals for the platform UI is extensibility.&nbsp; In
+fact, it is this extensibility which gives you the freedom to add new views,
+editors, perspectives, and actions to the platform.&nbsp; Of course, extensibility
+is a two way street.&nbsp; While you may wish to extend the platform, others
+may wish to extend your view or editor.&nbsp; It is common for one plug-in
+to add actions to the menu, toolbar, or context menu of a view from another
+plugin.
+<p>In the platform, the menu and toolbar for a view are automatically extended
+ by the platform.&nbsp; In contrast, context menu extension is supported in collaboration
+ between the view and the platform.&nbsp; To achieve this collaboration, a view
+ must register each context menu it contains with the platform.&nbsp; It should
+ also define an command filter for each object type in the view.&nbsp; An command
+ filter makes it easier for one plug-in to add an command to objects in a view
+ defined by another plug-in.&nbsp; The command target is described using object
+ type and attributes.&nbsp;&nbsp; For more information on the implementation
+ of this concept, refer to <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+ an Eclipse View.</a>
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.17</font></b>
+<blockquote><font color="#09448D">Register all context menus in the view
+with the platform.</font></blockquote>
+<img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.18</font></b>
+<blockquote><font color="#09448D">Implement an Command Filter for each object
+type in the view.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Integration with the Window Menu Bar and Toolbar</h4>
+The window menu bar contains a number of global commands, such as Cut, Copy,
+and Paste within the Edit menu.&nbsp; These commands target the active part,
+as indicated by a shaded title area.&nbsp; If these commands are supported
+within a view, the view should hook these window commands, so that selection
+in the window menu bar or toolbar produces the same result as selection
+of the same command in the view.
+<p>A complete list of the global commands and built-in menus as declared in IWorkbenchActionConstants.java
+(see below).
+<p><tt></tt>File menu: Revert, Move, Rename, Refresh, Print, Properties<BR>
+Edit menu: Undo, Redo, Cut, Copy, Paste, Delete, Select All, Find/Replace, Add Bookmark, Add Task<BR>
+Navigate menu: Go Into, Back, Forward, Up One Level, Next, Previous, Back, Forward<BR>
+Project menu: Open Project, Close Project, Build Project, Rebuild Project
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.19</font></b>
+<blockquote><font color="#09448D">If a view has support for Cut, Copy,
+Paste, or any of the global commands, these commands must be executable from
+the same commands in the window menu bar and toolbar.</font></blockquote>
+<hr>
+<p>
+<font color="#000000">Although a view can't directly contribute to the main menubar or toolbar in Eclipse v2.1, it can still cause commands to appear there using &quot;action set / part associations&quot; (the actionSetPartAssociations extension point) which lets you associate action sets with particular parts (views or editors). For example, the Java tooling in Eclipse uses this for the Package Explorer.<BR>
+<BR>
+All commands for the view (or editor) should be made available on the main menubar, and only frequently used commands are on the context menu.<BR>
+<BR>
+In addition, the primary perspective(s) for such views (e.g. the Java and Java Browsing perspectives) should already have these action sets associated with the perspective, to improve UI stability.<BR>
+<BR></font></P>
+<h4>
+Persistence</h4>
+One of the primary goals for the platform UI is to provide efficient interaction
+with the workspace.&nbsp; In the platform this is promoted by saving the
+state of the workbench when a session ends (the workbench is shut down).&nbsp;
+When a new session is started (the workbench is opened), this state is
+restored, reducing the time required for the user to get back to work.
+<p>If a view has a static input object, in the sense that its input is not derived
+ from selection in other parts, the state of the view should be persisted between
+ sessions. If a view has a dynamic or transient input object, there is no need
+ to persist its state between sessions. Within the workbench, the state of the
+ Navigator view, including the input and expansion state, is saved between sessions.
+ For more information on the implementation of persistence, see "<a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+ an Eclipse View</a>". <br>
+ &nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+7.20</font></b>
+<blockquote><font color="#09448D">Persist the state of each view between
+sessions.</font></blockquote>
+
+<p><BR></P>
+
+<HR>
+<P><FONT color="#000000">Navigation views should support &quot;Link with
+Editor&quot; on the view menu. In Eclipse v2.1, this feature works on a
+per-view setting. If it's expected that users will toggle it frequently,
+then it can also go on the toolbar, but this is not required (the
+Hierarchy view and the views in the Java Browsing perspective support
+it, but don't have it on the toolbar, since they expect linking to
+almost always be on).<BR>
+<BR>
+The behaviour of &quot;Link with Editor&quot; is:</FONT></P>
+<UL>
+ <LI>when toggled off, no linking occurs (either view-&gt;editor or
+ editor-&gt;view)</LI>
+ <LI>when toggled on, linking occurs in both directions:
+ <UL>
+ <LI>view-&gt;editor: when the selection is changed in the view, it
+ brings any corresponding previously-open editor to front, but does not
+ activate it (the view must keep focus)</LI>
+ <LI>editor-&gt;view: when the user switches between editors, the view
+ updates its selection to correspond to the active editor</LI>
+ </UL>
+ </LI>
+ <LI>when turned on, it should immediately synchronize the selection in
+ the view with the frontmost editor, if applicable</LI>
+ <LI>this is not the same as single-click mode -- it does not cause new
+ editors to be opened</LI>
+ <LI>changing the setting affects only the current view instance, not
+ other instances of the same type</LI>
+ <LI>the view should persist the state of this setting separately for
+ each view instance, and also globally (but separately for each view
+ type, e.g. Navigator and Package Explorer persist their last setting
+ separately)</LI>
+ <LI>when opening a new instance of the view, it should use the last
+ global setting</LI>
+ <LI>the default setting (if there's no previously persisted global
+ setting) is up to the view, but primary navigation views like the
+ Navigator and Package Explorer default to off</LI>
+</UL>
+<P><IMG src="images/guidelineIndicator.gif" height="16" width="16"><B><FONT
+ color="#09448D">Guideline 7.21</FONT></B></P>
+<BLOCKQUOTE><FONT color="#09448D"><FONT
+ color="#000000"></FONT>Navigation views should
+support &quot;Link with Editor&quot; on the view menu<FONT color="#000000"></FONT></FONT></BLOCKQUOTE>
+
+<P><BR>
+
+</P>
+<h3>
+<a NAME="Perspectives"></a>Perspectives</h3>
+A perspective is a visual container for a set of views and editors (parts).&nbsp;
+Different perspectives can have different sets of views open, but if they both have the same view open, it's shared between them (but only if they are in the same workbench window). Editors are always all shared between perspectives in the same window.
+<p>A new perspective is opened by invoking Window -> Open Perspective -> X, where
+X identifies a particular perspective in Eclipse.&nbsp; The result is a
+new perspective in the workbench window with <i>type</i> X.&nbsp; For instance,
+if you invoke Window -> Open Perspective -> Resource, a new perspective is opened
+with type <i>Resource</i>.&nbsp; Eclipse comes with a pre-defined number
+of perspective types, such as Resource, Java, and Debug.&nbsp; The perspective
+type determines the initial layout of views, and visibility of command sets
+within the perspective.
+<p>As a plug-in developer, you may contribute new perspective types to Eclipse.&nbsp;
+ To do this, you must define a perspective extension.&nbsp; Each extension has
+ a <i>perspective factory</i>, a Java class which defines the initial layout
+ of views, and visibility of command sets within the perspective.&nbsp; You can
+ also add your own actions or views to an existing perspective type.&nbsp; For
+ more information on the implementation of these concepts, see <a href="http://www.eclipse.org/articles/using-perspectives/PerspectiveArticle.html" target="_top">Using
+ Perspectives in the Eclipse UI</a>.
+<p>A new perspective type should be created when there is a group of related
+non-modal tasks which would benefit from a predefined configuration of commands and
+views, and these tasks are long lived.&nbsp; A task oriented approach is
+imperative.&nbsp; As a development environment, Eclipse was designed to
+fulfill the needs of a large product development team, from product manager
+to content developer to product tester.&nbsp; It is fully extensible and
+may be configured with hundreds of command, wizard, view and editor extensions.&nbsp;
+In other words, it may contain a lot of features you'll never use.&nbsp; To
+avoid the visual overload and confusion which would occur if everything
+was visible in the UI, a perspective can be used to limit the presentation to a task-oriented set of views and command sets.
+<p>For instance, the task of Java code creation is long lived and complex,
+so the creation of a Java perspective is warranted.&nbsp; In Eclipse, the
+Java perspective contains an editor area, Packages Explorer view, Hierarchy view,
+Tasks view, and Outline view.&nbsp; The Java and Debug command sets are
+also visible.&nbsp; Together, these components are useful for a variety
+of long lived, Java coding tasks.
+<p>It is not appropriate to create a new perspective type for short lived
+tasks.&nbsp; For instance, the task of resource check-in is short lived,
+so it may be better performed using a view in the current perspective.
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.1</font></b>
+<blockquote><font color="#09448D">Create a new perspective type for long
+lived tasks, which involve the performance of smaller, non-modal tasks.</font></blockquote>
+<hr>
+<p>
+If your plug-in contributes a small number of views, and these augment
+an existing task, it is better to add those views to an existing perspective.&nbsp;
+For instance, if you create a view which augments the task of Java code
+creation, don't create a new perspective.&nbsp; Instead, add it to the
+existing Java perspective.&nbsp; This strategy provides better integration
+with the existing platform.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.2</font></b>
+<blockquote><font color="#09448D">If you just want to expose a single view,
+or two, extend an existing perspective type.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+View Layout</h4>
+If the user opens a new perspective, the initial layout of views will be
+defined by the perspective type (i.e., Resource, Java).&nbsp; This
+layout is performed in the <i>perspective factory</i>, a Java class associated
+with the perspective type.&nbsp; When the perspective is initialized, it
+consists of an editor area with no additional views.&nbsp; The perspective
+factory may add new views, using the editor area as the initial point of
+reference.
+<p>The size and position of each view is controlled by the perspective
+factory.&nbsp;&nbsp; These attributes should be defined in a reasonable
+manner, such that the user can resize or move a view if they desire it.
+An important issue to consider is the overall flow between the views (and editors) in the perspective. For example, initially the navigation views may be placed to the left of the editor area, outline views may be placed either to the right of the editor area or below the navigation view, and other supporting views may be placed below and to the right of the editor area.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.3</font></b>
+<blockquote><font color="#09448D">The size and position of each view in
+a perspective should be defined in a reasonable manner, such that the user
+can resize or move a view if they desire it. When defining the initial layout, it is important to consider the overall flow between the views (and editors) in the perspective.</font></blockquote>
+<hr>
+<p>
+A perspective should have at least two parts, including the visible views
+and the editor area.&nbsp; If this is not the case, then the perspective
+should be re-examined to determine if it is better suited as a view or
+editor.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.4&nbsp;</font></b>
+<blockquote><font color="#09448D">If a perspective has just one part, it
+may be better suited as a view or editor.</font></blockquote>
+<hr>
+<p>
+In some scenarios, it may be undesirable to have an editor area within
+a perspective.&nbsp; In this case, the perspective factory should hide
+the editor area, using the existing java methods.&nbsp; It is not acceptable
+to resize the editor area to a point where it is no longer visible.&nbsp;
+If the user does open an editor in the perspective, for whatever reason,
+they will be unable to see or resize it.
+<p>When the editor area is programmatically hidden, if the user opens an
+editor in the perspective, the editor area will become visible. The view
+that occupied the editor area before will be shrunk. Therefore, it is
+important to define a non-empty editor area even when the editor is programmatically
+hidden.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.5</font></b>
+<blockquote><font color="#09448D">If it is undesirable to have an editor
+area in a perspective, hide it.&nbsp; Do not resize the editor area to
+the point where it is no longer visible.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Command Contribution</h4>
+The perspective factory may add actions to the File > New, Window > Open Perspective
+, and&nbsp; Window > Show View menus.&nbsp; It is also possible
+to add one or more command sets to the window.&nbsp; In each case, you should
+choose commands which are relevant to the task orientation of the perspective.
+<p>The File > New menu should be populated with wizards for the creation
+of objects commonly used in the task.&nbsp; For instance, in the Java perspective
+the File > New menu contains menu items for the creation of packages, classes,
+and interfaces.
+<p>The Window > Show View menu should be populated with the initial
+views in the perspective, as well as any extra views that may be important
+for the task at hand.
+The Navigate &gt; Show In menu should be used to allow users to navigate in their contents.<p><img src="images/showViewMenu.gif" hspace="40" height=325 width=486>
+<br>&nbsp;
+<p>The application development lifecycle should be considered when populating
+the the Window - Open Perspective menu.&nbsp; The development of most applications
+follow a well defined lifecycle, from designing / modeling, to editing
+/ creating, to debugging / testing, to assembling / deploying.&nbsp; Each
+perspective will fall into one of these steps.&nbsp; The Open
+Perspective menu should be used to link the current perspective to perspectives
+that support tasks immediately downstream of the current one, as well as
+tasks further upstream, to allow for iterative development.
+<p>For instance, the Java perspective is used in a larger lifecycle, involving
+Java and Debug tasks.&nbsp; The Window > Open Perspective menu is populated
+with each of these perspectives.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.6</font></b>
+<blockquote><font color="#09448D">Populate the window menu bar with commands
+and command sets which are appropriate to the task orientation of the perspective,
+and any larger workflow.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Opening a Perspective in Code</h4>
+An command should only open a new perspective if the user explicitly states
+a desire to do so.&nbsp; If the user does not state a desire to do so,
+it may cause loss of context.
+<p>For instance, imagine a scenario where the user selects an object and
+invokes an command.&nbsp; In the perspective where the command is invoked,
+the user may have a set of views and editors open.&nbsp; These represent
+the working state, or context, of the user.&nbsp; If a new perspective
+is created, that context will be left behind, forcing the user to recreate
+the context.&nbsp; This is time wasted.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.7 </font></b>
+<blockquote><font color="#09448D">A new perspective should be opened only
+if the user explicitly states a desire to do so.&nbsp; In making this statement,
+the user agrees to leave their old context, and create a new one.</font></blockquote>
+<hr>
+<p>
+In some cases, a new perspective is opened as the side effect of another
+command.&nbsp; For instance, if users start debugging their application code, they may be switched to the Debug perspective.&nbsp; If this
+behavior is implemented, the user should have the option to turn this behavior
+off.&nbsp; The option can be exposed in the command dialog, or within a
+Preference page.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.8</font></b>
+<blockquote><font color="#09448D">If a new perspective is opened as a side
+effect of another command, the user should be able to turn this behavior
+off.</font></blockquote>
+<hr>
+<p>
+If a new perspective is opened, it may be opened within the current
+window, or in a new window.&nbsp; The user controls this option using the
+Workbench preferences.&nbsp; If code within a plug-in opens a new perspective,
+the plug-in should honor the user preference.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.9</font></b>
+<blockquote><font color="#09448D">If a new perspective is opened, it should
+be opened within the current window, or in a new window, depending
+on the user preference.</font></blockquote>
+<hr>
+<p>
+With regard to command contributions applied to the New, Open Perspective,
+and Show View menus, the list of wizards, perspectives, and views added
+as shortcuts to these menus should be at most 7 plus / minus 2 items.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+8.10</font></b><blockquote><font color="#09448D">The list of shortcuts added to the New,
+Open Perspective, and Show View menus should be at most 7 plus / minus
+2 items.</font></blockquote>
+
+<p><br>
+
+<h3>
+<a NAME="Windows"></a>Windows</h3>
+In this section we look at the window menu bar, toolbar, and layout.&nbsp;
+As a plug-in developer, you can contribute actions to the menu bar and
+toolbar using an <i>action set</i>, a set of task oriented actions which
+the user can show or hide.&nbsp; You can control the layout of views within
+a window by defining a <i>perspective</i>.&nbsp; In this section we'll
+look at action extension.&nbsp; For more information on perspectives, see
+<a href="#Perspectives">Perspectives</a>.
+<h4>
+Actions</h4>
+Each workbench window contains a menu bar and toolbar.&nbsp; These are
+pre-populated by the platform, but a plug-in developer may add additional
+items to each.&nbsp; This is done by defining an <i>action set</i>, a set
+of task oriented actions which the user can show or hide.&nbsp; The actions
+within an action set may be distributed throughout the window menu bar
+and toolbar.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+9.1</font></b>
+<blockquote><font color="#09448D">Use an Action Set to contribute actions
+to the window menu bar and toolbar.</font></blockquote>
+<hr>
+<p>
+The window menu bar contains a number of pulldown menus: File, Edit, Navigate,
+Project, Window, and Help.&nbsp; Each of these has a different purpose,
+which will be explained in the following paragraphs.&nbsp; For consistency
+with the action sets contributed by other plug-ins, the commands within
+an action set should conform to the existing distribution of actions in
+the window.&nbsp; There is no need to group the actions in a separate pulldown
+menu of the menu bar.
+<p>The File menu contains file oriented actions, such as Save, Close, Print,
+Import, Export and Exit.&nbsp; The contents of the File > New menu are
+determined by the perspective type.&nbsp; However, the user may add or
+remove items using the Window -> Customize Perspective... menu item.&nbsp; The contents
+of the Import and Export dialogs are populated with every import and export
+wizard, respectively.
+<p>The Edit menu contains editor oriented actions, such as Undo, Redo,
+Cut, Copy, and Paste.&nbsp; These actions target the active part (as indicated
+by a shaded title bar) .&nbsp; It is very common for an editor to add items
+to this menu.&nbsp; However, it is uncommon for an action set to add actions
+to the Edit Menu; action sets tend to be global in nature, while the edit
+menu targets a specific part, and interaction with the data in that part.
+<p>The Navigate menu contains navigational actions such as Go to, Open Type,
+Show In, to enable users to browse laterally or drill down in their code.
+<p>The Project menu contains actions which apply to the contents of the
+workspace, such as Rebuild All and Open Type.&nbsp; An action set may add
+actions which search the entire workspace, generate project info and so on.
+<p>The Window menu contains actions which apply to window management and
+system preferences. It also contains the Open Perspective and Show View
+submenu which contains actions affecting the state of the window contents.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+9.2</font></b>
+<blockquote><font color="#09448D">Follow the platform lead when distributing
+actions within an Action Set.</font></blockquote>
+<hr>
+<p>
+The toolbar contains the most commonly used actions of the menu bar.&nbsp;
+In reflection of this, you should contribute actions to the menu bar first,
+and then to the toolbar if they will be frequently used.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+9.3</font></b>
+<blockquote><font color="#09448D">Contribute actions to the window menu
+bar first, and then to the window toolbar if they will be frequently used.</font></blockquote>
+<hr>
+<p>
+The contents of each action set should be defined using a task oriented
+approach.&nbsp; For instance, the Java action set contains actions to create
+a new package, class and interfaces.&nbsp; It also contains an command to
+open an editor on a class, Goto Type. These form a cohesive set of related
+actions, which can be turned on and off by the user, depending on the active
+task.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+9.4</font></b>
+<blockquote><font color="#09448D">Define each action set with a specific
+task in mind.</font></blockquote>
+<hr>
+<p>
+The size of an action set is also important.&nbsp; If an action set is
+too large, it will flood the menu or toolbar, and reduce the users ability
+to customize the menu and toolbar.&nbsp; At the same time, if an action
+set is too small, the user may find customization of the menu and toolbar
+is too labor intensive.&nbsp; Break an action set up when it has more than
+about 7 items.
+<p>There is no magic number for the size of an action set, but it should
+be carefully designed to contain the smallest possible semantic chunking
+of actions. Avoid the temptation to provide only one action set for an
+entire plug-in.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+9.5</font></b>
+<blockquote><font color="#09448D">An action set should contain the smallest
+possible semantic chunking of actions. Avoid the temptation to provide
+only one action set for an entire plug-in.</font></blockquote>
+<hr>
+<p>
+An action set can be used to share a set of actions between two or more
+views and editors.&nbsp; For instance, a Java Refactor action set may be
+applicable to the selection within a Java Editor, an Outline view, and
+a Hierarchy View.&nbsp; In this situation the actions can be shared by
+defining an action set extension for the workbench.&nbsp; Once this action
+set has been defined, it can be automatically included in a perspective
+by the perspective developer, or added to a perspective by the user.
+<p>An action set should not be used to promote command from a single view
+to the window menu bar and toolbar.&nbsp; This simply clutters up the user
+interface.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+9.6</font></b>
+<blockquote><font color="#09448D">Use an action set to share a set of actions
+which are useful in two or more views or editors.</font></blockquote>
+<hr>
+<p>
+The set of visible command in a window may be changed by invoking Window >
+Customize Perspective.&nbsp; Within the resulting dialog, you can add or remove items
+from the File > New menu, Window > Open Perspective menu, or Window > Show
+View menu.&nbsp; It is also possible to add or remove action sets.&nbsp;
+In general, the visible action sets should be controlled by the user, and
+should never be changed programmatically.&nbsp; There are two reasons for
+this.&nbsp; First, users like to control the environment, not be controlled.&nbsp;
+And second, the user is in the best position to understand the active task,
+and the appropriate action sets for its completion.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+9.7</font></b>
+<blockquote><font color="#09448D">Let the user control the visible action
+sets.&nbsp; Don't try to control it for them.</font></blockquote>
+<hr>
+<p>
+
+A common example of an command which may be added to an action set is Navigate
+> Open Type.&nbsp; This command can be used to open an editor on a type
+which is not visible in the current window, and is a form of lateral navigation.&nbsp;
+In general, all Open actions which take the form should be added to the
+Navigate menu, for consistency.
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+9.8</font></b>
+<blockquote><font color="#09448D">"Open Object" actions must appear in
+the Navigate pulldown menu of the window.</font></blockquote>
+
+<hr>
+<p>
+
+<h4>
+Status Bar</h4>
+If there is a need for a plug-in to show non-modal contextual information
+in the status bar area, always use the global status bar.
+For example, editors use the global status bar to show the current line and column number.<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+9.9</font></b>
+<blockquote><font color="#09448D">Always use the global status bar to display
+status related messages.</font></blockquote>
+
+
+
+<h3>
+<a NAME="Properties"></a>Properties</h3>
+A Properties dialog or view is used to view / modify the properties of
+an object which are not visible in the normal presentation of that object.
+For instance, the Read Only attribute for a file is modified in the Properties
+Dialog.&nbsp; The build path for a Java Project is modified in the Properties
+Dialog.
+<p>Within Eclipse, there are two ways to edit the properties of an object:
+in the Properties dialog, and in the Properties view.&nbsp; Each of these
+is applicable in different situations.
+<p>The Properties view is commonly used to edit the properties for a set
+of objects in an editor, where quick access to the properties is important,
+and you switch from one object to another quickly.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+10.1</font></b>
+<blockquote><font color="#09448D">Use the Properties view to edit the properties
+of an object when quick access is important, and you will switch quickly
+from object to object.</font></blockquote>
+<hr>
+<p>
+The properties for an object should be quick to calculate.&nbsp; If it
+is too expensive to calculate the properties for an object, the quick access
+to properties offered by the Properties view becomes worthless.&nbsp; In
+this situation, where quick access is not possible, a Properties Dialog
+should be used.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+10.2</font></b>
+<blockquote><font color="#09448D">Use a Properties Dialog to edit the properties
+of an object which are expensive to calculate.</font></blockquote>
+<hr>
+<p>
+In some cases, the properties for an object are dependent upon one another,
+such that a change in one will affect another, or even enable / disable
+the option to change another.&nbsp; In this situation, a Properties Dialog
+may be a better way to represent the semantic link between these properties.
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+10.3</font></b>
+<blockquote><font color="#09448D">&nbsp;Use a Properties Dialog to edit
+the properties of an object which contain complex relationships to one
+another.</font></blockquote>
+<hr>
+<p>
+When both the Properties view and the Properties Dialog are used to present
+and edit properties of an object, the Properties Dialog should contain
+the superset of items shown in the Properties view.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+10.4</font></b>
+<blockquote><font color="#09448D">&nbsp;Properties Dialog should contain
+the superset of items shown in the Properties view.</font></blockquote>
+
+
+
+<h3>
+<a NAME="Widgets"></a>Widgets</h3>
+In this section, we will describe some of the recommended designs for Standard Windows Toolkit (SWT)
+widgets.
+
+<p>
+<h4>Tree and Table</h4>
+For Tree and Table widgets that have a checkbox associated with a cell item,
+users can either select the item or change the checkbox state.
+Changing the current selection should not automatically change the check state
+of the selected item.
+However, the current selection should be set to a given item
+when its check state is changed (e.g. users click on the checkbox associated
+with the item).
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+11.1</font></b>
+<blockquote><font color="#09448D">For Tree and Table widgets that have a checkbox associated
+with a cell item, changing the current selection should not automatically change
+the check state of the selected item. However, the current selection should be set
+to a given item when its check state is changed.</font></blockquote><p>
+
+<br>
+<h2>
+<a NAME="Standard Components"></a>Standard Components</h2>
+In this section we'll look at the standard components which ship with Eclipse.&nbsp;
+The Eclipse SDK contains a number of views, including the Navigator, Outline,
+Properties, Tasks, and Bookmarks view.&nbsp; Eclipse also contains a default
+text editor and a Resource perspective.
+<p>As a plug-in developer, you should try to add new actions to the existing
+parts.&nbsp; This leads to better integration with the platform, and the
+existing knowledge of the user.
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+12.1</font></b>
+<blockquote><font color="#09448D">If appropriate, add actions to standard
+components of Eclipse using the plug-in registry.</font></blockquote>
+<hr>
+<p>
+
+<p><br>When extending the standard components such as the Navigator, Outline,
+Properties, Tasks, and Bookmark views, make sure your specialized components
+carry over the base component's characteristics (drag and drop support,
+keyboard navigation, selection behaviour, etc.)
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+12.2</font></b>
+<blockquote><font color="#09448D">If you subclass or copy any of the standard
+components, always carry over the standard components' characteristics.</font></blockquote>
+
+<p><br>
+
+
+<h3>
+<a NAME="Navigator"></a>The Navigator View</h3>
+The Navigator is used to navigate the workspace, create new resources,
+modify resources, and open an editor on a resource.&nbsp; Plug-in developers
+may contribute new actions to the menu, toolbar, and context menu.
+<br>&nbsp;
+<h4>
+Adding Actions</h4>
+This is done by adding an extension to the plug-in registry.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+13.1</font></b>
+<blockquote><font color="#09448D">Add actions to the Navigator View menu,
+toolbar, and context menu using the plug-in registry.</font></blockquote>
+<hr>
+<p>
+If object contributions are made to the context menu, try to qualify the
+target object as much as possible, to avoid adding the command to the wrong
+objects in the Navigator.&nbsp; For instance, a Java command may target
+IFiles with a .java extension, or IProjects with a Java nature.&nbsp; It
+will cause confusion if Java actions appear on non-java objects.
+<p>Some actions are a reflection of tool use, rather than object type.&nbsp;
+For instance, a repository plug-in may provide actions for file check in,
+check out, etc.&nbsp; These actions should only appear on the resources
+in the Navigator if the user has actively chosen to use the repository
+tool.&nbsp; To control the visibility of these actions, the plug-in should
+apply a project nature to the managed resources, and use the project nature
+attribute in all context menu contributions.
+<p>For more information on command filtering,&nbsp; refer to <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+ an Eclipse View</a>.&nbsp; The standard attributes for resources are defined
+ in IResourceActionFilter.java (see below).
+<pre>public interface IResourceActionFilter extends IActionFilter {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String NAME = "name";&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String EXTENSION = "extension";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String PATH = "path";&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String READ_ONLY = "readOnly";&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String PROJECT_NATURE = "projectNature";&nbsp;&nbsp;
+}</pre>
+The standard attributes for project filtering are defined in IProjectActionFilter.java.
+<pre>public interface IProjectActionFilter extends IResourceActionFilter {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String NATURE = "nature";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String OPEN = "open";
+}</pre>
+<img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+13.2</font></b>
+<blockquote><font color="#09448D">Use the attributes defined in IResourceActionFilter.java&nbsp;
+and IProjectActionFilter.java to control the visibility of context menu
+actions in the Navigator.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Integration with Other Views and Editors</h4>
+In Eclipse, the use of a "Navigate -&gt; Show In" command is a common way to link the selection
+in one view to the input of another.&nbsp; For instance, a "Show in Package Explorer"
+command is visible in the context menu for a selected class in the source editor.&nbsp;
+When invoked, the class in the source editor is selected and revealed in
+the Package Explorer view.&nbsp; This approach should be used as a general, non
+intrusive pattern for view or editor linking.&nbsp; It is context sensitive,
+and reflects the intentions of the user.
+<p>A "Navigate -&gt; Show In Navigator" command should be included in any view where a
+resource may appear.&nbsp; If invoked, the command should select and reveal
+the resource in the navigator.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+13.3</font></b>
+<blockquote><font color="#09448D">Use a "Navigate -&gt; Show In Navigator" command in each
+view, to link resources back to the Navigator.</font></blockquote>"
+
+
+<h3>
+<a NAME="Tasks"></a>The Tasks View</h3>
+The Tasks view is used to display the current tasks, errors and warnings
+in the workspace.&nbsp; A plug-in developer may contribute new tasks, errors,
+and warnings to the workspace, and rely upon the Tasks view to display
+those objects.&nbsp; You can also contribute new actions to the menu, toolbar,
+and context menu.&nbsp; This is done by adding an extension to the plug-in
+registry.
+<h4>
+Adding Tasks</h4>
+A new task, error or warning can be created using the Marker Manager services
+from the Core Resources Management plugin.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+14.1</font></b>
+<blockquote><font color="#09448D">Add markers (tasks, errors and warnings)
+to the Tasks view using the Marker Manager services from the Core Resources
+Management plugin.</font></blockquote>
+<hr>
+<p>
+The Tasks view is a table, containing columns for the task image, completion
+status, priority, description, resource, and line number.&nbsp; The description
+text of each marker should be short and concise, so that it will fit in
+the status line of Eclipse.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+14.2</font></b>
+<blockquote><font color="#09448D">The description text of each marker should
+be short and concise, so that it will fit in the status line of Eclipse.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Adding Actions</h4>
+You can contribute new actions to the menu, toolbar, and context menu.&nbsp;
+This is done by adding an extension to the plug-in registry.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+14.3</font></b>
+<blockquote><font color="#09448D">Add actions to the Tasks view menu, toolbar,
+and context menu using the plug-in registry.</font></blockquote>
+<hr>
+<p>
+If object contributions are made to the context menu, try to qualify the target
+object as much as possible, to avoid adding the command to the wrong objects in
+the Tasks view.&nbsp; At an implementation level, each object in the Tasks view
+is a <i>marker</i>, a general mechanism for associate notes with a resource.&nbsp;
+Use the attributes within IMarkerActionFilter.java to control the visibility of
+Task object actions (see below).&nbsp; For more information on command filtering,&nbsp;
+refer to <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+an Eclipse View</a>.
+<pre>public interface IMarkerActionFilter extends IActionFilter {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String TYPE = "type";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String SUPER_TYPE = "superType";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String PRIORITY = "priority";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String SEVERITY = "severity";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String DONE = "done";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String MESSAGE = "message";
+}</pre>
+
+<p><br><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+14.4</font></b>
+<blockquote><font color="#09448D">Use the attributes defined in IMarkerActionFilter.java
+to control the visibility of context menu actions in the Tasks view.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Integration with Other Views and Editors</h4>
+In an editor, task objects are commonly used to mark a location within
+a document.&nbsp; Once a task has been created, it appears in the Task
+view.&nbsp; If this task is selected (via double clicking), you should
+reopen the editor at the location defined in the task. The focus should
+be changed from the Task view to the editor.
+<p>If appropriate, support for the creation of new task objects in an editor
+should be implemented by the editor.&nbsp; For more information on this,
+see <a href="#Editors">Editors</a>.
+<br>&nbsp;
+<h4>
+Adding F1 Help to Task View</h4>
+Plug-ins should support F1 keyboard command and link it to an infopop that
+gives a detailed description of the selected item in the Task view.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+14.5</font></b>
+<blockquote><font color="#09448D">Support F1 keyboard command and link it
+to an infopop that gives a detailed description of the selected item in
+the Task view.</font></blockquote>
+
+<p>
+
+<h3>
+<a NAME="The Preference Dialog"></a>The Preference Dialog</h3>
+The Preference Dialog is used to edit the global preference for a feature
+in the workbench.
+<p>A new preference page should be created when you need to expose global
+options to the user.&nbsp; For instance, the global preferences for Java
+compilation are exposed as a group of preference pages in the Preference
+Dialog.&nbsp; If these preferences are changed, they affect the entire
+Java plug-in.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+15.1</font></b>
+<blockquote><font color="#09448D">Global options should be exposed within
+the Preferences Dialog.</font></blockquote>
+<hr>
+<p>
+A preference page should not be used to expose the local options for a
+particular instance of a view, editor, or window.&nbsp;&nbsp; In this situation,
+the user will look to the menu and toolbar of the control itself to customize
+it.&nbsp; If these options are exposed in the Preference Dialog, it will
+blur the location of customization, and confuse the user.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+15.2</font></b>
+<blockquote><font color="#09448D">Expose the preferences for a particular
+view, editor or window in the view itself, via a menu or tool item.</font></blockquote>
+<hr>
+<p>
+
+<h4>
+Preference Page Design</h4>
+In the simplest case, any plug-in which needs to expose an option to the
+user will define a single preference page.&nbsp; This preference page should
+contain all of the options for the plug-in, until the number of options
+starts to overload the page.&nbsp; At that point a nested design for preference
+pages should be adopted.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+15.3</font></b>
+<blockquote><font color="#09448D">Start out with a single preference page.&nbsp;
+Then evolve to more if you need to.</font></blockquote>
+<hr>
+<p>
+In a nested design, a root preference page is added to the preference dialog,
+and then sub pages are added to the root preference page.&nbsp; The root
+preference page should never be blank.&nbsp; Instead, it should contain
+the most commonly used preferences, or those preferences which have a wide
+spread effect upon the plug-in behavior.&nbsp; Beneath the root page, a
+sub page should be created for each major chunk of functionality within
+the plug-in.
+<p>There is no reason to set the focus in a preference page, because focus
+is always set to the tree, by the Eclipse platform, after the preference
+page is made visible.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+15.4</font></b>
+<blockquote><font color="#09448D">If you create a preference group, use
+the root page for frequently used preferences, or those preferences which
+have wide spread effect.&nbsp; Specialize within the sub pages. The root
+preference page should not be blank.</font></blockquote>
+<hr>
+<p>
+
+<p><br>Each new plug-in should integrate its plug-in preferences, wizards,
+and views into existing preference, wizard, and view categories where it
+makes sense, rather than the blind creation of new categories for itself.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+15.5</font></b>
+<blockquote><font color="#09448D">Attempt to integrate plug-in preferences,
+wizards, and views into existing categories for a new plug-in first, before
+considering the creation of a new category.</font></blockquote>
+
+
+<h3>
+<a NAME="Outline"></a>The Outline View</h3>
+In Eclipse, there is a special relationship between an editor and the Outline
+view.&nbsp; When an editor is opened, the Outline view will connect to
+the editor, and ask it for an outline model.&nbsp; If the editor answers
+an outline model, that model will be displayed in the Outline view whenever
+the editor is active.&nbsp; The outline is used to navigate through the
+edit data, or interact with the edit data at a higher level of abstraction.
+<p>If you are an editor developer, the relationship between an editor and
+the Outline view is important.&nbsp; For more information on the collaboration
+between these two, see <a href="#Editors">Editors</a>.
+<p>
+
+<h3>
+<a NAME="The Properties View"></a>The Properties View</h3>
+The Properties view shows the properties for the active part in the workbench,
+or the selection within that part. These properties are supplied by the
+active part itself.&nbsp; The Properties view is simply a container for
+their presentation.
+<p>Within Eclipse, the properties for an object can be exposed using a
+Properties dialog, or the Properties view.&nbsp; The Properties view is
+commonly used to edit the properties for a set of objects in an editor,
+where quick access to the properties is important, and you switch from
+one object to another quickly.
+<p>For more information on the use of the Properties view, or Properties
+dialog, refer to <a href="#Properties">Properties</a>.
+<p>
+
+<h3>
+<a NAME="Bookmarks"></a>The Bookmarks View</h3>
+The Bookmarks view is used to bookmark files, and open them quickly.&nbsp;
+A plug-in developer may contribute new bookmarks to the workspace, and
+rely upon the Bookmarks view to display those bookmarks.&nbsp; You can
+also contribute new actions to the menu, toolbar, and context menu.&nbsp;
+This is done by adding an extension to the plug-in registry.
+<p>In an editor, bookmark objects are commonly used to mark a location
+within a document.&nbsp; Once a bookmark has been created, it appears in
+the Bookmarks view.&nbsp; If this bookmark is selected, you&nbsp; may reopen
+the editor at the location defined in the bookmark.
+<p>If appropriate, support for the creation of new bookmark objects should
+be implemented by the editor.&nbsp; For more information on this, see <a href="#Editors">Editors</a>.
+<p>
+
+<h3>
+<a NAME="Text Editor"></a>The Text Editor</h3>
+The Text Editor is commonly used to edit text files.&nbsp; A plug-in developer
+can contribute new actions to the menu, toolbar, and context menu.&nbsp;
+This is done by adding an extension to the plug-in registry. For more information
+on this, see <a href="#Editors">Editors</a>.
+<p>
+
+<h3>
+<a NAME="Resource Perspective"></a>The Resource Perspective</h3>
+The Resource perspective contains a Navigator, Outline, Task view, and
+editor area.&nbsp; Plug-in developers may contribute a new command, action
+set, or view to the Resource perspective.&nbsp; For more information, refer
+to
+<a href="#Perspectives">Perspectives</a>..
+<p>
+
+<br>
+<h2>
+<a NAME="Flat Look Design"></a>Flat Look Design</h2>
+
+The Eclipse platform provides a Web user interface, also known as Flat Look, design
+alternative for implementing content editors. For example, the editor in the
+Eclipse plug-in development environment (PDE) perspective uses Flat Look.
+
+<p><img src="images/flatlook1.gif" hspace="40" height=597 width=789>
+<p>
+
+The Flat Look design may be more suitable for certain type of user tasks,
+and more appealing to certain user profile.
+However, this design should not be used just because it provides a different look
+than the native platform look and feel. The use of Flat Look design should be
+considered in the context of the supported user scenarios. This design is usually
+a good fit for extensive property and configuration editing, such as editing
+Eclipse's plugin.xml file, and J2EE Web application's deployment descriptors.
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+16.1</font></b>
+<blockquote><font color="#09448D">Use Flat Look design for user scenarios that involve
+extensive property and configuration editing.</font></blockquote>
+
+<hr>
+<p>
+
+When required, use a "More..." button for navigation purpose (function similar to a hyperlink).
+
+
+<p><img src="images/flatlook2.gif" hspace="40" height=102 width=307>
+
+<p>
+On the overview page, initially expand basic or core sections, but collapse advanced sections.
+On non-overview pages, provide a "Home" icon which takes users back to the overview page
+
+
+<p><img src="images/flatlook3.gif" hspace="40" height=314 width=616>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+16.2</font></b>
+<blockquote><font color="#09448D">Have the core sections on the overview page expanded,
+and provide a "Home" icon on other pages to take users back to the overview page.</font></blockquote>
+
+<hr>
+<p>
+
+<p>
+Don't use tabs within a Flat Look editor tab. Use an alternative design or rendering
+of the tabs.
+
+
+<p><img src="images/flatlook4.gif" hspace="40" height=316 width=324>
+
+<p>
+When applicable, always provide a "Source" tab.
+Assign mnemonics for sections, controls, etc. for keyboard navigation.
+
+
+<p><img src="images/flatlook5.gif" hspace="40" height=344 width=406>
+
+<h4>
+<a NAME="Editor and Outline View Interaction"></a>Editor and Outline View Interaction</h4>
+
+Plug-ins that use Flat Look design for content editor should provide support for
+full two way interactions between the editor and outline view.
+
+<p>
+In the outline view,
+use grouping elements corresponding to tabs in the content editor for
+the organization of the tree view.
+
+
+<p><img src="images/flatlook6.gif" hspace="40" height=474 width=772>
+
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+16.3</font></b>
+<blockquote><font color="#09448D">Use grouping elements corresponding to tabs
+in the Flat Look content editor for the organization of the tree view in outline view.
+</font></blockquote>
+<p>
+
+<br>
+<h2>
+<a NAME="The Tao of IResource"></a>The Tao of Resource</h2>
+In Eclipse, the notion of a tool disappears.&nbsp; In its place, is the
+idea of a universal tool platform - an open, extensible IDE - where tool
+plug-ins are added to extend the capabilities of the platform.&nbsp; These
+plug-ins "teach" Eclipse how to work with things - java files, web content,
+graphics, video - almost anything you can imagine.&nbsp; At an implementation
+level, these plug-ins communicate using resources (projects, folders, and
+files).&nbsp; The resource is the common medium for integration between
+plugins and external tools.
+<p>The resource concept was developed for a number of reasons:
+<br>&nbsp;
+<ol>
+<li>
+Integration between a plug-in from one vendor, and a plug-in from another,
+is only possible if there is a common, well known data abstraction.</li>
+
+<li>
+Integration with external tools is only possible if everything, at some
+level, is a file.</li>
+</ol>
+
+<p><br>Resources are also important at the UI level.&nbsp; If an object
+command, decorator, or property page contribution is made to an IResource,
+the platform will ensure that this contribution is visible in any view
+or editor where the resource appears.&nbsp; For instance, a .java file
+will be visible in the Navigator, the Hierarchy view, and the Packages
+view.&nbsp; To the user, the .java file is the same object, regardless
+of the view where it appears, so the object appearance, context menu, and
+properties should be consistent in each view.
+<p>In some cases, the implementation of a particular view or editor may
+wrap a resource within another object, for presentation purposes.&nbsp;
+If the wrapper is equivalent to a resource, it is important to expose this
+equivalence to the platform.&nbsp; If the resource is exposed, the platform
+may apply resource contributions to the resource equivalent object.&nbsp;
+This ensures presentation consistency for an object in the platform.
+<p>The underlying resource for an object is exposed by implementing IAdaptable
+on the model object, and answering an IContributorResourceAdapter.&nbsp;
+For more information on the implementation of an IContributorResourceAdapter,
+refer to Eclipse Corner.
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+17.1</font></b>
+<blockquote><font color="#09448D">Expose the resource for resource equivalent
+model objects using an IContributorResourceAdapter.</font></blockquote>
+
+<br>
+<h2>
+<a NAME="Accessibility"></a>Accessibility</h2>
+In a view, editor, or other control, every features should be accessible
+using a mouse or the keyboard.
+<p><font color="#000000">In a dialog or wizard, a shortcut key should be
+defined for each button or control.&nbsp; The shortcut key should be displayed
+with an underline beneath the appropriate shortcut character.</font>
+<br>&nbsp;
+<p><img src="images/guidelineIndicator.gif" height="16" width="16"><b><font color="#09448D">Guideline
+18.1</font></b>
+<blockquote><font color="#09448D">All of the features provided by a tool
+should be accessible using a mouse or the keyboard.</font></blockquote>
+<hr>
+<p>
+
+
+<h3>
+<a NAME="Standard Accelerators"></a>Standard Accelerators</h3>
+The Eclipse platform has defined a large number of shortcut keys.&nbsp;
+Plug-in developers should make sure that the existing shortcut keys do
+not conflict with the shortcut keys defined in the plug-in.
+<br>&nbsp;
+<br>&nbsp;
+<table border="1" cellspacing="0" cellpadding="3">
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT><b>Key</b></td>
+
+<td ALIGN=LEFT><b>{Key} by itself</b></td>
+
+<td ALIGN=LEFT><b>SHIFT+{Key}</b></td>
+
+<td ALIGN=LEFT><b>CTRL+{Key}</b></td>
+
+<td ALIGN=LEFT><b>CTRL+SHIFT+{Key}</b></td>
+
+<td ALIGN=LEFT><b>ALT+{Key}</b></td>
+
+<td ALIGN=LEFT><b>CTRL+ALT+{Key}</b></td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>A</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Select All</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>B</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Project / Build</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Bookmarks</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>C</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Copy</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>D</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Display</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>E</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Next Problem</td>
+
+<td ALIGN=LEFT>(JDT editor) Previous Problem</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Find / Replace</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>G</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>H</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Search</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>I</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>J</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>K</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Tasks</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>L</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Go to Line</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>M</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Add Import</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT) Refactor / Move</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>N</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>File / New / Other</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Navigator</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>O</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Organize Imports</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Outline</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>P</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>File / Print</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Properties</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Q</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Inspect</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>R</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>S</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>File / Save</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>File / Save All</td>
+
+<td ALIGN=LEFT>Window / Switch to Editor</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>T</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT) Open Type</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>U</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>V</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Paste</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>W</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>X</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Cut</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT) Refactor / Extract method</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Y</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Redo</td>
+
+<td ALIGN=LEFT>(JDT) Refactor / Redo</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Z</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Undo</td>
+
+<td ALIGN=LEFT>(JDT) Refactor / Undo</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Space</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#E3E3E3">&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Content Assist</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Backspace</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Windows: Undo</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Tab</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Shift Right</td>
+
+<td ALIGN=LEFT>(JDT editor) Shift Left</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Insert</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Windows: Paste</td>
+
+<td ALIGN=LEFT>Windows: Copy</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Delete</td>
+
+<td ALIGN=LEFT>Edit / Delete</td>
+
+<td ALIGN=LEFT>Windows: Cut</td>
+
+<td ALIGN=LEFT>Edit / Delete</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Home</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>End</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Page Up</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Page Down</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Insert</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Delete</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Hyphen (-)</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Show System Menu</td>
+
+<td ALIGN=LEFT>Show View Menu</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Left Arrow</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Right Arrow</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Up Arrow</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Down Arrow</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F1</td>
+
+<td ALIGN=LEFT>Help</td>
+
+<td ALIGN=LEFT>Help</td>
+
+<td ALIGN=LEFT>Help</td>
+
+<td ALIGN=LEFT>Help</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F2</td>
+
+<td ALIGN=LEFT>(Navigator view) Rename, (JDT editor) Open JavaDoc</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F3</td>
+
+<td ALIGN=LEFT>(JDT editor) Open on Selection</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F4</td>
+
+<td ALIGN=LEFT>(JDT editor) Open Type Hierarchy</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>File / Close All</td>
+
+<td ALIGN=LEFT>File / Close</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F5</td>
+
+<td ALIGN=LEFT>(Navigator view) Refresh, (Properties view) Refresh, (Debug)
+Step Into</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F6</td>
+
+<td ALIGN=LEFT>(Debug) Step Over</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Next Editor</td>
+
+<td ALIGN=LEFT>Previous Editor</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F7</td>
+
+<td ALIGN=LEFT>(Debug) Run to Return</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Next View</td>
+
+<td ALIGN=LEFT>Previous View</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F8</td>
+
+<td ALIGN=LEFT>(Debug) Resume</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F9</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F10</td>
+
+<td ALIGN=LEFT>(Debug) Relaunch last</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F11</td>
+
+<td ALIGN=LEFT>(Debug) Debug</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(Debug) Run</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F12</td>
+
+<td ALIGN=LEFT>Activate Editor</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Activate Editor</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+</table>
+
+<p>
+
+<br>
+<h2>
+<a NAME="Best Practices"></a>Best Practices</h2>
+<p>
+
+
+In this section, we provide examples of best practices for designing and implementing
+some common user interactions within the Eclipse platform.
+
+<p>
+
+<h4>
+<a NAME="BP:Syntax and Compilation Error Handling"></a>Syntax and Compilation Error Handling</h4>
+
+When designing editors that provide syntax or compilation checking support,
+follow the Java tooling design in the Eclipse platform.
+
+<p>
+Provide on the fly syntax checking if possible. Use red "squiggle" to indicate where
+the potential error is located in the source code. Use a red box on the side bar on the
+right side to indicate the approximate error position in the file. Use a prominent marker
+on the upper right hand corner to indicate that the file contains errors or warnings.
+Use red color to indicate errors, and use yellow to indicate warnings.
+
+<p><img src="images/bp1.gif" hspace="40" height=597 width=789>
+
+<p>
+After users perform a save operation, user a more prominent marker on the left hand side
+margin to indicate errors and warnings in the file. When using the mouse pointer to hover
+over the marker, the description text should be displayed. In addition, show the
+icon decorator in the content editor tab. In the tree view that shows the resource in
+the Eclipse workspace, use icon decorator to indicate errors or warnings associated
+with this resource, and propagate the icon decorator indication up to the parents
+of the resource in the tree view. Finally, an entry should be added to the Task view
+to list the errors and warnings.
+
+<p><img src="images/bp2.gif" hspace="40" height=597 width=789>
+
+<h4>
+<a NAME="BP:Coding Assistance"></a>Coding Assistance</h4>
+In addition to supporting the standard content assist in an editor, editors should
+exploit the use of Quick Fixes and Quick Assist. Use the light bulb marker on the
+left hand side margin to provide suggestions on how to fix problems with the
+source code. Users can click on the light bulb or use Edit -> Quick Fix menu item
+to invoke this command.
+
+<p><img src="images/bp3.gif" hspace="40" height=597 width=789>
+
+<p>
+Even when there are no syntax errors in the file, users should be able to obtain
+certain quick assistance with their code using the Quick Fix mechanism.
+For example, assigning an expression to a local variable.
+
+<p><img src="images/bp4.gif" hspace="40" height=597 width=789>
+
+
+<p><hr>
+<p>
+If an editor is used for writing code in a given programming language,
+hyper-linked code support should be enabled. While using the mouse pointer
+to hover over the source code, pressing the Ctrl key will turn the programming language
+constructs such as class, method, and field identifiers into clickable links
+to the corresponding declaration.
+
+
+<p><img src="images/bp5.gif" hspace="40" height=597 width=789>
+
+<p><hr>
+<p>
+When possible, a plug-in should provide refactoring support at the programming
+language or application development level. For example, if users rename a method in
+a Java class, refactoring support should enable users to automatically find and
+fix up all references. If users change the URL for a given resource in a Web
+application, refactoring support should enable users to automatically update
+the references to the modified URL.
+
+<p><img src="images/bp6.gif" hspace="40" height=597 width=789>
+
+
+<h4>
+<a NAME="BP:Context Menu"></a>Context Menu</h4>
+Here is one suggested process to reason why a menu item should be added or
+removed from the context menu. The objective is to reduce the number of
+context menu items to no more than 20.
+
+<p>
+First, remove menu items that are not sensitive to selections.
+Second, remove menu items that are not frequently used.
+Third,?examine the items that are not sensitive?to selection
+but are frequently used. Add at most of 5 of these items back.
+Fourth,?remove all disabled menu items, except for clipboard operations
+such as copy and paste, and team, compare and replace submenus.
+Fifth, remove menu items that are frequently used, selection sensitive,
+but have a dominant keyboard shortcut key defined, except for
+clipboard and save operations.
+
+
+<h4>
+<a NAME="BP:Labels, Fonts and Layout for Flat Look Design"></a>
+Labels, Fonts and Layout for Flat Look Design</h4>
+
+For Flat Look design, when using buttons with ellipses
+(except for the "More..." button), it should pop up a secondary window
+which can be a dialog box or a wizard.
+
+<p>
+Use Title capitalization for section titles.
+The distance between section columns should be 32 pixels.
+
+<p>
+On pages with listbox on the left hand side,
+the distance be between the list box and the right-hand column
+(e.g. showing properties for a selected listbox item) should be 10 pixels.
+
+<p><img src="images/flatlook7.gif" hspace="40" height=285 width=321>
+
+<p><hr>
+<p>
+
+<p>
+For labels and fields, use RGB value (160, 160, 164) for enabled state,
+RBG value (0, 0, 0) for read-only state, and RBG value (128, 128, 128) for disabled state.
+
+
+<p><img src="images/flatlook8.gif" hspace="40" height=138 width=600>
+
+<p>
+For listbox control, use RBG value (0, 0, 0) for the border to indicate enabled state,
+use RBG value (128, 128, 128) for disabled state.
+
+
+<p><img src="images/flatlook9.gif" hspace="40" height=368 width=384></p>
+
+<p>
+<h4>
+<a NAME="BP:Decorators"></a>
+Decorators</h4>
+
+Enabling and disabling the decorators are extremely useful when the decorations performed by two or more decorators conflict with each other. For example, the CVS plug-in might decorate the base image by superimposing the base image with a custom image while the &quot;Decorate Example&quot; plug-in might superimpose a different custom image at the same position thereby conflicting with the CVS plug-in decoration. If the decoration performed by two different decorators on the same resource conflict, users should appropriately enable / disable different decorators to get the required decoration.
+<p>
+Implementation tip:<br>
+It is very important to design custom decorators that don't conflict with basic decorations provided by different Eclipse views. For example, the package explorer view decorates Java files with problem markers (a problem marker is placed at the bottom left hand corner) if there are compilation errors. It is a bad practice to decorate resources with custom decoration exactly at the position of a problem marker and developers should avoid this. If the custom decoration is performed at the bottom left corner, then custom decoration and the problem marker decoration, if any, conflict each other and hence users will not be able to view the decorations. The solution to the above mentioned problem is to provide a custom image decoration at the bottom right corner which does not conflict with the basic image decoration provided by Eclipse. The top left corner is the second best place although it conflicts with the binary project decorator. The bottom left and top right should be avoided as they are decorated outside of the decorator mechanism
+<BR>
+<p>
+
+<br>
+<h2>
+<a NAME="Checklist For Developers"></a>Checklist For Developers</h2>
+Here is a checklist for developers who are developing UI plugins.&nbsp;
+This <i>could</i> be used for certification purposes.
+<br>&nbsp;
+
+
+<h3>General UI Guidelines</h3>
+
+<h4>The Spirit of Eclipse</h4>
+
+<p><img src="images/guidelineCheckbox.gif"" height="16" width="16">
+<font color="#09448D"><b>Guideline 1.1</b></font>
+<blockquote><font color="#09448D">Follow and apply good user interface
+design principles: user in control, directness, consistency, forgiveness,
+feedback, aesthetics, and simplicity.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.2</font></b>
+<blockquote><font color="#006699">Follow the platform lead for user interface
+conventions.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.3</font></b>
+<blockquote><font color="#09448D">Be careful not to mix UI metaphors.&nbsp;
+It may blur the original concept, and your own application.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.4</font></b>
+<blockquote><font color="#09448D">If you have an interesting idea, work
+with the Eclipse community to make Eclipse a better platform for all.</font></blockquote>
+</p>
+
+
+<h4>Capitalization</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+1.5</font></b>
+<blockquote><font color="#09448D">Use Headline style capitalization for
+menus, tooltip and all titles, including those used for windows, dialogs, tabs, column headings
+and push buttons. Capitalize the first and last words, and all nouns, pronouns,
+adjectives, verbs and adverbs.&nbsp; Do not include ending punctuation.</font></blockquote>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.6</font></b>
+<blockquote><font color="#09448D">Use Sentence style capitalization for
+all control labels in a dialog or window, including those for check boxes,
+radio buttons, group labels, and simple text fields.&nbsp; Capitalize the
+first letter of the first word, and any proper names such as the word Java.</font></blockquote>
+</p>
+
+
+<h4>Language</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 1.7</font></b>
+<blockquote><font color="#09448D">Create localized version of the resources within your plug-in.</font></blockquote>
+</p>
+
+
+<h4>Error Handling</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+1.8</font></b>
+<blockquote><font color="#09448D">When an error occurs which requires either
+an explicit user input or immediate attention from users, communicate the
+occurrence with a modal dialog.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+1.9</font></b>
+<blockquote><font color="#09448D">If a programming error occurs in the
+product, communicate the occurrence with a dialog, and log it.</font></blockquote>
+</p>
+
+<br>
+<h3>Visual Design</h3>
+
+<h4>Consistency</h4>
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.1</font></b>
+<blockquote><font color="#09448D">Re-use the core visual concepts to maintain consistent representation and meaning
+across Eclipse plug-ins.</font></blockquote></p>
+
+
+<h4>Icon Palettes</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.2</font></b>
+<blockquote><font color="#09448D">Use the Eclipse 256 color palette for creating the active or selected state of
+all icon types.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.3</font></b>
+<blockquote><font color="#09448D">Use the Eclipse 8 color palette for creating the enabled state of perspective,
+view, toolbar, toolbar wizard, and local toolbar icons.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.4</font></b>
+<blockquote><font color="#09448D">Use the Eclipse 2 color palette for creating the disabled state of toolbar,
+toolbar wizard, and local toolbar icons.</font></blockquote></p>
+
+
+
+<h4>Icon Types</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.5</font></b>
+<blockquote><font color="#09448D">Use the appropriate icon type in the location it is designed for within the
+user interface.</font></blockquote></p>
+
+
+
+<h4>Icon Size &amp; Placement</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.6</font></b>
+<blockquote><font color="#09448D">Follow the specific size specifications for each type of icon.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.7</font></b>
+<blockquote><font color="#09448D">Cut the icons with the specific placement shown to ensure alignment in the user interface.</font></blockquote></p>
+
+
+
+<h4>Icon Positioning</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.8</font></b>
+<blockquote><font color="#09448D">Follow the positioning guidelines for the different types of icons for optimal alignment
+of these elements relative to one another.</font></blockquote></p>
+
+
+<h4>Icon Positioning</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.9</font></b>
+<blockquote><font color="#09448D">Use the Eclipse special blue 183 color palette for creating wizard graphics.</font></blockquote></p>
+
+
+
+<h4>Wizard Size &amp; Placement</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.10</font></b>
+<blockquote><font color="#09448D">Follow the specific size specifications for wizard graphics.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.11</font></b>
+<blockquote><font color="#09448D">Cut the wizard graphics with the specific placement shown to ensure alignment
+in the wizard banner area.</font></blockquote></p>
+
+
+<h4>Implementation Conventions</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.12</font></b>
+<blockquote><font color="#09448D">Follow the predefined directory structure and naming convention.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.13</font></b>
+<blockquote><font color="#09448D">Keep the original directory names provided.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.14</font></b>
+<blockquote><font color="#09448D">Minimize duplication of graphics within a plugin by keeping all graphics in one, or few, first level user interface directories.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.15</font></b>
+<blockquote><font color="#09448D">Use the active, enabled, and disabled states provided.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.16</font></b>
+<blockquote><font color="#09448D">Abbreviate file name instead of using the full icon name,
+e.g. New Interface becomes "newint".</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.17</font></b>
+<blockquote><font color="#09448D">Use lower case characters in your file names, e.g. DTD becomes "dtd".</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.18</font></b>
+<blockquote><font color="#09448D">Use 10 characters or less in your file names if possible (underscores count as a character).</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.19</font></b>
+<blockquote><font color="#09448D">Use a file name suffix that describes its location or function in the tool,
+e.g. newint_wiz.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.20</font></b>
+<blockquote><font color="#09448D">Use transparent *.gif format for all user interface icons and wizard graphics,
+unless the context requires a different file format.</font></blockquote></p>
+
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16">
+<b><font color="#09448D">&nbsp;Guideline 2.21</font></b>
+<blockquote><font color="#09448D">Keep the original file names provided.</font></blockquote></p>
+
+
+<br>
+<h3>Component Development</h3>
+
+<h4>Commands</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+3.1</font></b>
+<blockquote><font color="#09448D">Each command must have a label, tool tip,
+and full color image.&nbsp; The label and tool tip must use Headline style
+capitalization.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+3.2</font></b>
+<blockquote><font color="#09448D">The command tooltip should describe the
+result of the command, not the current state of the command. Use the text same as that for the command label.</font></blockquote>
+
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+3.3</font></b>
+<blockquote><font color="#09448D">Adopt the labeling terminology of the
+workbench for New, Delete and Add commands.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+3.4</font></b>
+<blockquote><font color="#09448D">An command should only be enabled if it
+can be completed successfully.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+3.5</font></b>
+<blockquote><font color="#09448D">Command enablement should be quick.&nbsp;
+If command enablement cannot be quick, enable the command optimistically
+and display an appropriate message if the command is invoked, but cannot
+be completed.</font></blockquote>
+</p>
+
+
+<h4>Dialogs</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 4.1</font></b>
+<blockquote><font color="#09448D">When a dialog opens, set the initial
+focus to the first input control in the container. If there are no input controls, the initial focus should
+be assigned to the default button.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">
+Guideline 4.2</font></b>
+<blockquote><font color="#09448D">Slush Bucket widget (or Twin Box) should
+flow from left to right with the source objects on the left hand side.
+It should have the >, &lt;, >>, &lt;&lt; control buttons in this order.</font></blockquote>
+</p>
+
+
+<h4>Wizards</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.1</font></b>
+<blockquote><font color="#09448D">Use a wizard for any task consisting
+of many steps, which must be completed in a specific order.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.2</font></b>
+<blockquote><font color="#09448D">Each wizard must contain a header with
+a banner graphic and a text area for user feedback.&nbsp; It must also
+contain Back, Next, Finish, and Cancel buttons in the footer.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.3</font></b>
+<blockquote><font color="#09448D">Start the wizard with a prompt, not an
+error message.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.4</font></b>
+<blockquote><font color="#09448D">Seed the fields within the wizard using
+the current workbench state.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.5</font></b>
+<blockquote><font color="#09448D">Validate the wizard data in tab order.&nbsp;
+Display a prompt when information is absent, and an error when information
+is invalid.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.6</font></b>
+<blockquote><font color="#09448D">Only enable the Next / Finish buttons
+if all required information in the dialog is present and valid.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.7</font></b>
+<blockquote><font color="#09448D">Remove all programming message ID's from
+wizard text.</font></blockquote>
+
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.8</font></b>
+<blockquote><font color="#09448D">Use a Browse Button whenever an existing
+object is referenced in a wizard.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.9</font></b>
+<blockquote><font color="#09448D">If a new file is created, open the file
+in an editor.&nbsp; If a group of files are created, open the most important,
+or central file in an editor. Open the readme.html file upon creation of
+an example project.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.10</font></b>
+<blockquote><font color="#09448D">If a new project is created, prompt users and change the
+active perspective to suit the project type.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.11</font></b>
+<blockquote><font color="#09448D">If a new object is created, select and
+reveal the new object in the appropriate view.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.12</font></b>
+<blockquote><font color="#09448D">Create folder objects in a wizard if
+reasonable defaults can be defined.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+5.13</font></b>
+<blockquote><font color="#09448D">Use the term "Project name" for the input field label when the
+item must be a Project; otherwise, use the term "Folder name". Do not qualify
+the term.</font></blockquote>
+</p>
+
+
+<h4>Editors</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.1</font></b>
+<blockquote><font color="#09448D">Use an editor to edit or browse a file,
+document, or other primary content.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.2</font></b>
+<blockquote><font color="#09448D">Modifications made in an editor must
+follow an open-save-close lifecycle model.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.3</font></b>
+<blockquote><font color="#09448D">Only one instance of an editor may exist,
+for each editor input, within a perspective.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.4</font></b>
+<blockquote><font color="#09448D">It must be possible to open a separate
+instance of an editor for each different input.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.5</font></b>
+<blockquote><font color="#09448D">The editor should be labeled with the
+name of the file, document, or input being edited.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.6</font></b>
+<blockquote><font color="#09448D">In multipage editors, use a tab control
+for page activation.Tab labels should be kept to one word, and two words
+at most.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.7</font></b>
+<blockquote><font color="#09448D">All of the commands, except for the obvious commands, available in the editor
+should be added to the window menu bar.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.8</font></b>
+<blockquote><font color="#09448D">Use the standard format for editor contributions
+in the window menu bar.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.9</font></b>
+<blockquote><font color="#09448D">If an editor has support for Cut, Copy,
+Paste, or any of the global commands, these commands must be executable from
+the same commands in the window menu bar and toolbar.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.10</font></b>
+<blockquote><font color="#09448D">Fill the editor toolbar with the most
+commonly used items in the view menu.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.11</font></b>
+<blockquote><font color="#09448D">Fill the context menu with selection
+oriented commands.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.12</font></b>
+<blockquote><font color="#09448D">Use the standard format for editor context
+menus.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.13</font></b>
+<blockquote><font color="#09448D">Fill the context menu with a fixed set
+of commands for each selection type, and then enable or disable each to
+reflect the selection state.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.14</font></b>
+<blockquote><font color="#09448D">Register all context menus in the editor
+with the platform.</font></blockquote>
+</p>
+
+<img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.15</font></b>
+<blockquote><font color="#09448D">Implement an Command Filter for each object
+type in the editor.</font></blockquote>
+
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.16</font></b>
+<blockquote><font color="#09448D">If the input to an editor is deleted,
+and the editor contains no changes, the editor should be closed.</font></blockquote>
+
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.17</font></b>
+<blockquote><font color="#09448D">If the input to an editor is deleted,
+and the editor contains changes, the editor should give the user a chance
+to save their changes to another location, and then close.</font></blockquote>
+
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.18</font></b>
+<blockquote><font color="#09448D">If the resource is dirty, prefix the resource
+name presented in the editor tab with an asterisk.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.19</font></b>
+<blockquote><font color="#09448D">Treat read-only editor input as you would
+any other input.&nbsp; Enable the Save As if possible. Display "Read-only"
+in the status bar area.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.20</font></b>
+<blockquote><font color="#09448D">If the data within an editor is too extensive
+to see on a single screen, and will yield a structured outline, the editor
+should provide an outline model to the Outline view.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.21</font></b>
+<blockquote><font color="#09448D">Notification about location between an
+editor and the Outline view should be two-way. A context menu should be available
+in the Outline view as appropriate.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.22</font></b>
+<blockquote><font color="#09448D">An error or warning image should be added
+to items with the error or warning respectively. A container should have a red X if it there are errors on the container itself, a gray X if any of its descendents have errors (but not the container itself), and no X if neither the container nor any of its descendents have errors.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.23</font></b>
+<blockquote><font color="#09448D">If appropriate, implement the "Add Task"
+feature in your editor.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.24</font></b>
+<blockquote><font color="#09448D">If appropriate, implement the "Add Bookmark"
+feature in your editor.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.25</font></b>
+<blockquote><font color="#09448D">Editors with source lines of text should show the current line and optionally column numbers the status line. It's optional for the editor to show line numbers for each line in the editor itself.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.26</font></b>
+<blockquote><font color="#09448D">Table cell editors should support the
+single-click activation model, and in edit mode, they should render complex
+controls upon single-click.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.27</font></b>
+<blockquote><font color="#09448D">Changes made in a table cell editor should
+be committed when a user clicks off the cell or hits the "Enter" key. Selection
+should be cancelled when user hits the "Esc" key.First letter navigation
+should be supported as a cursoring mechanism within a cell.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.28</font></b>
+<blockquote><font color="#09448D">When performing fine-grain error validation
+in an editor, use red squiggles to underline the invalid content. When users move the mouse over the red squiggles, display the error text in a fly-over pop up box.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.29</font></b>
+<blockquote><font color="#09448D">Use the Task view to show errors found
+when the Save command is invoked.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+6.30</font></b>
+<blockquote><font color="#09448D">If modifications to a resource are made
+outside of the workbench, users should be prompted to either override the
+changes made outside of the workbench, or back out of the Save operation
+when the Save command is invoked in the editor.</font></blockquote>
+</p>
+
+
+<h4>Views</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.1</font></b>
+<blockquote><font color="#09448D">Use a view to navigate a hierarchy of
+information, open an editor, or display the properties of an object.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.2</font></b>
+<blockquote><font color="#09448D">Modifications made within a view must
+be saved immediately.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.3</font></b>
+<blockquote><font color="#09448D">Only one instance of a view may exist
+in a perspective.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.4</font></b>
+<blockquote><font color="#09448D">A view must be able to be opened in more than one perspective.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.5</font></b>
+<blockquote><font color="#09448D">A view can be opened from the Window
+> Show View menu.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.6</font></b>
+<blockquote><font color="#09448D">The view label in the title bar must
+be prefixed with the label of the view in the Perspective > Show View menu.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.7</font></b>
+<blockquote><font color="#09448D">If a view contains more than one control,
+it may be advisable to split it up into two or more views.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.8</font></b>
+<blockquote><font color="#09448D">When a view first opens, derive the view
+input from the state of the perspective.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.9</font></b>
+<blockquote><font color="#09448D">If a view displays a resource tree, consider
+using the window input as the root of visible information in the view.</font></blockquote>
+</p>
+
+</P><p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.10</font></b>
+<blockquote><font color="#09448D">Use the view pulldonw menu for presentation commands, not
+selection-oriented commands.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.11</font></b>
+<blockquote><font color="#09448D">Use the standard order of commands for view pulldown
+menus.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.12</font></b>
+<blockquote><font color="#09448D">Put only the most commonly used commands on the toolbar. Any command on a toolbar must also appear in a menu, either the context menu or the view menu.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.13</font></b>
+<blockquote><font color="#09448D">Fill the context menu with selection
+oriented actions, not presentation actions.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.14</font></b>
+<blockquote><font color="#09448D">Use the standard order of commands for view context
+menus.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.15</font></b>
+<blockquote><font color="#09448D">Fill the context menu with a fixed set
+of commands for each selection type, and then enable or disable each to
+reflect the selection state.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.16</font></b>
+<blockquote><font color="#09448D">If an object appears in more than one
+view, it should have the same context menu in each.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.17</font></b>
+<blockquote><font color="#09448D">Register all context menus in the view
+with the platform.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.18</font></b>
+<blockquote><font color="#09448D">Implement an Command Filter for each object
+type in the view.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.19</font></b>
+<blockquote><font color="#09448D">If a view has support for Cut, Copy,
+Paste, or any of the global commands, these commands must be executable from
+the same commands in the window menu bar and toolbar.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+7.20</font></b>
+<blockquote><font color="#09448D">Persist the state of each view between
+sessions.</font></blockquote>
+</p>
+
+<P><img src="images/guidelineCheckbox.gif" height="16" width="16"><B><font color="#09448D">&nbsp;Guideline
+7.21</FONT></B></P><BLOCKQUOTE><FONT color="#09448D"><FONT color="#000000"></FONT>
+Navigation views should support &quot;Link with Editor&quot; on the view menu<FONT color="#000000"></FONT>
+</FONT></BLOCKQUOTE>
+</P>
+
+
+<h4>Perspectives</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.1</font></b>
+<blockquote><font color="#09448D">Create a new perspective type for long
+lived tasks, which involve the performance of smaller, non-modal tasks.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.2</font></b>
+<blockquote><font color="#09448D">If you just want to expose a single view,
+or two, extend an existing perspective type.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.3</font></b>
+<blockquote><font color="#09448D">The size and position of each view in
+a perspective should be defined in a reasonable manner, such that the user
+can resize or move a view if they desire it. When defining the initial layout, it is important to consider the overall flow between the views (and editors) in the perspective.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.4&nbsp;</font></b>
+<blockquote><font color="#09448D">If a perspective has just one part, it
+may be better suited as a view or editor.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.5</font></b>
+<blockquote><font color="#09448D">If it is undesirable to have an editor
+area in a perspective, hide it.&nbsp; Do not resize the editor area to
+the point where it is no longer visible.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.6</font></b>
+<blockquote><font color="#09448D">Populate the window menu bar with commands
+and command sets which are appropriate to the task orientation of the perspective,
+and any larger workflow.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.7 </font></b>
+<blockquote><font color="#09448D">A new perspective should be opened only
+if the user explicitly states a desire to do so.&nbsp; In making this statement,
+the user agrees to leave their old context, and create a new one.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.8</font></b>
+<blockquote><font color="#09448D">If a new perspective is opened as a side
+effect of another command, the user should be able to turn this behavior
+off.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.9</font></b>
+<blockquote><font color="#09448D">If a new perspective is opened, it should
+be opened within the current window, or in a new window, depending
+on the user preference.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+8.10</font></b><blockquote><font color="#09448D">The list of shortcuts added to the New,
+Open Perspective, and Show View menus should be at most 7 plus / minus
+2 items.</font></blockquote>
+</p>
+
+
+<h4>Windows</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+9.1</font></b>
+<blockquote><font color="#09448D">Use an Action Set to contribute actions
+to the window menu bar and toolbar.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+9.2</font></b>
+<blockquote><font color="#09448D">Follow the platform lead when distributing
+actions within an Action Set.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+9.3</font></b>
+<blockquote><font color="#09448D">Contribute actions to the window menu
+bar first, and then to the window toolbar if they will be frequently used.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+9.4</font></b>
+<blockquote><font color="#09448D">Define each action set with a specific
+task in mind.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+9.5</font></b>
+<blockquote><font color="#09448D">An action set should contain the smallest
+possible semantic chunking of actions. Avoid the temptation to provide
+only one action set for an entire plug-in.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+9.6</font></b>
+<blockquote><font color="#09448D">Use an action set to share a set of actions
+which are useful in two or more views or editors.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+9.7</font></b>
+<blockquote><font color="#09448D">Let the user control the visible action
+sets.&nbsp; Don't try to control it for them.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+9.8</font></b>
+<blockquote><font color="#09448D">"Open Object" actions must appear in
+the Navigate pulldown menu of the window.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+9.9</font></b>
+<blockquote><font color="#09448D">Always use the global status bar to display
+status related messages.</font></blockquote>
+</p>
+
+
+<h4>Properties</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+10.1</font></b>
+<blockquote><font color="#09448D">Use the Properties view to edit the properties
+of an object when quick access is important, and you will switch quickly
+from object to object.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+10.2</font></b>
+<blockquote><font color="#09448D">Use a Properties Dialog to edit the properties
+of an object which are expensive to calculate.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+10.3</font></b>
+<blockquote><font color="#09448D">&nbsp;Use a Properties Dialog to edit
+the properties of an object which contain complex relationships to one
+another.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+10.4</font></b>
+<blockquote><font color="#09448D">&nbsp;Properties Dialog should contain
+the superset of items shown in the Properties view.</font></blockquote>
+</p>
+
+
+<h4>Widgets</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+11.1</font></b>
+<blockquote><font color="#09448D">For Tree and Table widgets that have a checkbox associated
+with a cell item, changing the current selection should not automatically change
+the check state of the selected item. However, the current selection should be set
+to a given item when its check state is changed.</font></blockquote>
+</p>
+
+<br>
+<h3>Standard Components</h3>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+12.1</font></b>
+<blockquote><font color="#09448D">If appropriate, add actions to standard
+components of Eclipse using the plug-in registry.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+12.2</font></b>
+<blockquote><font color="#09448D">If you subclass or copy any of the standard
+components, always carry over the standard components' characteristics.</font></blockquote>
+</p>
+
+
+<h4>The Navigator View</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+13.1</font></b>
+<blockquote><font color="#09448D">Add actions to the Navigator View menu,
+toolbar, and context menu using the plug-in registry.</font></blockquote>
+</p>
+
+<img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+13.2</font></b>
+<blockquote><font color="#09448D">Use the attributes defined in IResourceActionFilter.java&nbsp;
+and IProjectActionFilter.java to control the visibility of context menu
+actions in the Navigator.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+13.3</font></b>
+<blockquote><font color="#09448D">Use a "Navigate -&gt; Show In Navigator" command in each
+view, to link resources back to the Navigator.</font></blockquote>
+</p>
+
+
+<h4>The Tasks View</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+14.1</font></b>
+<blockquote><font color="#09448D">Add markers (tasks, errors and warnings)
+to the Tasks view using the Marker Manager services from the Core Resources
+Management plugin.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+14.2</font></b>
+<blockquote><font color="#09448D">The description text of each marker should
+be short and concise, so that it will fit in the status line of Eclipse.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+14.3</font></b>
+<blockquote><font color="#09448D">Add actions to the Tasks view menu, toolbar,
+and context menu using the plug-in registry.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+14.4</font></b>
+<blockquote><font color="#09448D">Use the attributes defined in IMarkerActionFilter.java
+to control the visibility of context menu actions in the Tasks view.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+14.5</font></b>
+<blockquote><font color="#09448D">Support F1 keyboard command and link it
+to an infopop that gives a detailed description of the selected item in
+the Task view.</font></blockquote>
+</p>
+
+
+<h4>The Preference Dialog</h4>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+15.1</font></b>
+<blockquote><font color="#09448D">Global options should be exposed within
+the Preferences Dialog.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+15.2</font></b>
+<blockquote><font color="#09448D">Expose the preferences for a particular
+view, editor or window in the view itself, via a menu or tool item.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+15.3</font></b>
+<blockquote><font color="#09448D">Start out with a single preference page.&nbsp;
+Then evolve to more if you need to.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+15.4</font></b>
+<blockquote><font color="#09448D">If you create a preference group, use
+the root page for frequently used preferences, or those preferences which
+have wide spread effect.&nbsp; Specialize within the sub pages. The root
+preference page should not be blank.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+15.5</font></b>
+<blockquote><font color="#09448D">Attempt to integrate plug-in preferences,
+wizards, and views into existing categories for a new plug-in first, before
+considering the creation of a new category.</font></blockquote>
+</p>
+
+<br>
+<h3>Flat Look Design</h3>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+16.1</font></b>
+<blockquote><font color="#09448D">Use Flat Look design for user scenarios that involves
+extensive property and configuration editing.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+16.2</font></b>
+<blockquote><font color="#09448D">Have the core sections on the overview page expanded,
+and provide a "Home" icon on other pages to take users back to the overview page.</font></blockquote>
+</p>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="##09448D">&nbsp;Guideline
+16.3</font></b>
+<blockquote><font color="#09448D">Use grouping elements corresponding to tabs
+in the Flat Look content editor for the organization of the tree view in outline view.
+</font></blockquote>
+</p>
+
+
+<br>
+<h3>The Tao of Resource</h3>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+17.1</font></b>
+<blockquote><font color="#09448D">Expose the resource for resource equivalent
+model objects using an IContributorResourceAdapter.</font></blockquote>
+</p>
+
+
+<br>
+<h3>Accessibility</h3>
+
+<p><img src="images/guidelineCheckbox.gif" height="16" width="16"><b><font color="#09448D">&nbsp;Guideline
+18.1</font></b>
+<blockquote><font color="#09448D">All of the features provided by a tool
+should be accessible using a mouse or the keyboard.</font></blockquote>
+</p>
+
+
+<br>
+<h2>
+<a NAME="Glossary"></a>Glossary</h2>
+
+<P>
+<dl>
+<dt>
+<b>Command</b></dt>
+
+<dd>
+A <i>command</i>, which is invoked by a user to carry out some specific functions, may appear as an item in a menu, or an item in a toolbar. In reflection of this, it has attributes for the menu or tool item label, tooltip, and image.
+As a plug-in developer, you can contribute commands to the window menu bar and toolbar, or to individual views and editors. Contribution to the window is performed using an <i>action set</i>, a set of task oriented commands which the user can show or hide. Contribution to a view or editor is performed using individual command.
+</dd>
+
+<br>&nbsp;
+<dt>
+<b>Bookmarks View</b></dt>
+
+<dd>
+A view used to browse the bookmarks in the workbench.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Editor</b></dt>
+
+<dd>
+An editor is a visual component within a workbench page. It is typically
+used to edit or browse a document or input object. The input is identified
+using an &lt;code>IEditorInput&lt;/code>.&nbsp; Modifications made in an
+editor part follow an open-save-close lifecycle model (in contrast to a
+view part, where modifications are saved to the workbench immediately).</dd>
+
+<br>&nbsp;
+<dt>
+<b>File</b></dt>
+
+<dd>
+An object in the workspace, analogous to files in the file system.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Folder</b></dt>
+
+<dd>
+A container for files in the workspace.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Navigator View</b></dt>
+
+<dd>
+A view used to browse the files in the workspace</dd>
+
+<br>&nbsp;
+<dt>
+<b>Outline View</b></dt>
+
+<dd>
+A view, commonly used to view the outline of the active editor.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Perspective</b></dt>
+
+<dd>
+A perspective is a visual container for a set of views and editors (parts).&nbsp;
+These parts exist wholly within the perspective and are not shared.&nbsp;
+A perspective is also like a page within a book.&nbsp; It exists within
+a window along with any number of other perspectives and, like a page within
+a book, only one perspective is visible at any time.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Platform</b></dt>
+
+<dd>
+A generic framework for the integration of tools.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Preferences</b></dt>
+
+<dd>
+A Preference Page is used to edit the preferences for a feature in the
+platform.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Project</b></dt>
+
+<dd>
+A group of files and folders within the workspace.&nbsp; Each project maps
+to a corresponding user specified directory in the file system.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Properties View</b></dt>
+
+<dd>
+A view, typically used to browse the properties for an object in the active
+editor or view.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Properties Dialog</b></dt>
+
+<dd>
+A dialog for editing the properties of an object.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Property Page</b></dt>
+
+<dd>
+A page within a Properties Dialog.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Resource</b></dt>
+
+<dd>
+The generic name for projects, folders and files.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Tasks View</b></dt>
+
+<dd>
+A view used to browse the tasks, errors, and warnings within the workspace.</dd>
+
+<br>&nbsp;
+<dt>
+<b>View</b></dt>
+
+<dd>
+A view is a visual component within a workbench page.&nbsp; It is typically
+used to navigate a hierarchy of information (like the workspace), open
+an editor, or display properties for the active editor.&nbsp; Modifications
+made in a view are saved immediately (in contrast to an editor part, which
+conforms to a more elaborate open-save-close lifecycle).</dd>
+
+<br>&nbsp;
+<dt>
+<b>Wizard</b></dt>
+
+<dd>
+A Wizard is typically used to create new resources, import resources, or
+export resources.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Workbench</b></dt>
+
+<dd>
+The Workbench provides the user interface structure for Eclipse. The purpose
+of the Workbench is to facilitate the seamless integration of tools. These
+tools contribute to extension points defined by the Workbench.&nbsp; The
+Workbench is responsible for the presentation and coordination of the user
+interface.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Workspace</b></dt>
+
+<dd>
+The various tools plugged in to the Eclipse Platform operate on regular
+files in the user's workspace.&nbsp; The workspace consists of one or more
+top level projects, where each project maps to a corresponding user specified
+directory in the file system.&nbsp; Each project contains a collection
+of folders and files.</dd>
+</dl>
+
+<br>
+
+<h2>
+<a NAME="Acknowledgement"></a>Acknowledgement</h2>
+Screenshots contributed to Eclipse.org and used in this document,
+originate from plugins released or under development by the following teams:
+<p>
+<ul>
+<li>
+Java Development Tooling, Eclipse Subproject</li>
+<li>
+WebSphere&reg; Studio Application Developer, IBM Corporation</li>
+<li>
+Rational XDE Professional, IBM Corporation.</li>
+</ul>
+<p>By agreeing to share selected elements of their user interface designs
+(both positive and negative), we feel that these teams have helped make
+the UI guidelines stronger.
+<br>
+
+<h2>
+<a NAME="Revision"></a>Revision History</h2>
+<p>This covers the more significant changes to the guidelines since Version 1.0:</p>
+<table class="indent" border="1" cellspacing="0" cellpadding="5" width="90%"">
+
+ <tr>
+ <td rowspan="5" valign="top"><h4>Added</h4></td>
+ <td>General UI Principles : "Decorators" subsection</td>
+ </tr>
+ <tr>
+ <td>"Visual Design" section covers consistency, design and implementation issues for UI graphics</td>
+ </tr>
+ <tr>
+ <td>Component Development : "Widgets" subsection describes some of the recommended designs for Standard
+ Windows Toolkit (SWT) widgets</td>
+ </tr>
+ <tr>
+ <td>"Flat Look Design" section for user scenarios that involve extensive property and configuration editing</td>
+ </tr>
+ <tr>
+ <td>"Best Practices" section provides examples of best practices for designing and implementing some
+ common user interactions</td>
+ </tr>
+
+ <tr>
+ <td rowspan="2" valign="top"><h4>Removed</h4></td>
+ <td>Component Development : Perspectives : Opening a perspective in code - Guideline "Consider replacing the
+ perspective type before you open a new perspective" has been removed</td>
+ </tr>
+ <tr>
+ <td>Component Development : Windows : Actions - "Open Application" has been removed</td>
+ </tr>
+
+ <tr>
+ <td rowspan="2" valign="top"><h4>Modified</h4></td>
+ <td>Anything referred to as an "action" in Version 1.0 of the guidelines has been changed to "command" in
+ Version 2.1 of the guidelines</td>
+ </tr>
+ <tr>
+ <td>The full guideline document has been reformatted and the graphical presentation has been updated</td>
+ </tr>
+</table>
+
+
+<p>
+<hr WIDTH="100%">
+<div align="center"><br>
+ Version 2.1 February 2004 <br>
+<br>Copyright&copy; 2001 - 2004 International Business Machine Corporation.
+<br>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.
+<br>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</div>
+</p>
+<br>
+</body>
+</html>
diff --git a/Article-UI-Guidelines/Index.html b/Article-UI-Guidelines/Index.html
new file mode 100644
index 0000000..d9d6f7c
--- /dev/null
+++ b/Article-UI-Guidelines/Index.html
@@ -0,0 +1,8 @@
+<HTML>
+<HEAD><TITLE>Eclipse User Interface Guidelines</TITLE>
+</HEAD>
+<FRAMESET cols=190,50%>
+<FRAME frameBorder=1 marginHeight=0 marginWidth=2 name=_left src="Toc.html">
+<FRAME frameBorder=1 marginHeight=2 marginWidth=2 name=_right src="Contents.html">
+</FRAMESET>
+</HTML>
diff --git a/Article-UI-Guidelines/Toc.html b/Article-UI-Guidelines/Toc.html
new file mode 100644
index 0000000..ba056d9
--- /dev/null
+++ b/Article-UI-Guidelines/Toc.html
@@ -0,0 +1,218 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Build">
+ <title>Eclipse UI Guidelines</title>
+<link rel="stylesheet" href="default_style.css">
+</head>
+<body>
+<p align="center"><b><font face="Arial,Helvetica">Eclipse UI Guidelines<br></font></b>
+ <a href="Contents.html" target="_top">View without table of contents</a></p>
+<table CELLSPACING=0 CELLPADDING=0 WIDTH="225" >
+ <tr>
+ <td COLSPAN="2" WIDTH="50">
+ <p><nobr><a href="Contents.html#Introduction" target="_right">Introduction</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td WIDTH="80%">
+ <p><nobr><a href="Contents.html#The Workbench" target="_right">The Workbench</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Projects, Folder and Files" target="_right">Projects,
+ Folders, and Files</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Getting Started" target="_right">Getting
+ Started</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#General UI Guidelines" target="_right">General
+ UI Principles</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td WIDTH="90%">
+ <p><nobr><a href="Contents.html#The Spirit of Eclipse" target="_right">The
+ Spirit of Eclipse</a></nobr> <br>
+ <nobr><a href="Contents.html#Capitalization" target="_right">Capitalization</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Colors" target="_right">Colors</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#BP:Decorators" target="_right">Decorators</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Language" target="_right">Language</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Error Handling" target="_right">Error Handling</a></nobr>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2" WIDTH="50">
+ <p><nobr><a href="Contents.html#Introduction_VDG" target="_right">Visual Design</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td WIDTH="90%">
+ <p>
+ <nobr><a href="Contents.html#Consistency_VDG" target="_right">Consistency</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#IconSpecsPal_VDG" target="_right">Icon Palettes</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#IconSpecsTypes_VDG" target="_right">Icon Types</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#IconSpecsSize_VDG" target="_right">Icon Size &amp; Placement</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#IconSpecsPos_VDG" target="_right">Icon Positioning</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#IconSpecsOvr_VDG" target="_right">Icon Overlays</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#WizSpecsPal_VDG" target="_right">Wizard Palette</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#WizSpecsSize_VDG" target="_right">Wizard Size &amp; Placement</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#ConsistencyImp_VDG" target="_right">Implementation Conventions</a></nobr>
+ <!-- Also considered "Name &amp; Path Conventions" as a title for this section -->
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Component Development" target="_right">Component
+ Development</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td>
+ <p><nobr><a href="Contents.html#Commands" target="_right">Commands</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Dialogs" target="_right">Dialogs</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Wizards" target="_right">Wizards</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Editors" target="_right">Editors</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Views" target="_right">Views</a></nobr> <br>
+ <nobr><a href="Contents.html#Perspectives" target="_right">Perspectives</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Windows" target="_right">Windows</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Properties" target="_right">Properties</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Widgets" target="_right">Widgets
+ </a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Standard Components" target="_right">Standard
+ Components</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td>
+ <p><nobr><a href="Contents.html#Navigator" target="_right">The Navigator
+ View</a></nobr> <br>
+ <nobr><a href="Contents.html#Tasks" target="_right">The Tasks View</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#The Preference Dialog" target="_right">The
+ Preferences Dialog</a></nobr> <br>
+ <nobr><a href="Contents.html#Outline" target="_right">The Outline View</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#The Properties View" target="_right">The
+ Properties View</a></nobr> <br>
+ <nobr><a href="Contents.html#Bookmarks" target="_right">The Bookmarks
+ View</a></nobr> <br>
+ <nobr><a href="Contents.html#Text Editor" target="_right">The Text Editor</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Resource Perspective" target="_right">The
+ Resource Perspective</a></nobr> </p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Flat Look Design" target="_right">Flat Look
+ Design</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td>
+ <p><nobr><a href="Contents.html#Editor and Outline View Interaction" target="_right">
+ Editor and Outline View Interaction</a></nobr> <br>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><a href="Contents.html#The Tao of IResource" target="_right">The Tao
+ of Resource</a></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><a href="Contents.html#Accessibility" target="_right">Accessibility</a></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td>
+ <p><a href="Contents.html#Standard Accelerators" target="_right">Standard
+ Accelerators</a></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Best Practices" target="_right">Best Practices</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Checklist For Developers" target="_right">Checklist
+ for Developers</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Glossary" target="_right">Glossary</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Acknowledgement" target="_right">Acknowledgement</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Revision" target="_right">Revision History</a></nobr></p>
+ </td>
+ </tr>
+</table>
+
+<hr ALIGN=LEFT WIDTH="100%"><font face="Times New Roman, Times, serif"><font size=-2>Copyright
+&copy; 2001 - 2004 International Business Machine Corporation.</font></font>
+</body>
+</html>
diff --git a/Article-UI-Guidelines/default_style.css b/Article-UI-Guidelines/default_style.css
new file mode 100644
index 0000000..3d2a43a
--- /dev/null
+++ b/Article-UI-Guidelines/default_style.css
@@ -0,0 +1,17 @@
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm; }
+p, td { font-family: arial, helvetica, geneva; font-size: 10pt; }
+th { font-family: arial, helvetica, geneva; font-size: 11px; font-weight: bold; }
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt; }
+.sub, sup { font-family: arial, helvetica, geneva; font-size: 10pt; }
+code { font-family: "Courier New", Courier, mono; font-size: 10pt; }
+li { font-family: arial, helvetica, geneva; font-size: 10pt; }
+
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold; }
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold; color: #000000; border-bottom: thin solid #0080C0; }
+h2.checklist { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold; color: #000000; }
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold; }
+h4 { font-family: arial, helvetica, geneva; font-size: 13pt; font-weight: bold; }
+hr { margin-left: 40px; margin-right: 40px; color: #0080C0; height: 1px; }
+
+/* Table indent */
+.indent { margin-left: 40px; } \ No newline at end of file
diff --git a/Article-UI-Guidelines/images/256palette.gif b/Article-UI-Guidelines/images/256palette.gif
new file mode 100644
index 0000000..ec958da
--- /dev/null
+++ b/Article-UI-Guidelines/images/256palette.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/Idea.gif b/Article-UI-Guidelines/images/Idea.gif
new file mode 100644
index 0000000..c88ec70
--- /dev/null
+++ b/Article-UI-Guidelines/images/Idea.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/actionExamples.gif b/Article-UI-Guidelines/images/actionExamples.gif
new file mode 100644
index 0000000..6b780e3
--- /dev/null
+++ b/Article-UI-Guidelines/images/actionExamples.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/badHilight.gif b/Article-UI-Guidelines/images/badHilight.gif
new file mode 100644
index 0000000..b7e84dd
--- /dev/null
+++ b/Article-UI-Guidelines/images/badHilight.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/badTooltips.gif b/Article-UI-Guidelines/images/badTooltips.gif
new file mode 100644
index 0000000..a5d1707
--- /dev/null
+++ b/Article-UI-Guidelines/images/badTooltips.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/badWizardInit.gif b/Article-UI-Guidelines/images/badWizardInit.gif
new file mode 100644
index 0000000..adbb882
--- /dev/null
+++ b/Article-UI-Guidelines/images/badWizardInit.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/bp1.gif b/Article-UI-Guidelines/images/bp1.gif
new file mode 100644
index 0000000..6d28cec
--- /dev/null
+++ b/Article-UI-Guidelines/images/bp1.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/bp2.gif b/Article-UI-Guidelines/images/bp2.gif
new file mode 100644
index 0000000..b34a052
--- /dev/null
+++ b/Article-UI-Guidelines/images/bp2.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/bp3.gif b/Article-UI-Guidelines/images/bp3.gif
new file mode 100644
index 0000000..d879124
--- /dev/null
+++ b/Article-UI-Guidelines/images/bp3.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/bp4.gif b/Article-UI-Guidelines/images/bp4.gif
new file mode 100644
index 0000000..8beb7bc
--- /dev/null
+++ b/Article-UI-Guidelines/images/bp4.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/bp5.gif b/Article-UI-Guidelines/images/bp5.gif
new file mode 100644
index 0000000..e0da95d
--- /dev/null
+++ b/Article-UI-Guidelines/images/bp5.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/bp6.gif b/Article-UI-Guidelines/images/bp6.gif
new file mode 100644
index 0000000..066cf76
--- /dev/null
+++ b/Article-UI-Guidelines/images/bp6.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/cell1.gif b/Article-UI-Guidelines/images/cell1.gif
new file mode 100644
index 0000000..356870b
--- /dev/null
+++ b/Article-UI-Guidelines/images/cell1.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/cell2.gif b/Article-UI-Guidelines/images/cell2.gif
new file mode 100644
index 0000000..8c7b494
--- /dev/null
+++ b/Article-UI-Guidelines/images/cell2.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/cell3.gif b/Article-UI-Guidelines/images/cell3.gif
new file mode 100644
index 0000000..2123dc8
--- /dev/null
+++ b/Article-UI-Guidelines/images/cell3.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/cellTableEditor.gif b/Article-UI-Guidelines/images/cellTableEditor.gif
new file mode 100644
index 0000000..7cc89a0
--- /dev/null
+++ b/Article-UI-Guidelines/images/cellTableEditor.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/dirtyEditor.gif b/Article-UI-Guidelines/images/dirtyEditor.gif
new file mode 100644
index 0000000..db0c56a
--- /dev/null
+++ b/Article-UI-Guidelines/images/dirtyEditor.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/disabledcolors.gif b/Article-UI-Guidelines/images/disabledcolors.gif
new file mode 100644
index 0000000..edc9001
--- /dev/null
+++ b/Article-UI-Guidelines/images/disabledcolors.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/editorTitles.gif b/Article-UI-Guidelines/images/editorTitles.gif
new file mode 100644
index 0000000..579fe6e
--- /dev/null
+++ b/Article-UI-Guidelines/images/editorTitles.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/enabledcolors.gif b/Article-UI-Guidelines/images/enabledcolors.gif
new file mode 100644
index 0000000..d4f519c
--- /dev/null
+++ b/Article-UI-Guidelines/images/enabledcolors.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/errorsInOutline.gif b/Article-UI-Guidelines/images/errorsInOutline.gif
new file mode 100644
index 0000000..ec3e113
--- /dev/null
+++ b/Article-UI-Guidelines/images/errorsInOutline.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/fileDeletedDialog.gif b/Article-UI-Guidelines/images/fileDeletedDialog.gif
new file mode 100644
index 0000000..681907a
--- /dev/null
+++ b/Article-UI-Guidelines/images/fileDeletedDialog.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/flatlook1.gif b/Article-UI-Guidelines/images/flatlook1.gif
new file mode 100644
index 0000000..497adbd
--- /dev/null
+++ b/Article-UI-Guidelines/images/flatlook1.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/flatlook2.gif b/Article-UI-Guidelines/images/flatlook2.gif
new file mode 100644
index 0000000..fa80f9b
--- /dev/null
+++ b/Article-UI-Guidelines/images/flatlook2.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/flatlook3.gif b/Article-UI-Guidelines/images/flatlook3.gif
new file mode 100644
index 0000000..82a435d
--- /dev/null
+++ b/Article-UI-Guidelines/images/flatlook3.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/flatlook4.gif b/Article-UI-Guidelines/images/flatlook4.gif
new file mode 100644
index 0000000..386b732
--- /dev/null
+++ b/Article-UI-Guidelines/images/flatlook4.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/flatlook5.gif b/Article-UI-Guidelines/images/flatlook5.gif
new file mode 100644
index 0000000..7ec6b89
--- /dev/null
+++ b/Article-UI-Guidelines/images/flatlook5.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/flatlook6.gif b/Article-UI-Guidelines/images/flatlook6.gif
new file mode 100644
index 0000000..54bfb88
--- /dev/null
+++ b/Article-UI-Guidelines/images/flatlook6.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/flatlook7.gif b/Article-UI-Guidelines/images/flatlook7.gif
new file mode 100644
index 0000000..bded644
--- /dev/null
+++ b/Article-UI-Guidelines/images/flatlook7.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/flatlook8.gif b/Article-UI-Guidelines/images/flatlook8.gif
new file mode 100644
index 0000000..cb8e210
--- /dev/null
+++ b/Article-UI-Guidelines/images/flatlook8.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/flatlook9.gif b/Article-UI-Guidelines/images/flatlook9.gif
new file mode 100644
index 0000000..43acb76
--- /dev/null
+++ b/Article-UI-Guidelines/images/flatlook9.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/folderSelection.gif b/Article-UI-Guidelines/images/folderSelection.gif
new file mode 100644
index 0000000..b2063d4
--- /dev/null
+++ b/Article-UI-Guidelines/images/folderSelection.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/goodParentCreation.gif b/Article-UI-Guidelines/images/goodParentCreation.gif
new file mode 100644
index 0000000..b68c88a
--- /dev/null
+++ b/Article-UI-Guidelines/images/goodParentCreation.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/goodTooltips.gif b/Article-UI-Guidelines/images/goodTooltips.gif
new file mode 100644
index 0000000..385fb75
--- /dev/null
+++ b/Article-UI-Guidelines/images/goodTooltips.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/goodWizardInit.gif b/Article-UI-Guidelines/images/goodWizardInit.gif
new file mode 100644
index 0000000..e408db9
--- /dev/null
+++ b/Article-UI-Guidelines/images/goodWizardInit.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/guidelineCheckbox.gif b/Article-UI-Guidelines/images/guidelineCheckbox.gif
new file mode 100644
index 0000000..d1954f9
--- /dev/null
+++ b/Article-UI-Guidelines/images/guidelineCheckbox.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/guidelineIndicator.gif b/Article-UI-Guidelines/images/guidelineIndicator.gif
new file mode 100644
index 0000000..05bfab6
--- /dev/null
+++ b/Article-UI-Guidelines/images/guidelineIndicator.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/icon_types.gif b/Article-UI-Guidelines/images/icon_types.gif
new file mode 100644
index 0000000..b527192
--- /dev/null
+++ b/Article-UI-Guidelines/images/icon_types.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/iconposition_main.gif b/Article-UI-Guidelines/images/iconposition_main.gif
new file mode 100644
index 0000000..f4faf16
--- /dev/null
+++ b/Article-UI-Guidelines/images/iconposition_main.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/impready_folderstructure.gif b/Article-UI-Guidelines/images/impready_folderstructure.gif
new file mode 100644
index 0000000..5156134
--- /dev/null
+++ b/Article-UI-Guidelines/images/impready_folderstructure.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/metaphor_concepts.gif b/Article-UI-Guidelines/images/metaphor_concepts.gif
new file mode 100644
index 0000000..e75b838
--- /dev/null
+++ b/Article-UI-Guidelines/images/metaphor_concepts.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/overlay_realestate.gif b/Article-UI-Guidelines/images/overlay_realestate.gif
new file mode 100644
index 0000000..abfaa98
--- /dev/null
+++ b/Article-UI-Guidelines/images/overlay_realestate.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/ovr_auxiliary.gif b/Article-UI-Guidelines/images/ovr_auxiliary.gif
new file mode 100644
index 0000000..165b3e4
--- /dev/null
+++ b/Article-UI-Guidelines/images/ovr_auxiliary.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/ovr_java.gif b/Article-UI-Guidelines/images/ovr_java.gif
new file mode 100644
index 0000000..acff43a
--- /dev/null
+++ b/Article-UI-Guidelines/images/ovr_java.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/ovr_java_sample1.gif b/Article-UI-Guidelines/images/ovr_java_sample1.gif
new file mode 100644
index 0000000..15bcb3f
--- /dev/null
+++ b/Article-UI-Guidelines/images/ovr_java_sample1.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/ovr_projectnature.gif b/Article-UI-Guidelines/images/ovr_projectnature.gif
new file mode 100644
index 0000000..21f3751
--- /dev/null
+++ b/Article-UI-Guidelines/images/ovr_projectnature.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/ovr_projectnature_sample.gif b/Article-UI-Guidelines/images/ovr_projectnature_sample.gif
new file mode 100644
index 0000000..208d3a2
--- /dev/null
+++ b/Article-UI-Guidelines/images/ovr_projectnature_sample.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/ovr_versioncontrol.gif b/Article-UI-Guidelines/images/ovr_versioncontrol.gif
new file mode 100644
index 0000000..214124d
--- /dev/null
+++ b/Article-UI-Guidelines/images/ovr_versioncontrol.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/ovr_versioncontrol_cvs.gif b/Article-UI-Guidelines/images/ovr_versioncontrol_cvs.gif
new file mode 100644
index 0000000..d448f0d
--- /dev/null
+++ b/Article-UI-Guidelines/images/ovr_versioncontrol_cvs.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/ovr_versioncontrol_cvs_samp.gif b/Article-UI-Guidelines/images/ovr_versioncontrol_cvs_samp.gif
new file mode 100644
index 0000000..cfe79df
--- /dev/null
+++ b/Article-UI-Guidelines/images/ovr_versioncontrol_cvs_samp.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/perspective_realestate.gif b/Article-UI-Guidelines/images/perspective_realestate.gif
new file mode 100644
index 0000000..3ee3a60
--- /dev/null
+++ b/Article-UI-Guidelines/images/perspective_realestate.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/perspective_specs.gif b/Article-UI-Guidelines/images/perspective_specs.gif
new file mode 100644
index 0000000..a2b1fe9
--- /dev/null
+++ b/Article-UI-Guidelines/images/perspective_specs.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/run_co.gif b/Article-UI-Guidelines/images/run_co.gif
new file mode 100644
index 0000000..0426423
--- /dev/null
+++ b/Article-UI-Guidelines/images/run_co.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/showViewMenu.gif b/Article-UI-Guidelines/images/showViewMenu.gif
new file mode 100644
index 0000000..cf90e8a
--- /dev/null
+++ b/Article-UI-Guidelines/images/showViewMenu.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/slushBucket.gif b/Article-UI-Guidelines/images/slushBucket.gif
new file mode 100644
index 0000000..aa50ef7
--- /dev/null
+++ b/Article-UI-Guidelines/images/slushBucket.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/synch_co.gif b/Article-UI-Guidelines/images/synch_co.gif
new file mode 100644
index 0000000..ff0ddb8
--- /dev/null
+++ b/Article-UI-Guidelines/images/synch_co.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/titlebar_specs.gif b/Article-UI-Guidelines/images/titlebar_specs.gif
new file mode 100644
index 0000000..8d9efda
--- /dev/null
+++ b/Article-UI-Guidelines/images/titlebar_specs.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/toolbar_realestate.gif b/Article-UI-Guidelines/images/toolbar_realestate.gif
new file mode 100644
index 0000000..93366b7
--- /dev/null
+++ b/Article-UI-Guidelines/images/toolbar_realestate.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/toolbar_specs.gif b/Article-UI-Guidelines/images/toolbar_specs.gif
new file mode 100644
index 0000000..403ad11
--- /dev/null
+++ b/Article-UI-Guidelines/images/toolbar_specs.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/tooltipCaps.gif b/Article-UI-Guidelines/images/tooltipCaps.gif
new file mode 100644
index 0000000..9c802c6
--- /dev/null
+++ b/Article-UI-Guidelines/images/tooltipCaps.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/treeview_specs.gif b/Article-UI-Guidelines/images/treeview_specs.gif
new file mode 100644
index 0000000..4967d7c
--- /dev/null
+++ b/Article-UI-Guidelines/images/treeview_specs.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/view_realestate.gif b/Article-UI-Guidelines/images/view_realestate.gif
new file mode 100644
index 0000000..ee85bdf
--- /dev/null
+++ b/Article-UI-Guidelines/images/view_realestate.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/wizardAppearance.gif b/Article-UI-Guidelines/images/wizardAppearance.gif
new file mode 100644
index 0000000..b5e2dd7
--- /dev/null
+++ b/Article-UI-Guidelines/images/wizardAppearance.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/wizardErrorMsgs.gif b/Article-UI-Guidelines/images/wizardErrorMsgs.gif
new file mode 100644
index 0000000..f6bfb63
--- /dev/null
+++ b/Article-UI-Guidelines/images/wizardErrorMsgs.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/wizardErrorMsgs2.gif b/Article-UI-Guidelines/images/wizardErrorMsgs2.gif
new file mode 100644
index 0000000..d8faf68
--- /dev/null
+++ b/Article-UI-Guidelines/images/wizardErrorMsgs2.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/wizardFieldPopulation.gif b/Article-UI-Guidelines/images/wizardFieldPopulation.gif
new file mode 100644
index 0000000..bc250bb
--- /dev/null
+++ b/Article-UI-Guidelines/images/wizardFieldPopulation.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/wizardMsgs.gif b/Article-UI-Guidelines/images/wizardMsgs.gif
new file mode 100644
index 0000000..07c6ba8
--- /dev/null
+++ b/Article-UI-Guidelines/images/wizardMsgs.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/wizban.gif b/Article-UI-Guidelines/images/wizban.gif
new file mode 100644
index 0000000..9081b96
--- /dev/null
+++ b/Article-UI-Guidelines/images/wizban.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/wizban183.gif b/Article-UI-Guidelines/images/wizban183.gif
new file mode 100644
index 0000000..ca18f78
--- /dev/null
+++ b/Article-UI-Guidelines/images/wizban183.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/wizbans.gif b/Article-UI-Guidelines/images/wizbans.gif
new file mode 100644
index 0000000..5c1c4d5
--- /dev/null
+++ b/Article-UI-Guidelines/images/wizbans.gif
Binary files differ
diff --git a/Article-UI-Guidelines/images/workbench_decomposed.gif b/Article-UI-Guidelines/images/workbench_decomposed.gif
new file mode 100644
index 0000000..cd0ecf4
--- /dev/null
+++ b/Article-UI-Guidelines/images/workbench_decomposed.gif
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/Contents.html b/Article-UI-Guidelines/v200202/Contents.html
new file mode 100644
index 0000000..75e82b8
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/Contents.html
@@ -0,0 +1,3887 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="Author" content="Build">
+<meta name="GENERATOR" content="Mozilla/4.72 [en] (Windows NT 5.0; U) [Netscape]">
+<title>Eclipse UI Guidelines</title>
+<link HREF="default_style.css" REL="stylesheet">
+<style type="text/css">
+<!--
+.tocstyle { font-family: Arial, Helvetica, sans-serif; font-size: 10px}
+-->
+</style>
+</head>
+<body>
+
+<div align="right"> <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2001-2002 Object Technology International, Inc. and others.</font>&nbsp;
+ <table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+ </tr>
+ </table>
+ </div>
+
+<h1>
+<img SRC="Idea.jpg" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+Eclipse User Interface Guidelines</h1></center>
+
+<center>
+<p><br><b><font color="#000000">By: Dave Springgay (OTI), Jin Li (IBM),</font></b>
+<br><b><font color="#000000">Julian Jones (IBM), and Greg Adams (OTI).</font></b>
+<p><b><font color="#000000">Last Updated: Feb. 27, 2002</font></b></center>
+
+<h3>
+<font color="#000000">Notice</font></h3>
+<font color="#000000">This is a living document.&nbsp; In other words, your feedback
+can influence the ideas and guidelines described here.&nbsp; If you have comments,
+please join the Eclipse Project community and give us your feedback.&nbsp; The
+Eclipse Project web site can be found at <a href="http://www.eclipse.org" target="_top">www.eclipse.org</a>.</font>
+<p>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h2>
+<a NAME="Introduction"></a>Introduction</h2>
+In this document the Eclipse User Interface Guidelines are defined.
+<p>Eclipse is a universal tool platform - an open, extensible IDE for anything,
+but nothing in particular. The real value comes from tool plug-ins that
+"teach" Eclipse how to work with things - Java&trade; files, Web content, graphics,
+video - almost anything you can imagine. Eclipse allows you to independently
+develop tools that integrate with other people's tools so seamlessly, you
+won't know where one tool ends and another starts. The very notion of a
+tool, as we know it, disappears completely.
+<p>The platform is very flexible and extensible, but this flexibility has
+a serious drawback.&nbsp; In particular, there is no way within the program
+to ensure User Interface consistency between the registered components
+within the platform.&nbsp; This document attempts to reconcile this problem,
+by defining standard User Interface guidelines for the creation of new
+components.&nbsp; If these guidelines are adopted within your own tools,
+it will lead to greater consistency with the platform and other tools,
+and an easier learning curve for your customers.
+<p>These guidelines are intended for use by designers and implementors
+of an Eclipse user interface extension.
+<br>&nbsp;
+<h3>
+<a NAME="The Workbench"></a>The Workbench</h3>
+To start out, let's take a look at the workbench user interface, and the
+various components within it.
+<p>The workbench is a collection of windows.&nbsp; Each window contains
+a menu, a toolbar, and one or more perspectives (see below).&nbsp; A perspective
+is a visual container for a set of views and editors (parts).&nbsp; These
+parts exist wholly within the perspective and are not shared.&nbsp; A perspective
+is like a page within
+a book.&nbsp; It exists within a window along with any number of other
+perspectives and, like a page within a book, only one perspective is visible
+at any time.
+<center>
+<p><img SRC="workbench_decomposed.jpg" height=578 width=480></center>
+
+<p>In the File menu you will find a New submenu, which contains menu items
+for Project, Folder, and File creation.&nbsp; The File menu also contains
+menu items for Import and Export, which are used to import files into the
+Workbench, and export them out again.&nbsp; In the Edit menu, you will
+find familiar actions like Cut, Copy, Paste, and Delete.&nbsp; These actions
+are known as global actions, and target the active part (as indicated by
+a shaded title bar). In other words, if the Delete action is invoked with
+the Navigator active, the actual implementation is performed by the Navigator.
+In the Perspective menu, you will find menu items to add views to the window,
+or change the layout of the window completely.&nbsp; In the Window menu
+you'll find the Preferences menu item, which is used to modify the functional
+preferences of Eclipse.
+<p>As a plug-in developer, you can contribute new views, editors, wizards,
+menu, and tool items to the platform.&nbsp; These contributions are defined
+using XML, and once registered, integrate seamlessly with the components
+which already exist in the platform.
+<h3>
+<a NAME="Projects, Folder and Files"></a>Projects, Folder and Files</h3>
+Eclipse can be used to create anything - java files, web content, graphics,
+video - almost anything you can imagine.&nbsp; These objects are stored
+as regular files within the Eclipse workspace.&nbsp; The workspace consists
+of one or more top level projects.&nbsp; Each project contains a collection
+of folders and files.&nbsp; These objects are known as <i>resources</i>.
+<br>&nbsp;
+<p>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h2>
+<a NAME="Getting Started"></a>Getting Started</h2>
+For most developers, an introduction to the platform can be overwhelming,
+and you may ask "where do I get started?".&nbsp; Here are a few basic guidelines
+which will help you.
+<p>This document is intended for UI developers.&nbsp; With this audience
+in mind, we can talk about the two main layers of any application: the
+model layer and the user interface layer.&nbsp; In Eclipse the model layer,
+known as the Workspace, is a collection of resources (projects, folders
+and files).&nbsp; The user interface, or Workbench, defines the presentation
+for those resources.
+<p>As a UI developer, you will also have a model and a presentation.&nbsp;
+If we assume that your goal is to make the model visible, through some
+presentation, most developers will start out by adding a new view or editor
+to the workbench.
+<p><font color="#000000">In Eclipse, an editor is used to interact with
+the primary focus of attention, which may be a document, data object, or
+person.&nbsp; In every case, the primary focus of attention is a reflection
+of the primary task.&nbsp; To illustrate this concept, let's look at some
+common examples.</font>
+<p><font color="#000000">To do Java programming, the primary task is to
+create, edit, and debug Java code. The primary focus is the Java code,
+so an editor is used to interact with that code.&nbsp; The navigator, outline,
+and properties view exist to support the primary task, but rarely hold
+your attention for an extended period of time while you are writing Java
+code.</font>
+<p><font color="#000000">To read email, the primary task is to create,
+send, read, and reply to email. The primary focus is a particular email
+message, so an editor is used to view or reply to an email message.&nbsp;
+A view may be used to select an email message to read, and open an editor.</font>
+<p><font color="#000000">To communicate using instant messenging, the primary
+task is the conversation.&nbsp; The primary focus is a particular conversation,
+so an editor is used to carry on that conversation.&nbsp; A view may be
+used to list people with whom you can initiate a conversation.</font>
+<p><font color="#000000">To browse the Web, the primary task is reading.
+The primary focus is a particular web page, so an editor is used to browse
+the web page. A</font>
+<br>
+ <font color="#000000">view may be used to save your favorite links, and reopen
+ them.&nbsp; At any time, you may decide to edit the page you are looking at.&nbsp;
+ This causes a new</font> <font color="#000000">editor to open.</font>
+<p><font color="#000000">In each case, the primary task determines the primary
+ focus of attention. As the primary focus of attention, it deserves a primary
+ position in the UI</font> <font color="#000000">(as an editor), and can contribute
+ actions to the window menu bar and toolbar.</font>
+<p><font color="#000000">Views are used to support the primary task.&nbsp; You
+ use them to navigate a hierarchy of information, open an editor, or view properties
+ for the active</font> <font color="#000000">editor.&nbsp; In reflection of their
+ support role, they can not contribute actions to the window menu bar and toolbar.</font>
+<p>Once you have added a view or editor, an interesting question arises.&nbsp;
+Where did this model come from?&nbsp; In Eclipse, most data is created
+using a Creation Wizard.&nbsp; You may want to add a Creation wizard too.
+And once an object exists, you may need a way to edit the properties for
+that object using a Properties page, or the Properties dialog.
+<p>All of these ideas will be discussed, in detail, in the following sections.
+<p>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h2>
+<a NAME="General UI Guidelines"></a>General UI Guidelines</h2>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<br>This document defines UI guidelines that are unique and specific to
+the Eclipse platform. It is a supplement to the other standard UI guidelines
+such as Microsoft&reg; User Experience, Macintosh Human Interface Guidelines,
+and Java Look and Feel Guidelines. You should continue to consult those
+guidelines for basic UI design and implementation recommendations.
+<p>It is expected that you already have a basic understanding of the Eclipse
+UI architecture and APIs, and the basic UI design principles: user in control,
+directness, consistency, forgiveness, feedback, aesthetics, and simplicity.
+If you do not currently have the prerequisite knowledge, please read the
+relevant documentation first.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">
+Guideline 1.1</font></b>
+<blockquote><font color="#3333FF">Follow and apply good user interface
+design principles: user in control, directness, consistency, forgiveness,
+feedback, aesthetics, and simplicity.</font></blockquote>
+
+<h3>
+<a NAME="The Spirit of Eclipse"></a>The Spirit of Eclipse</h3>
+At its heart, Eclipse is a platform for tool plug-ins.&nbsp; These plug-ins
+may be developed by a single team or by a partnership of teams, or the
+user may assemble a set of plug-ins from diverse sources.&nbsp; In either
+case, the usability of an individual tool, and Eclipse as a whole, will
+be positively influenced by user interface consistency.
+<p>If you're in doubt about the appropriate look and feel for a tool, look
+to the platform first, then the Java development tooling in Eclipse for
+guidance. In many cases, the workflow you imagine may already exist in
+Eclipse.&nbsp; If so, adopt the platform's workflow and user interface
+conventions. This will lead to greater consistency with the platform and
+other plugins, and an easier learning curve for your customers.
+<p>In some scenarios, it may be tempting to ignore the workflow of Eclipse and
+ implement a "custom" user interface.&nbsp; This interface will almost certainly
+ stand out like a sore thumb in an integrated environment, where other tools
+ adopt the platform conventions.&nbsp; You lose the benefit of past experience,
+ and force your customers to learn new ideas.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">
+Guideline 1.2</font></b>
+<blockquote><font color="#3333FF">Follow the platform lead for user interface
+conventions.</font></blockquote>
+If you decide to reuse the conventions of Eclipse, be careful not to misappropriate
+Eclipse specific UI conventions.&nbsp; For instance, the active part in
+a workbench window is indicated by a shaded title.&nbsp; The use of shaded
+titles within an editor (see below) may be one way to indicate where the
+focus is, within that part, but it will also blur the concept of part activation
+in the window.
+<br>&nbsp;
+<p><img SRC="badHilight.jpg" HSPACE=50 height=427 width=706>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">
+Guideline 1.3</font></b>
+<blockquote><font color="#3333FF">Be careful not to mix UI metaphors.&nbsp;
+It may blur the original concept, and your own application.</font></blockquote>
+Eclipse is an open source project.&nbsp; If you feel your ideas are generally
+useful, join the Eclipse community, write a proposal, and work with the
+Eclipse community to make Eclipse a better platform for product development
+and customer satisfaction.
+<p>Visit www.eclipse.org and join the Eclipse UI mailing list platform-ui-dev.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">
+Guideline 1.4</font></b>
+<blockquote><font color="#3333FF">If you have an interesting idea, work
+with the Eclipse community to make Eclipse a better platform for all.</font></blockquote>
+
+<h3>
+<a NAME="Capitalization"></a>Capitalization</h3>
+Consistent capitalization of text within a plug-in leads to a more polished
+feel, and greater perception of quality.&nbsp; Within a dialog or window,
+headline capitalization should be applied to all titles, menus, toolbar
+items, tabs, and push buttons.&nbsp; Sentence style capitalization should
+be applied to all check boxes, radio buttons, and group labels.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b> <font color="#3333FF">Guideline
+1.5</font></b>
+<blockquote><font color="#3333FF">Use Headline style capitalization for
+all titles, including those used for windows, dialogs, tabs, column headings
+and push buttons. Capitalize the first and last words, and all nouns, pronouns,
+adjectives, verbs and adverbs.&nbsp; Do not include ending punctuation.</font></blockquote>
+<img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">
+Guideline 1.6</font></b>
+<blockquote><font color="#3333FF">Use Sentence style capitalization for
+all control labels in a dialog or window, including those for check boxes,
+radio buttons, group labels, and simple text fields.&nbsp; Capitalize the
+first letter of the first word, and any proper names.</font></blockquote>
+
+<h3>
+<a NAME="Colors"></a>Colors</h3>
+Eclipse provides full support for indexed and true color display.&nbsp;
+On paletted devices, true colors will be mapped to the appropriate palette
+color using a best fit approach, so no work is required of the plug-in
+developer to support these devices.&nbsp; Images associated with a menu
+item, toolbar item, or control icon may be defined with 256 colors or greater.
+<br>&nbsp;
+<h3>
+<a NAME="Language"></a>Language</h3>
+Eclipse will ship on a variety of different platforms, in a variety of
+locales.&nbsp; In reflection of the different languages and numeric formats
+in each, a localization strategy should be adopted for the text and images
+within each plug-in.&nbsp; This involves the separation of all resources
+from the source code of a plug-in itself, so that those resources can be
+translated to a new locale.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">
+Guideline 1.7</font></b>
+<blockquote><font color="#3333FF">Localize the resources within your plug-in.</font></blockquote>
+
+<h3>
+<a NAME="Error Handling"></a>Error Handling</h3>
+If an error occurs in Eclipse, the appropriate response will be dependent
+on the context of the error.
+<p>When a user input error occurs in a wizard, please refer to <a href="#Wizards">Wizards</a>
+section on how to handle the error.
+<p>When an error occurs in an editor, please refer to <a href="#Editors">Editors</a>
+section on how to handle the error.
+<p>When an error occurs which requires either an explicit user input or
+immediate attention from users, a modal dialog should be used to communicate
+the error to the user.&nbsp; This forces the user to notice, and deal with
+the problem. It is not appropriate to activate a part and display the error
+in the part.&nbsp; If this approach is taken, the user may fail to notice
+the activation and the error.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+1.8</font></b>
+<blockquote><font color="#3333FF">When an error occurs which requires either
+an explicit user input or immediate attention from users, communicate the
+occurrence with a modal dialog.</font></blockquote>
+If a programming error occurs in the product, an error dialog should be
+used to communicate the occurrence to the user.&nbsp; The error should
+also be logged using the workbench error logging facility.&nbsp; This gives
+the user an opportunity to restart the platform, remove the offending plugin,
+and contact their system administrator.
+<p>The plug-in should provide the following information in the detail area
+of the error dialog:
+<ul>
+<li>
+Provider name</li>
+
+<li>
+Plug-in name (user friendly name)</li>
+
+<li>
+Plug-in ID</li>
+
+<li>
+Version</li>
+</ul>
+<img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+1.9</font></b>
+<blockquote><font color="#3333FF">If a programming error occurs in the
+product, communicate the occurrence with a dialog, and log it.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h2>
+<a NAME="Component Development"></a>Component Development</h2>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Actions"></a>Actions</h3>
+An <i>action</i> is a command which can be triggered by the user.&nbsp;
+An action may appear as an item in a menu, or an item in a toolbar.&nbsp;
+In reflection of this, it has attributes for the menu or tool item label,
+tooltip, and image.
+<p>As a plug-in developer, you can contribute actions to the window menu
+bar and toolbar, or to individual views and editors.&nbsp; Contribution
+to the window is performed using an <i>action set</i>, a set of task oriented
+actions which the user can show or hide.&nbsp; Contribution to a view or
+editor is performed using individual actions.
+<p>Here is an illustration of the main areas of contribution.
+<p><img SRC="actionExamples.jpg" HSPACE=50 height=562 width=474>
+<p>In this section we'll look at general action guidelines.&nbsp; For information
+on window, view, or editor specific guidelines, see <a href="#Windows">Windows</a>,
+<a href="#Views">Views</a>,
+and <a href="#Editors">Editors</a>.
+<h4>
+Appearance</h4>
+Each action must have a label, tool tip, and image.&nbsp; If the action
+appears in a toolbar, the action image will be displayed on all platforms.&nbsp;
+If the action appears in a menu, the image will only be displayed on some
+platforms, such as Windows&reg; 2000.&nbsp; The label and tool tip should use
+Headline style capitalization, as defined in General UI Guidelines.
+<p>Each action must provide one full color image.&nbsp; This image will
+be displayed if the mouse is placed over the action.&nbsp; It will also
+be used to generate the enabled, disabled, and pressed images which appear
+in normal action use.&nbsp; Actions which are contributed in code also
+have the option to define explicit images for enabled, disabled, and roll
+over.&nbsp; This option can be used for greater control over image appearance.
+<p>The following snapshot shows the valid use of Headline capitalization
+in a toolbar.
+<p><img SRC="tooltipCaps.jpg" height=141 width=244>
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+2.1</font></b>
+<blockquote><font color="#3333FF">Each action must have a label, tool tip,
+and full color image.&nbsp; The label and tool tip must use Headline style
+capitalization.</font></blockquote>
+The tool tips for an action should describe the <i>behavior which occurs</i>
+if the action is invoked.&nbsp; For instance, in the following snapshot
+the behavior of the Field button is shown.&nbsp; If the action is unpressed,
+pressing the action will hide the fields.&nbsp; If the action is pressed,
+unpressing the action will show the fields.&nbsp; This behavior is shown
+using two tool tips.
+<p><img SRC="goodTooltips.jpg" height=203 width=437>
+<p>A single tool tip should not be used to convey the behavior of both
+cases.&nbsp; It is too ambiguous.
+<p><img SRC="badTooltips.jpg" height=116 width=640>
+<p>Nor should it label the state the toolbar button is currently in.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+2.2</font></b>
+<blockquote><font color="#3333FF">The action tooltip should describe the
+result of the action, not the current state of the action.</font></blockquote>
+For consistency, any action which has a similar behavior to existing actions
+in the workbench, should adopt the same terminology.
+<p>When creating a resource, the term "New" should be used in an action
+or wizard.&nbsp; For instance, "New File", "New Project" and "New Java
+Class".&nbsp; The term "Delete" should be used when deleting an existing
+resource.
+<p>When creating an object inside a resource (e.g., a tag in an XML file;
+a method or field in a Java class), the term "Add" should be used; the
+user is adding something to an existing resource.&nbsp; The term "Remove"
+should be used to remove an object from a resource.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+2.3</font></b>
+<blockquote><font color="#3333FF">Adopt the labeling terminology of the
+workbench for New, Delete, Add, and Remove actions.</font></blockquote>
+
+<h4>
+Enablement</h4>
+An action should only be enabled if it can be completed successfully.&nbsp;
+If this is not the case, the action should be disabled.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+2.4</font></b>
+<blockquote><font color="#3333FF">An action should only be enabled if it
+can be completed successfully.</font></blockquote>
+Action enablement should be quick to calculate.&nbsp; If it is too expensive
+to calculate the enablement of an action, the action should be optimistically
+enabled.&nbsp; If the action is invoked, it should calculate the real enablement,
+and show a dialog to the user if it is not available.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+2.5</font></b>
+<blockquote><font color="#3333FF">Action enablement should be quick.&nbsp;
+If action enablement cannot be quick, enable the action optimistically
+and display an appropriate message if the action is invoked, but cannot
+be completed.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Dialogs"></a>Dialogs</h3>
+A dialog is used for modal interaction with the user.&nbsp; It can be used
+to solicit information, or provide feedback.
+<br>&nbsp;
+<h4>
+Initialization</h4>
+When a dialog first opens, the initial focus should be given to the first
+control where information is required from the user.&nbsp; This control
+can be determined by the tab order of controls until a control is found
+where information is required.&nbsp; If the dialog provides simple feedback,
+or requires simple confirmation from the user, the initial focus may also
+be assigned to the default button.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">
+Guideline 3.1</font></b>
+<blockquote><font color="#3333FF">When a dialog opens, set the initial
+focus to one of the controls in the container.</font></blockquote>
+
+<h4>
+Multiple Item Selection</h4>
+Slush Bucket widgets (also known as the Twin Box design) should flow from
+the left to the right with the source objects on the left and selected
+files on the right.
+<p>Slush Buckets should also have the following control buttons, in this
+order, for moving objects from the source the selected buckets.
+<br>&nbsp;
+<center><table BORDER=3 CELLSPACING=3 CELLPADDING=3 >
+<tr>
+<td><b>Button</b></td>
+
+<td><b>Function</b></td>
+</tr>
+
+<tr>
+<td>></td>
+
+<td>Add whatever is selected on the left to the right</td>
+</tr>
+
+<tr>
+<td>&lt;</td>
+
+<td>Remove selected items from the right</td>
+</tr>
+
+<tr>
+<td>>></td>
+
+<td>Add all (whether they are selected or not)</td>
+</tr>
+
+<tr>
+<td>&lt;&lt;</td>
+
+<td>Remove&nbsp; all</td>
+</tr>
+</table></center>
+
+<p><img SRC="slushBucket.jpg" height=278 width=533>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">
+Guideline 3.2</font></b>
+<blockquote><font color="#3333FF">Slush Bucket widget (or Twin Box) should
+flow from left to right with the source objects on the left hand side.
+It should have the >, &lt;, >>, &lt;&lt; control buttons in this order.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Wizards"></a>Wizards</h3>
+In Eclipse, a wizard is commonly used for the creation of new resources,
+resource import, or resource export.&nbsp; It can also be used for the
+execution of any task involving a sequential series of steps.&nbsp; A wizard
+should be used if there are many steps in the task, and they must be completed
+in a specific order.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.1</font></b>
+<blockquote><font color="#3333FF">Use a wizard for any task consisting
+of many steps, which must be completed in a specific order.</font></blockquote>
+
+<h4>
+Appearance</h4>
+At the top of each wizard is a header, containing a banner graphic and
+a text area.&nbsp; The banner graphic contains an image representing the
+wizard task, and should be created with a white to blue, gray scale palette
+for consistency with other banners in Eclipse.&nbsp; These colors also
+avoid distracting the user from the important fields of the wizard.&nbsp;
+The text area is used to prompt the user for information which is absent,
+and display error messages if information is invalid.&nbsp; The presence
+of the header, with banner graphic and text area, creates a more polished
+feel, and greater perception of quality to the wizard.
+<p>At the bottom of each wizard, a Back, Next, Finish, and Cancel button
+should appear.
+<p><img SRC="wizardAppearance.jpg" HSPACE=40 height=390 width=500>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.2</font></b>
+<blockquote><font color="#3333FF">Each wizard must contain a header with
+a banner graphic and a text area for user feedback.&nbsp; It must also
+contain Back, Next, Finish, and Cancel buttons in the footer.</font></blockquote>
+
+<h4>
+Initialization</h4>
+When a wizard first opens, the focus should be placed in the first field
+requiring information (see Guidelines 3.1).&nbsp; The header should be
+used to prompt the user for the first piece of required information.
+<p><img SRC="goodWizardInit.jpg" height=122 width=570>
+<p>It is not appropriate to display an error message.&nbsp; At this point,
+the user hasn't done anything yet.
+<p><img SRC="badWizardInit.jpg" height=124 width=576>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.3</font></b>
+<blockquote><font color="#3333FF">Start the wizard with a prompt, not an
+error message.</font></blockquote>
+The initial state of the wizard should be derived from the context where
+it is opened.&nbsp; For instance, in the New File wizard, the current workbench
+selection is examined.&nbsp; If it points to a valid project or folder,
+the wizard will pre-populate the parent field with the parent project or
+folder name, and put cursor focus in the next field requiring user input.&nbsp;
+If the user's selection does not point to a valid parent project or folder,
+the wizard will not pre-populate the folder name. Instead, it will leave
+the field blank and put the cursor focus in the field.&nbsp;&nbsp; When
+the user's selection is on a file, a wizard may also go through these calculations
+using the parent folder or project of the file.
+<p><img SRC="wizardFieldPopulation.jpg" height=279 width=533>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.4</font></b>
+<blockquote><font color="#3333FF">Seed the fields within the wizard using
+the current workbench state.</font></blockquote>
+
+<h4>
+Validation of Data</h4>
+Information validation within a wizard should be done in tab order.&nbsp;
+If the first required field is empty, an informative prompt should be shown
+in the text area, directing the user to fill in the field.&nbsp; If the
+first required field is in error, an error message should be shown in the
+text area.&nbsp; If the first required field is valid, check the next field,
+and so on.&nbsp; The text area should not be used to display more than
+one prompt or error at a time.
+<p>If dialog information is absent or invalid, the Next or Finish buttons
+should be disabled until the situation is resolved.&nbsp; When resolution
+occurs, and all of the information has been provided, the Next or Finish
+buttons may be enabled.
+<p><img SRC="wizardErrorMsgs.jpg" height=527 width=540>
+<p>Error messages should only be displayed when user input is invalid.
+<p><img SRC="wizardErrorMsgs2.jpg" height=199 width=454>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.5</font></b>
+<blockquote><font color="#3333FF">Validate the wizard data in tab order.&nbsp;
+Display a prompt when information is absent, and an error when information
+is invalid.</font></blockquote>
+<img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.6</font></b>
+<blockquote><font color="#3333FF">Only enable the Next / Finish buttons
+if all required information in the dialog is present and valid.</font></blockquote>
+The error messages in a wizard should be intended for the end user, not
+the developer.&nbsp; With this in mind, message IDs should never be presented
+as part of the error text in the wizard's header area.
+<p><img SRC="wizardMsgs.jpg" height=98 width=543>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.7</font></b>
+<blockquote><font color="#3333FF">Remove all programming message ID's from
+wizard text.</font></blockquote>
+
+<h4>
+Browse Buttons</h4>
+An edit field and "Browse..." button combination should be used whenever
+an existing object is referenced within a wizard.&nbsp; The edit field
+is used for direct input of the existing object, and the Browse button
+is used to browse and select the object from a list of all possible choices.
+<p>For instance, in the New Java Class wizard, a "Browse..." button is
+placed beside the "Super Class" edit field.&nbsp; If the browse button
+is pressed, a Browse Dialog will appear, and the user can select a super
+class.&nbsp; This pattern should be used whenever a link will be established
+between a new object and an old one.&nbsp; The "Browse..." button should
+be located to the right of the edit field.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.8</font></b>
+<blockquote><font color="#3333FF">Use a Browse Button whenever an existing
+object is referenced in a wizard.</font></blockquote>
+In the Browse Dialog, invalid choices should not appear.&nbsp; When the
+dialog is closed, and focus returns to the parent control, refresh the
+enablement state of controls within the dialog.&nbsp; In particular, refresh
+the enablement of Next, Finish, and OK buttons.
+<p>An example of valid and invalid filtering is shown in the following
+snapshot.
+<p><img SRC="folderSelection.jpg" height=1220 width=611>
+<br>&nbsp;
+<h4>
+Wizard Completion</h4>
+The New Resource and Import Wizards commonly create new files, folders,
+and projects within the workbench.&nbsp; If a single file is created, the
+wizard should open the file in an editor in the active page.&nbsp; If more
+than one file is created, open the most important, or central file.&nbsp;
+This makes it easier to modify and save the file.
+<p>Have a readme.html file for every example project, and opening that
+readme.html automatically upon project creation.&nbsp; This will give users
+an immediate overview of the example: what it does, prerequisites, limitations,
+steps to take, and so on.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.9</font></b>
+<blockquote><font color="#3333FF">If a new file is created, open the file
+in an editor.&nbsp; If a group of files are created, open the most important,
+or central file in an editor. Open the readme.html file upon creation of
+an example project.</font></blockquote>
+If a new project is created, the wizard should change the active perspective
+within the workbench to one which is appropriate for the new project type.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.10</font></b>
+<blockquote><font color="#3333FF">If a new project is created, change the
+active perspective to suit the project type.</font></blockquote>
+In either case, where a file, folder, or project is created, the wizard
+should select and reveal the new object in the appropriate view.&nbsp;
+This provides concrete evidence to the user that, yes, the new object was
+created and now exists.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.11</font></b>
+<blockquote><font color="#3333FF">If a new object is created, select and
+reveal the new object in the appropriate view.</font></blockquote>
+In many situations, the creation of a resource may involve the creation
+of a project or folder to contain the resource.&nbsp; If the containing
+project or folder can be created from within the wizard (with a very reasonable
+set of defaults), the wizard should allow it. If the creation of such resources
+requires detailed user interaction in order for parent project or folder
+to be set up correctly, the wizard should not attempt to do this. Instead,
+the wizard error text should instruct the user that "The specified project
+does not exist".
+<p>The EAR Import wizard is an example where allowing the user to specify
+the name of the parent project in place makes for a much more usable interaction.
+In this case, based on the user provided name, the wizard goes off and
+creates not only the EAR project itself, but also any web projects, etc.,
+that may be needed as well.
+<p><img SRC="goodParentCreation.jpg" height=299 width=506>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.12</font></b>
+<blockquote><font color="#3333FF">Create folder objects in a wizard if
+reasonable defaults can be defined.</font></blockquote>
+
+<h4>
+Terminology</h4>
+Within a creation wizard, if the item being created must be a Project (not
+a folder below a project) the label "Project Name" should be used to receive
+the project name.&nbsp; If it can be a folder below the project, the term
+"Folder" should be used.&nbsp; Do not qualify the term (e.g., do not use
+"Server Folder").
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+4.13</font></b>
+<blockquote><font color="#3333FF">Use the label "Project Name" when the
+item must be a Project; otherwise, use the label "Folder". Do not qualify
+the term.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Editors"></a>Editors</h3>
+An editor is a visual component within a workbench page. It is <font color="#000000">used
+to interact with the primary focus of attention, which may be a document,
+data object, or person.&nbsp; The primary focus of attention is a reflection
+of the primary task.</font>
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.1</font></b>
+<blockquote><font color="#3333FF">Use a editor to edit or browse a file,
+document, or other input object.</font></blockquote>
+Modifications made in an editor follow an open-save-close lifecycle model.&nbsp;
+When an editor first opens, the editor contents should be unmodified (clean).&nbsp;
+If the contents are modified, the editor should communicate this change
+to the platform.&nbsp; In response, an asterisk will appear in the editor
+tab.&nbsp; The modifications should be buffered within the edit model,
+until such a time as the user explicitly saves them.&nbsp; At that point,
+the modifications should be committed to the model storage.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.2</font></b>
+<blockquote><font color="#3333FF">Modifications made in an editor must
+follow an open-save-close lifecycle model.</font></blockquote>
+An editor is document or input-centric.&nbsp; Each editor has an input,
+and only one editor can exist for each editor input within a page.&nbsp;
+This policy has been designed to simplify part management.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.3</font></b>
+<blockquote><font color="#3333FF">Only one instance of an editor may exist,
+for each editor input, within a perspective.</font></blockquote>
+In addition, it should be possible to open a separate instance of an editor
+for each input.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.4</font></b>
+<blockquote><font color="#3333FF">It must be possible to open a separate
+instance of an editor for each input.</font></blockquote>
+
+<h4>
+Appearance</h4>
+The editor should be labeled with the name of the resource being edited;
+not with the name of the editor.
+<p><img SRC="editorTitles.jpg" height=84 width=562>
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.5</font></b>
+<blockquote><font color="#3333FF">The editor should be labeled with the
+name of the file, document, or input being edited.</font></blockquote>
+If the editor contains more than one page, a tab control should be used
+for page activation.&nbsp; The use of this control is demonstrated by the
+plugin file and html editors.
+<p>Tab labels should be kept to one word, and two words at most.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.6</font></b>
+<blockquote><font color="#3333FF">In multipage editors, use a tab control
+for page activation.Tab labels should be kept to one word, and two words
+at most.</font></blockquote>
+
+<h4>
+Menus</h4>
+An editor may contribute items directly to the window menu bar.&nbsp; All
+of the actions available in the editor should be displayed in the window
+menu bar, for accessibility and clarity.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.7</font></b>
+<blockquote><font color="#3333FF">All of the actions available in the editor
+should be added to the window menu bar.</font></blockquote>
+The following format is recommended, to ensure consistency across Eclipse
+and better ease of use.
+<br>&nbsp;
+<center><table BORDER COLS=4 WIDTH="80%" >
+<tr>
+<td>Edit</td>
+
+<td>Insert</td>
+
+<td>Format</td>
+
+<td>Perspective</td>
+</tr>
+
+<tr>
+<td>Add any object centric actions here</td>
+
+<td>Add any "insert" actions here</td>
+
+<td>Format actions for the current selection.</td>
+
+<td>Actions to control what you see in the editor.</td>
+</tr>
+</table></center>
+
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.8</font></b>
+<blockquote><font color="#3333FF">Use the standard format for editor contributions
+in the window menu bar.</font></blockquote>
+The window menu bar contains a number of global actions, such as Cut, Copy,
+and Paste in the Edit menu.&nbsp; These actions target the active part,
+as indicated by a shaded title area.&nbsp; If these actions are supported
+within an editor, the editor should hook these window actions, so that
+selection in the window menu bar or toolbar produces the same result as
+selection of the same action in the editor.&nbsp; The editor should not
+ignore these actions, and contribute duplicate actions to the window menu
+bar or toolbar.
+<p>A complete list of the global actions is declared in the IWorkbenchActionConstants.java
+(see below).
+<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * From IWorkbenchActionConstants.</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Standard global
+actions in a workbench window.</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final
+String [] GLOBAL_ACTIONS = {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+UNDO,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+REDO,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CUT,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+COPY,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+PASTE,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+PRINT,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+DELETE,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+FIND,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+SELECT_ALL,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+BOOKMARK</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</tt>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.9</font></b>
+<blockquote><font color="#3333FF">If an editor has support for Cut, Copy,
+Paste, or any of the global actions, these actions must be executable from
+the same actions in the window menu bar and toolbar.</font></blockquote>
+
+<h4>
+Toolbars</h4>
+An editor may contribute actions directly to the window toolbar.&nbsp;
+The toolbar is used to expose the most commonly used actions in an editor.&nbsp;
+Any action which appears in the toolbar must also appear in the menu, but
+there is no need to duplicate every action in the menu within the toolbar.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.10</font></b>
+<blockquote><font color="#3333FF">Fill the editor toolbar with the most
+commonly used items in the view menu.</font></blockquote>
+The use of a local toolbar within an editor is contrary to the design of
+the workbench.&nbsp; Within the workbench, the toolbar for an editor is
+shared with editors of the same type.&nbsp; This reduces the flash which
+occurs when you switch between editors, reduces the number of images and
+actions in the product, and creates a better feel of integration.
+<h4>
+Context Menus</h4>
+A context menu should be used for context sensitive interaction with the
+objects in an editor.&nbsp; If an object is selected in an editor, and
+the context menu is opened, the context menu should only contain actions
+which are appropriate for the selection.&nbsp; Actions which affect the
+presentation of the view should not appear in the context menu.
+<p>In a text editor, you may assume that there is only one type of selection:
+text.&nbsp; In this case, the contents of the context menu will remain
+consistent for any selection in the editor.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.11</font></b>
+<blockquote><font color="#3333FF">Fill the context menu with selection
+oriented actions, do not presentation or global actions.</font></blockquote>
+For consistency with other editors in Eclipse, each editor should adopt
+a common order for actions within the context menu.&nbsp; This format is
+shown in the following table.&nbsp; Within this table, each item represents
+a category of actions.&nbsp; The categories within the context menu should
+be kept distinct from one another through the use of separators.
+<br>&nbsp;
+<center><table BORDER COLS=1 WIDTH="200" >
+<tr>
+<td>Undo / Redo</td>
+</tr>
+
+<tr>
+<td>Add</td>
+</tr>
+
+<tr>
+<td>Show In</td>
+</tr>
+
+<tr>
+<td>Cut Copy Paste</td>
+</tr>
+
+<tr>
+<td>Delete</td>
+</tr>
+
+<tr>
+<td>Other Plugin Additions</td>
+</tr>
+
+<tr>
+<td>Save</td>
+</tr>
+</table></center>
+
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.12</font></b>
+<blockquote><font color="#3333FF">Use the standard format for editor context
+menus.</font></blockquote>
+For good spatial navigation, fill the context menu with a fixed set of
+actions for each selection type.&nbsp; Once the contents have been defined,
+the enablement state of each action should determined using the selected
+object state.&nbsp; In doing so, you establish a consistency which makes
+the menu more predictable, and easier to navigate.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.13</font></b>
+<blockquote><font color="#3333FF">Fill the context menu with a fixed set
+of actions for each selection type, and then enable or disable each to
+reflect the selection state.</font></blockquote>
+One of the primary goals for the platform UI is extensibility.&nbsp; In
+fact, it is this extensibility which gives you the freedom to add new views,
+editors, perspectives, and actions to the platform.&nbsp; Of course, extensibility
+is a two way street.&nbsp; While you may wish to extend the platform, others
+may wish to extend your view or editor.&nbsp; It is common for one plug-in
+to add actions to the menu, toolbar, or context menu of an editor from
+another plugin.
+<p>In the platform, the menu and toolbar for an editor are automatically extended
+ by the platform.&nbsp; In contrast, context menu extension is supported in collaboration
+ between the editor and the platform.&nbsp; To achieve this collaboration, an
+ editor must register each context menu it contains with the platform.&nbsp;
+ It should also define an action filter for each object type in the editor.&nbsp;
+ An action filter makes it easier for one plug-in to add an action to objects
+ in an editor defined by another plug-in.&nbsp; The target is described using
+ object type and attributes.&nbsp;&nbsp; For more information on the implementation
+ of this concept, refer to <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+ an Eclipse View.</a>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.14</font></b>
+<blockquote><font color="#3333FF">Register all context menus in the editor
+with the platform.</font></blockquote>
+<img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.15</font></b>
+<blockquote><font color="#3333FF">Implement an Action Filter for each object
+type in the editor.</font></blockquote>
+
+<h4>
+Resource Deletion</h4>
+When a resource is deleted from one of the navigators (e.g., Navigator
+view, J2EE view, Data view, or DBA Explorer view), the handling of any
+editor that is currently open on that resource should be dependent on the
+change state of the editor.
+<p>If the editor does not contain any changes since the resource was last
+saved then the editor should be immediately closed.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.16</font></b>
+<blockquote><font color="#3333FF">If the input to an editor is deleted,
+and the editor contains no changes, the editor should be closed.</font></blockquote>
+If the editor contains changes to the resource since the resource was last
+saved (i.e., it is "dirty"), the editor should give the user a chance to
+save their changes to another location, and then close.&nbsp; Here is a
+sample of the dialog which should be displayed:
+<p><img SRC="fileDeletedDialog.jpg" HSPACE=50 height=124 width=436>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.17</font></b>
+<blockquote><font color="#3333FF">If the input to an editor is deleted,
+and the editor contains changes, the editor should give the user a chance
+to save their changes to another location, and then close.</font></blockquote>
+
+<h4>
+Unsaved Changes</h4>
+If the editor contains changes to the resource since the resource was last
+saved (i.e., it is "dirty"), an asterisk should be used to prefix the resource
+name presented in the editor tab:
+<p><img SRC="dirtyEditor.jpg" HSPACE=50 height=331 width=334>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.18</font></b>
+<blockquote><font color="#3333FF">If the resource is dirty, prefix the resource
+name presented in the editor tab with an asterisk.</font></blockquote>
+
+<h4>
+Read Only Files</h4>
+With a name like "editor", it's not surprising that the issue of read-only
+files may cause confusion.&nbsp; If it's read-only, how can you edit it?&nbsp;
+In this case, you should fall back to first principles.
+<blockquote>A view is typically used to navigate a hierarchy of information,
+open an editor, or display properties for the active editor.&nbsp; An editor
+is typically used to edit or browse a file, document or other input object.</blockquote>
+This statement is appropriate whether a file is read-only or not.&nbsp;
+In either case, the user should be able to select the file, open it, and
+browse the contents within an editor. If the file is read-only, the File
+> Save action should be disabled and the File > Save As should be enabled.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.19</font></b>
+<blockquote><font color="#3333FF">Treat read-only editor input as you would
+any other input.&nbsp; Enable the Save As if possible.</font></blockquote>
+
+<h4>
+Integration with Other Views</h4>
+In Eclipse, there is a special relationship between each editor and the
+Outline view.&nbsp; When an editor is opened, the Outline view will connect
+to the editor, and ask it for an outline model.&nbsp; If the editor answers
+an outline model, that model will be displayed in the Outline view whenever
+the editor is active.&nbsp; The outline is used to navigate through the
+edit data, or interact with the edit data at a higher level of abstraction.
+<p>For instance, if you open a .java file in an editor, the structure of
+the class is displayed in the Outline view.&nbsp; If you select a method
+or field in the outline, the text declaration of that item will be selected
+and revealed in the editor.&nbsp;&nbsp; If you select a method or field,
+and open the context menu, you can interact with the item as a conceptual
+unit, rather than just a bunch of text.
+<p>In general, an editor should provide an outline model to the Outline
+view if the data within the editor is too extensive to see on a single
+screen, and will yield a structured outline.&nbsp; This structured outline
+makes it very easy to navigate through objects like a java file or html
+file.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.20</font></b>
+<blockquote><font color="#3333FF">If the data within an editor is too extensive
+to see on a single screen, and will yield a structured outline, the editor
+should provide an outline model to the Outline view.</font></blockquote>
+
+<p><br>When an Editor has an interaction with the Outline view, notification
+about location should be two-way. That is, the user should be able to select
+something in the outline and have the editor position updated, and the
+user should be able to select something in the Editor pane and have the
+outline view updated.
+<p>Context&nbsp; menu should be available, as appropriate, in the outline
+view which should support creation operations as appropriate.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.21</font></b>
+<blockquote><font color="#3333FF">Notification about location between an
+Editor and the Outline view should be two-way. Context menu should be available
+in the Outline view as appropriate.</font></blockquote>
+
+<p><br>If the edit model contains errors or warnings, they should be indicated
+in the Outline view.&nbsp; An error or warning image should be added to
+the item with the error or warning respectively.&nbsp; If the item is part
+of a tree, the error or warning image should also be propagated to each
+ancestor of the item. If the ancestor of the item doesn't contain errors
+or warnings, a different error or warning image -- for example, a grayed
+X icon for error -- should be used for the ancestor. For instance, in the
+following line, the addFastView method has an error, so an error image
+is added to the item and its parent.
+<br>&nbsp;
+<p><img SRC="errorsInOutline.jpg" HSPACE=50 height=284 width=223>
+<br>&nbsp;
+<p>For this to work, care must be taken to design icons with overlay in
+mind, so that glyphs can be applied to the ancestor's icon.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.22</font></b>
+<blockquote><font color="#3333FF">An error or warning image should be added
+to items with the error or warning respectively. If the item is part of
+a tree, the error or warning image should also be propagated to each ancestor
+of the item. If the ancestor of the item doesn't contain errors or warnings,
+a different error or warning image should be used for the ancestor..</font></blockquote>
+In an editor, task objects are commonly used to mark a location within
+a document.&nbsp; Once a task has been created, it appears in the Task
+view.&nbsp; If the task is selected, you may reopen the editor at the location
+defined in the Task.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.23</font></b>
+<blockquote><font color="#3333FF">If appropriate, implement the "Add Task"
+feature in your editor.</font></blockquote>
+A bookmark object can also be used mark a location within a document.&nbsp;
+Once a bookmark has been created, it appears in the Bookmarks view.&nbsp;
+If the bookmark is selected, you may reopen the editor at the location
+defined in the Task.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.24</font></b>
+<blockquote><font color="#3333FF">If appropriate, implement the "Add Bookmark"
+feature in your editor.</font></blockquote>
+
+<h4>
+Line Numbers</h4>
+Editors with source lines of text should have line numbers, and optionally
+column numbers.&nbsp; Editors should also support a “Goto Line…” feature
+available in the context menu allowing users to quickly jump to a desired
+line.&nbsp; This functionality should be implemented along with line numbering
+in the editor.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.25</font></b>
+<blockquote><font color="#3333FF">Editors with source lines of text should
+have line numbers, and optionally column numbers..</font></blockquote>
+
+<h4>
+Table Cell Editors</h4>
+A single-click over a cell should select the current item and put the cell
+into edit mode. In edit mode, any dropdowns, buttons, or other controls
+in the cell should be rendered upon the single-click.
+<br>&nbsp;
+<p><img SRC="cellTableEditor.jpg" height=383 width=284>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.26</font></b>
+<blockquote><font color="#3333FF">Table cell editors should support the
+single-click activation model, and in edit mode, they should render complex
+controls upon single-click.</font></blockquote>
+
+<p><br>In addition, changes should be committed once a user clicks off
+the cell or hits ENTER.
+<p>The following are examples of good behaviour for a table cell Editor:
+<p>- when put in edit mode, drop-down appears with current selection active
+&amp; highlighted
+<br><img SRC="cell1.jpg" height=16 width=114>
+<p>- when cursoring through drop-down using arrow keys, it is possible
+to move up and down any number of choices and the drop-down stays visible
+until user makes an explicit selection
+<br><img SRC="cell2.jpg" height=97 width=56>
+<p>- first letter navigation is supported as a cursoring technique when
+the drop-down is visible
+<br>- supports the "Enter" key as a way of making an explicit selection
+via the keyboard when the drop-down is visible
+<br>- supports the "Esc" key as a way of canceling a selection via the
+keyboard when the drop-down is visible
+<br>- when put in edit mode, drop-down appears with current selection active
+&amp; highlighted
+<br><img SRC="cell3.jpg" height=15 width=142>
+<p>- when put in edit mode, it is possible to arrow key through the choices
+to make a selection without needing to invoke the drop-down
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.27</font></b>
+<blockquote><font color="#3333FF">Changes made in a table cell editor should
+be committed when a user clicks off the cell or hits the "Enter" key. Selection
+should be cancelled when user hits the "Esc" key.First letter navigation
+should be supported as a cursoring mechanism within a cell.</font></blockquote>
+
+<h4>
+Error Notification</h4>
+If you are doing keystroke by keystroke validation in an Editor, put error
+message in the workbench status area. Error text in the status area should
+be in red, while information text should be in black.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.28</font></b>
+<blockquote><font color="#3333FF">When performing fine-grain error validation
+in an Editor, use the workbench status area for message output.</font></blockquote>
+When the Save action is invoked in an editor, use the Task view for showing
+errors which are persisted.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.29</font></b>
+<blockquote><font color="#3333FF">Use the Task view to show errors found
+when the Save action is invoked.</font></blockquote>
+
+<h4>
+Interaction With External Editors</h4>
+While a resource is opened within the workbench, if modifications are made
+to it outside of the workbench, we recommend the following approach to
+handle this situation. When the Save action is invoked in the editor, users
+should be prompted to either override the changes made outside of the workbench,
+or back out of the Save operation.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+5.30</font></b>
+<blockquote><font color="#3333FF">If modifications to a resource are made
+outside of the workbench, users should be prompted to either override the
+changes made outside of the workbench, or back out of the Save operation
+when the Save action is invoked in the editor.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Views"></a>Views</h3>
+A view is a visual component within a workbench page.&nbsp; It is<font color="#000000">
+used in a support role for the primary task.&nbsp; You use them to navigate
+a hierarchy of information, open an editor, or view properties for the
+active editor.</font>
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.1</font></b>
+<blockquote><font color="#3333FF">Use a view to navigate a hierarchy of
+information, open an editor, or display the properties of an object.</font></blockquote>
+Modifications made in a view should be saved immediately.&nbsp; For instance,
+if a file is modified in the Navigator, the changes are committed to the
+workspace immediately.&nbsp; A change made in the Outline view is committed
+to the edit model of the active editor immediately.&nbsp; For changes made
+in the Properties view, if the property is a property of an open edit model,
+it should be persisted to the edit model. If it is a property of a file,
+persist to file.
+<p>In the past, some views have tried to implement an editor style lifecycle,
+with a Save action.&nbsp; This can cause confusion.&nbsp; The File menu
+within a workbench window contains a Save action, but it only applies to
+the active editor.&nbsp; It will not target the active view.&nbsp; This
+leads to a situation where the File > Save action is in contradiction to
+the Save action within the view.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.2</font></b>
+<blockquote><font color="#3333FF">Modifications made within a view must
+be saved immediately.</font></blockquote>
+Within a perspective, only one instance of a particular view can be opened.&nbsp;
+This policy is designed to simplify part management for a user.&nbsp; The
+user opens a view by invoking Perspective > Show View.&nbsp; If, for any
+reason, they lose a view, or forget about its existence, they can simply
+invoke Perspective > Show view again to make the view visible.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.3</font></b>
+<blockquote><font color="#3333FF">Only one instance of a view may exist
+in a perspective.</font></blockquote>
+In a multi-tasking world, humans often perform more than one task at a
+time.&nbsp; In Eclipse, task separation can be achieved by creating a separate
+perspective for each task.&nbsp; In reflection of this, it should be possible
+to open a particular view in more than one perspective.&nbsp; If only one
+instance of a view may exist, the ability to multi-task is taken away.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.4</font></b>
+<blockquote><font color="#3333FF">A view must be opened in one or more
+perspectives.</font></blockquote>
+A view can be opened in two ways: by invoking Perspective > Show View >
+X menu, where X is the name of the view, or by invoking another action
+within the workbench.&nbsp; For instance, if you select a class in the
+Packages view, and invoke Open Type Hierarchy, a Hierarchy view opens with
+the class hierarchy for the selection.
+<p>It should be possible to open any view from the Perspective > Show View
+menu, either as an explicit item within the menu, or as an item within
+the Perspective > Show View > Other dialog.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.5</font></b>
+<blockquote><font color="#3333FF">A view can be opened from the Perspective
+> Show View menu.</font></blockquote>
+
+<h4>
+Appearance</h4>
+A view consists of a title area, a toolbar, a pulldown menu, and an embedded
+control.
+<p>The view label in the title bar must be prefixed with label of the view
+in Perspective > Show View menu.&nbsp; Given that it is impossible to change
+the entry in the Show View menu, this means you cannot change the name
+of a view.&nbsp; However, you can add additional text to the view label,
+to clarify the state of the view.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.6</font></b>
+<blockquote><font color="#3333FF">The view label in the title bar must
+be prefixed with the label of the view in the Perspective > Show View menu.</font></blockquote>
+In most cases, a view will contain a single control or viewer.&nbsp; However,
+it is possible to embed more than one viewer or control in the view.&nbsp;
+If these controls are linked, such that selection in one control changes
+the input of another, it may be better to separate the view into two. Users
+will have greater freedom to open one of the results views, as their needs
+arise. Special relationships can alos be set up between these views to
+support the user task. In addition, this makes it easier for users to create
+a new perspective with a diverse set of views.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.7</font></b>
+<blockquote><font color="#3333FF">If a view contains more than one control,
+it may be advisable to split it up into two or more views.</font></blockquote>
+
+<h4>
+Initialization</h4>
+When a view is opened, the input of the view should be derived from the
+state of the perspective.&nbsp; The view may consult the perspective input
+or selection, or the state of another view.&nbsp; For instance, if the
+Outline view is opened, it will determine the active editor, query the
+editor for an outline model, and display the outline model.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.8</font></b>
+<blockquote><font color="#3333FF">When a view first opens, derive the view
+input from the state of the perspective.</font></blockquote>
+If the view is used to navigate a hierarchy of resources (i.e., the Navigator
+or Packages view), the input of the view may be derived from the perspective
+input.&nbsp; The perspective input defines the scope of visible resources
+within the perspective, and is defined by the user if they select a resource
+in the Navigator and invoke Open Perspective.&nbsp; For instance, if the
+Navigator view is opened, it will ask its perspective for the perspective
+input.&nbsp; The result is used as the initial input for the view.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.9</font></b>
+<blockquote><font color="#3333FF">If a view displays a resource tree, consider
+using the perspective input as the root of visible information in the view.</font></blockquote>
+
+<h4>
+Menus</h4>
+The pulldown menu for a view should be used for presentation actions.&nbsp;
+These are actions which affect the presentation of the view, but not the
+objects within the view.&nbsp; For instance, the Sort and Filter actions
+within the Navigator view affect the presentation of resources, but do
+not affect the resources themselves.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.10</font></b>
+<blockquote><font color="#3333FF">Fill the view pulldown menu with presentation
+actions, not selection oriented actions.</font></blockquote>
+For consistency with other views in Eclipse, each view should adopt a common
+order for actions within the pulldown menu.&nbsp; This format is shown
+in the following table.
+<br>&nbsp;
+<center><table BORDER COLS=1 WIDTH="200" >
+<tr>
+<td>Sorting</td>
+</tr>
+
+<tr>
+<td>Filtering</td>
+</tr>
+
+<tr>
+<td>Decorators</td>
+</tr>
+
+<tr>
+<td>Other Plugin Additions</td>
+</tr>
+</table></center>
+
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.11</font></b>
+<blockquote><font color="#3333FF">Use the standard format for view pulldown
+menus.</font></blockquote>
+
+<h4>
+Toolbars</h4>
+The toolbar is used to expose the most commonly used actions in a view.&nbsp;
+Any action which appears in the toolbar must also appear in the menu, but
+there is no need to duplicate every action in the menu within the toolbar.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.12</font></b>
+<blockquote><font color="#3333FF">Fill the view toolbar with the most commonly
+used items in the view menu.</font></blockquote>
+
+<h4>
+Context Menus</h4>
+A context menu should be used for context sensitive interaction with the
+objects in a view.&nbsp; If an object is selected in a view, and the context
+menu is opened, the context menu should only contain actions which are
+appropriate for the selection.&nbsp; Actions which affect the presentation
+of the view should not appear in the context menu.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.13</font></b>
+<blockquote><font color="#3333FF">Fill the context menu with selection
+oriented actions, not presentation actions.</font></blockquote>
+For consistency with other views in Eclipse, each view should adopt a common
+order for actions within the context menu.&nbsp; This format is shown in
+the following table.&nbsp; Within this table, each item represents a category
+of actions.&nbsp; The categories within the context menu should be kept
+distinct from one another through the use of separators.
+<br>&nbsp;
+<center><table BORDER COLS=1 WIDTH="200" >
+<tr>
+<td>New</td>
+</tr>
+
+<tr>
+<td>Open</td>
+</tr>
+
+<tr>
+<td>Navigate + Show In</td>
+</tr>
+
+<tr>
+<td>Cut Copy Paste</td>
+</tr>
+
+<tr>
+<td>Delete</td>
+</tr>
+
+<tr>
+<td>Other Plugin Additions</td>
+</tr>
+
+<tr>
+<td>Properties</td>
+</tr>
+</table></center>
+
+<p>The New category contains actions which create new objects.&nbsp; The
+Open category contains actions which open the selection in an editor.&nbsp;
+Navigate contains actions to refocus the view input, or reveal the view
+selection in another view.&nbsp; And the other categories are self explanatory.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.14</font></b>
+<blockquote><font color="#3333FF">Use the standard format for view context
+menus.</font></blockquote>
+For good spatial navigation, fill the context menu with a fixed set of
+actions for each selection type.&nbsp; Once the contents have been defined,
+the enablement state of each action should determined using the selected
+object state.&nbsp; In doing so, you establish a consistency which makes
+the menu more predictable, and easier to navigate.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.15</font></b>
+<blockquote><font color="#3333FF">Fill the context menu with a fixed set
+of actions for each selection type, and then enable or disable each to
+reflect the selection state.</font></blockquote>
+An object in one view may be visible in many other views or editors.&nbsp;
+For instance, a .java file is visible in the Navigator, the Hierarchy view,
+and the Packages view.&nbsp; To the user, these objects are all the same,
+regardless of location, so the context menu for the .java file should be
+the same in each.
+<p>To achieve a consistent context menu, plug-in developers which introduce
+a new object type should contribute actions to the context menu using an
+action factory, a Java class which populates the context menu.&nbsp; If
+this approach is used, the factory can be reused by other views where the
+same objects appear.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.16</font></b>
+<blockquote><font color="#3333FF">If an object appears in more than one
+view, it should have the same context menu in each.</font></blockquote>
+One of the primary goals for the platform UI is extensibility.&nbsp; In
+fact, it is this extensibility which gives you the freedom to add new views,
+editors, perspectives, and actions to the platform.&nbsp; Of course, extensibility
+is a two way street.&nbsp; While you may wish to extend the platform, others
+may wish to extend your view or editor.&nbsp; It is common for one plug-in
+to add actions to the menu, toolbar, or context menu of a view from another
+plugin.
+<p>In the platform, the menu and toolbar for a view are automatically extended
+ by the platform.&nbsp; In contrast, context menu extension is supported in collaboration
+ between the view and the platform.&nbsp; To achieve this collaboration, a view
+ must register each context menu it contains with the platform.&nbsp; It should
+ also define an action filter for each object type in the view.&nbsp; An action
+ filter makes it easier for one plug-in to add an action to objects in a view
+ defined by another plug-in.&nbsp; The action target is described using object
+ type and attributes.&nbsp;&nbsp; For more information on the implementation
+ of this concept, refer to <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+ an Eclipse View.</a>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.17</font></b>
+<blockquote><font color="#3333FF">Register all context menus in the view
+with the platform.</font></blockquote>
+<img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.18</font></b>
+<blockquote><font color="#3333FF">Implement an Action Filter for each object
+type in the view.</font></blockquote>
+
+<h4>
+Integration with the Window Menu Bar and Toolbar</h4>
+The window menu bar contains a number of global actions, such as Cut, Copy,
+and Paste within the Edit menu.&nbsp; These actions target the active part,
+as indicated by a shaded title area.&nbsp; If these actions are supported
+within a view, the view should hook these window actions, so that selection
+in the window menu bar or toolbar produces the same result as selection
+of the same action in the view.
+<p>A complete list of the global actions is declared in the IWorkbenchActionConstants.java
+(see below).
+<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * From IWorkbenchActionConstants.</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Standard global
+actions in a workbench window.</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final
+String [] GLOBAL_ACTIONS = {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+UNDO,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+REDO,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CUT,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+COPY,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+PASTE,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+PRINT,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+DELETE,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+FIND,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+SELECT_ALL,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+BOOKMARK</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</tt>
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.19</font></b>
+<blockquote><font color="#3333FF">If a view has support for Cut, Copy,
+Paste, or any of the global actions, these actions must be executable from
+the same actions in the window menu bar and toolbar.</font></blockquote>
+<font color="#000000">It is not possible to contribute view actions to
+the window menu bar or toolbar.&nbsp; A</font> view is typically used as
+an auxiliary view, to support the task of editing another object.&nbsp;
+In reflection of this, editor actions are given prominence in the window
+menu bar and toolbar, while view actions appear within the local menu and
+toolbar.
+<h4>
+Persistence</h4>
+One of the primary goals for the platform UI is to provide efficient interaction
+with the workspace.&nbsp; In the platform this is promoted by saving the
+state of the workbench when a session (the workbench is shut down) ends.&nbsp;
+When a new session (the workbench is opened) is started, this state is
+restored, reducing the time required for the user to get back to work.
+<p>If a view has a static input object, in the sense that its input is not derived
+ from selection in other parts, the state of the view should be persisted between
+ sessions. If a view has a dynamic or transient input object, there is no need
+ to persist its state between sessions. Within the workbench, the state of the
+ Navigator view, including the input and expansion state, is saved between sessions.
+ For more information on the implementation of persistence, see "<a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+ an Eclipse View</a>". <br>
+ &nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+6.20</font></b>
+<blockquote><font color="#3333FF">Persist the state of each view between
+sessions.</font></blockquote>
+
+<p><br>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Perspectives"></a>Perspectives</h3>
+A perspective is a visual container for a set of views and editors (parts).&nbsp;
+These parts exist wholly within the perspective and are not shared.&nbsp;
+A perspective is like
+a page within a book.&nbsp; It exists within a window along with any number
+of other perspectives and, like a page within a book, only one perspective
+is visible at any time.
+<p>A new perspective is opened by invoking Perspective > Open > X, where
+X identifies a particular perspective in Eclipse.&nbsp; The result is a
+new perspective in the workbench window with <i>type</i> X.&nbsp; For instance,
+if you invoke Perspective > Open > Resource, a new perspective is opened
+with type <i>Resource</i>.&nbsp; Eclipse comes with a pre-defined number
+of perspective types, including Resource, Java, and Team.&nbsp; The perspective
+type determines the initial layout of views, and visibility of action sets
+within the perspective.
+<p>As a plug-in developer, you may contribute new perspective types to Eclipse.&nbsp;
+ To do this, you must define a perspective extension.&nbsp; Each extension has
+ a <i>perspective factory</i>, a Java class which defines the initial layout
+ of views, and visibility of action sets within the perspective.&nbsp; You can
+ also add your own actions or views to an existing perspective type.&nbsp; For
+ more information on the implementation of these concepts, see <a href="http://www.eclipse.org/articles/using-perspectives/PerspectiveArticle.html" target="_top">Using
+ Perspectives in the Eclipse UI</a>.
+<p>A new perspective type should be created when there is a group of related
+tasks which would benefit from a predefined configuration of actions and
+views, and these tasks are long lived.&nbsp; A task oriented approach is
+imperative.&nbsp; As a development environment, Eclipse was designed to
+fulfill the needs of a large product development team, from product manager
+to content developer to product tester.&nbsp; It is fully extensible and
+may be configured with hundreds of action, wizard, view and editor extensions.&nbsp;
+In other words, it may contain a lot of junk you'll never use.&nbsp; To
+avoid the visual overload and confusion which would occur if everything
+was visible in the UI, a perspective can be used to define together a task
+oriented set of views and action sets.
+<p>For instance, the task of Java code creation is long lived and complex,
+so the creation of a Java perspective is warranted.&nbsp; In Eclipse, the
+Java perspective contains an editor area, Packages view, Hierarchy view,
+Tasks view, and Outline view.&nbsp; The Java and Debug action sets are
+also visible.&nbsp; Together, these components are useful for a variety
+of long lived, Java coding tasks.
+<p>It is not appropriate to create a new perspective type for short lived
+tasks.&nbsp; For instance, the task of resource check-in is short lived,
+so it may be better performed using a view in the current perspective.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.1</font></b>
+<blockquote><font color="#3333FF">Create a new perspective type for long
+lived tasks, which involve the performance of smaller, non modal tasks.</font></blockquote>
+If your plug-in contributes a small number of views, and these augment
+an existing task, it is better to add those views to an existing perspective.&nbsp;
+For instance, if you create a view which augments the task of Java code
+creation, don't create a new perspective.&nbsp; Instead, add it to the
+existing Java perspective.&nbsp; This strategy provides better integration
+with the existing platform.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.2</font></b>
+<blockquote><font color="#3333FF">If you just want to expose a single view,
+or two, extend an existing perspective type.</font></blockquote>
+
+<h4>
+View Layout</h4>
+If the user opens a new perspective, the initial layout of views will be
+defined by the perspective type (i.e., Resource, Java, Team).&nbsp; This
+layout is performed in the <i>perspective factory</i>, a Java class associated
+with the perspective type.&nbsp; When the perspective is initialized, it
+consists of an editor area with no additional views.&nbsp; The perspective
+factory may add new views, using the editor area as the initial point of
+reference.
+<p>The size and position of each view is controlled by the perspective
+factory.&nbsp;&nbsp; These attributes should be defined in a reasonable
+manner, such that the user can resize or move a view if they desire it.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.3</font></b>
+<blockquote><font color="#3333FF">The size and position of each view in
+a perspective should be defined in a reasonable manner, such that the user
+can resize or move a view if they desire it.</font></blockquote>
+A perspective should have at least two parts, including the visible views
+and the editor area.&nbsp; If this is not the case, then the perspective
+should be re-examined to determine if it is better suited as a view or
+editor.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.4&nbsp;</font></b>
+<blockquote><font color="#3333FF">If a perspective has just one part, it
+may be better suited as a view or editor.</font></blockquote>
+In some scenarios, it may be undesirable to have an editor area within
+a perspective.&nbsp; In this case, the perspective factory should hide
+the editor area, using the existing java methods.&nbsp; It is not acceptable
+to resize the editor area to a point where it is no longer visible.&nbsp;
+If the user does open an editor in the perspective, for whatever reason,
+they will be unable to see or resize it.
+<p>When the editor area is programmatically hidden, if the user opens an
+editor in the perspective, the editor area will become visible. The view
+that occupied the editor area before will be shrinked. Therefore, it is
+important to define a non-empty editor area even when the editor is programmatically
+hidden.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.5</font></b>
+<blockquote><font color="#3333FF">If it is undesirable to have an editor
+area in a perspective, hide it.&nbsp; Do not resize the editor area to
+the point where it is no longer visible.</font></blockquote>
+
+<h4>
+Action Contribution</h4>
+The perspective factory may add actions to the File > New, Perspective
+> Open, and&nbsp; Perspective > Show View menus.&nbsp; It is also possible
+to add one or more action sets to the window.&nbsp; In each case, you should
+choose actions which are relevant to the task orientation of the perspective.
+<p>The File > New menu should be populated with wizards for the creation
+of objects commonly used in the task.&nbsp; For instance, in the Java perspective
+the File > New menu contains menu items for the creation of packages, classes,
+and interfaces.
+<p>The Perspective > Show View menu should be populated with the initial
+views in the perspective, as well as any extra views that may be important
+for the task at hand.
+<p><img SRC="showViewMenu.jpg" height=493 width=421>
+<br>&nbsp;
+<p>The application development lifecycle should be considered when populating
+the the Perspective > Open menu.&nbsp; The development of most applications
+follow a well defined lifecycle, from designing / modeling, to editing
+/ creating, to debugging / testing, to assembling / deploying.&nbsp; Each
+perspective will fall into one of these steps.&nbsp; The Perspective Open
+menu should be used to linking the current perspective to perspectives
+that support tasks immediately downstream of the current one, as well as
+tasks further upstream, to allow for iterative development.
+<p>For instance, the Java perspective is used in a larger lifecycle, involving
+Java, Debug, and Team tasks.&nbsp; The Perspective > Open menu is populated
+with each of these perspectives.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.6</font></b>
+<blockquote><font color="#3333FF">Populate the window menu bar with actions
+and action sets which are appropriate to the task orientation of the perspective,
+and any larger workflow.</font></blockquote>
+
+<h4>
+Opening a Perspective in Code</h4>
+An action should only open a new perspective if the user explicitly states
+a desire to do so.&nbsp; If the user does not state a desire to do so,
+it may cause loss of context.
+<p>For instance, imagine a scenario where the user selects an object and
+invokes an action.&nbsp; In the perspective where the action is invoked,
+the user may have a set of views and editors open.&nbsp; These represent
+the working state, or context, of the user.&nbsp; If a new perspective
+is created, that context will be left behind, forcing the user to recreate
+the context.&nbsp; This is time wasted.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.7 </font></b>
+<blockquote><font color="#3333FF">A new perspective should be opened only
+if the user explicitly states a desire to do so.&nbsp; In making this statement,
+the user agrees to leave their old context, and create a new one.</font></blockquote>
+In some cases, a new perspective is opened as the side effect of another
+action.&nbsp; For instance, if Project > Open Type is invoked, the resulting
+editor may open in the current perspective, or a new one.&nbsp; If this
+behavior is implemented, the user should have the option to turn this behavior
+off.&nbsp; The option can be exposed in the action dialog, or within a
+Preference page.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.8</font></b>
+<blockquote><font color="#3333FF">If a new perspective is opened as a side
+effect of another action, the user should be able to turn this behavior
+off.</font></blockquote>
+If a new perspective is opened, it may be opened as a page within the current
+window, or in a new window.&nbsp; The user controls this option using the
+Workbench Preferences.&nbsp; If code within a plug-in opens a new perspective,
+the plug-in should honor the user preference.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.9</font></b>
+<blockquote><font color="#3333FF">If a new perspective is opened, it should
+be opened as a page within the current window, or in a new window, depending
+on the user preference.</font></blockquote>
+In many scenarios, it may be better to replace the current perspective
+<i>type</i>,
+rather than open a new perspective.&nbsp; For instance, if the Debug action
+is invoked in the Java perspective, the action may replace the perspective
+type to Debug.&nbsp; When this approach is taken, the open editors and
+views are carried forward to the new perspective, so no loss of context
+is occurs.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.10</font></b>
+<blockquote><font color="#3333FF">Consider replacing the perspective type
+before you open a new perspective.</font></blockquote>
+With regard to action contributions applied to the New, Open Perspective,
+and Show View menus, the list of wizards, perspectives, and views added
+as shortcuts to these menus should be at most 7 plus / minus 2 items.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+7.11</font></b>
+<blockquote><font color="#3333FF">The list of shortcuts added to the New,
+Open Perspective, and Show View menus should be at most 7 plus / minus
+2 items.</font></blockquote>
+
+<p><br>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Windows"></a>Windows</h3>
+In this section we look at the window menu bar, toolbar, and layout.&nbsp;
+As a plug-in developer, you can contribute actions to the menu bar and
+toolbar using an <i>action set</i>, a set of task oriented actions which
+the user can show or hide.&nbsp; You can control the layout of views within
+a window by defining a <i>perspective</i>.&nbsp; In this section we'll
+look at action extension.&nbsp; For more information on perspectives, see
+<a href="#Perspectives">Perspectives</a>.
+<h4>
+Actions</h4>
+Each workbench window contains a menu bar and toolbar.&nbsp; These are
+pre-populated by the platform, but a plug-in developer may add additional
+items to each.&nbsp; This is done by defining an <i>action set</i>, a set
+of task oriented actions which the user can show or hide.&nbsp; The actions
+within an action set may be distributed through-out the window menu bar
+and toolbar.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.1</font></b>
+<blockquote><font color="#3333FF">Use an Action Set to contribute actions
+to the window menu bar and toolbar.</font></blockquote>
+The window menu bar contains a number of pulldown menus: File, Edit, Perspective,
+Project, Window, and Help.&nbsp; Each of these has a different purpose,
+which will be explained in the following paragraphs.&nbsp; For consistency
+with the action sets contributed by other plug-ins, the actions within
+an action set should conform to the existing distribution of actions in
+the window.&nbsp; There is no need to group the actions in a separate pulldown
+menu of the menu bar.
+<p>The File menu contains file oriented actions, such as Save, Close, Print,
+Import, Export and Exit.&nbsp; The contents of the File > New menu are
+determined by the perspective type.&nbsp; However, the user may add or
+remove items using the Perspective > Customize menu item.&nbsp; The contents
+of the Import and Export dialogs are populated with every import and export
+wizard, respectively.
+<p>The Edit menu contains editor oriented actions, such as Undo, Redo,
+Cut, Copy, and Paste.&nbsp; These actions target the active part (as indicated
+by a shaded title bar) .&nbsp; It is very common for an editor to add items
+to this menu.&nbsp; However, it is uncommon for an action set to add actions
+to the Edit Menu; action sets tend to be global in nature, while the edit
+menu targets a specific part, and interaction with the data in that part.
+<p>The Perspective menu contains actions which affect the state of the
+window contents, such as Open Perspective, Show View and Close Perspective.
+<p>The Project menu contains actions which apply to the contents of the
+workspace, such as Rebuild All and Open Type.&nbsp; An action set may add
+actions which search the entire workspace, generate project info, open
+editors, etc.
+<p>The Window menu contains actions which apply to window management and
+system preferences.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.2</font></b>
+<blockquote><font color="#3333FF">Follow the platform lead when distributing
+actions within an Action Set.</font></blockquote>
+The toolbar contains the most commonly used actions of the menu bar.&nbsp;
+In reflection of this, you should contribute actions to the menu bar first,
+and then to the toolbar if they will be frequently used.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.3</font></b>
+<blockquote><font color="#3333FF">Contribute actions to the window menu
+bar first, and then to the window toolbar if they will be frequently used.</font></blockquote>
+The contents of each action set should be defined using a task oriented
+approach.&nbsp; For instance, the Java action set contains actions to create
+a new package, class and interfaces.&nbsp; It also contains an action to
+open an editor on a class, Goto Type. These form a cohesive set of related
+actions, which can be turned on and off by the user, depending on the active
+task.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.4</font></b>
+<blockquote><font color="#3333FF">Define each action set with a specific
+task in mind.</font></blockquote>
+The size of an action set is also important.&nbsp; If an action set is
+too large, it will flood the menu or toolbar, and reduce the users ability
+to customize the menu and toolbar.&nbsp; At the same time, if an action
+set is too small, the user may find customization of the menu and toolbar
+is too labor intensive.&nbsp; Break an action set up when it has more than
+about 7 items.
+<p>There is no magic number for the size of an action set, but it should
+be carefully designed to contain the smallest possible semantic chunking
+of actions. Avoid the temptation to provide only one action set for an
+entire plug-in.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.5</font></b>
+<blockquote><font color="#3333FF">An action set should contain the smallest
+possible semantic chunking of actions. Avoid the temptation to provide
+only one action set for an entire plug-in.</font></blockquote>
+An action set can be used to share a set of actions between two or more
+views and editors.&nbsp; For instance, a Java Refactor action set may be
+applicable to the selection within a Java Editor, an Outline view, and
+a Hierarchy View.&nbsp; In this situation the actions can be shared by
+defining an action set extension for the workbench.&nbsp; Once this action
+set has been defined, it can be automatically included in a perspective
+by the perspective developer, or added to a perspective by the user.
+<p>An action set should not be used to promote action from a single view
+to the window menu bar and toolbar.&nbsp; This simply clutters up the user
+interface.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.6</font></b>
+<blockquote><font color="#3333FF">Use an action set to share a set of actions
+which are useful in two or more views or editors.</font></blockquote>
+The set of visible action in a window may be changed by invoking Perspective
+> Customize.&nbsp; Within the resulting dialog, you can add or remove items
+from the File > New menu, Perspective > Open menu, or Perspective > Show
+View menu.&nbsp; It is also possible to add or remove action sets.&nbsp;
+In general, the visible action sets should be controlled by the user, and
+should never be changed programmatically.&nbsp; There are two reasons for
+this.&nbsp; First, users like to control the environment, not be controlled.&nbsp;
+And second, the user is in the best position to understand the active task,
+and the appropriate action sets for its completion.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.7</font></b>
+<blockquote><font color="#3333FF">Let the user control the visible action
+set.&nbsp; Don't try to control it for them.</font></blockquote>
+
+<h4>
+Common Window Actions</h4>
+A common example of an action which may be added to an action set is Project
+> Open Type.&nbsp; This action can be used to open an editor on a type
+which is not visible in the current window, and is a form of lateral navigation.&nbsp;
+In general, all Open actions which take the form should be added to the
+Project menu, for consistency.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.8</font></b>
+<blockquote><font color="#3333FF">"Open Object" actions must appear in
+the Project pulldown menu of the window.</font></blockquote>
+Any action within an action set, which opens another application, should
+be added to the Window pulldown menu.&nbsp; This approach is consistent
+with the existing functionality of the Window menu, where you can navigate
+from one window to another within the workbench.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.9</font></b>
+<blockquote><font color="#3333FF">"Open Application" actions must appear
+in the Window pulldown menu of the window.</font></blockquote>
+
+<h4>
+Status Bar</h4>
+If there is a need for a plug-in to show non-modal contextual information
+in the status bar area, always use the global status bar.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+8.10</font></b>
+<blockquote><font color="#3333FF">Always use the global status bar to display
+status related messages.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Properties"></a>Properties</h3>
+A Properties dialog or view is used to view / modify the properties of
+an object which are not visible in the normal presentation of that object.
+For instance, the Read Only attribute for a file is modified in the Properties
+Dialog.&nbsp; The build path for a Java Project is modified in the Properties
+Dialog.
+<p>Within Eclipse, there are two ways to edit the properties of an object:
+in the Properties dialog, and in the Properties view.&nbsp; Each of these
+is applicable in different situations.
+<p>The Properties view is commonly used to edit the properties for a set
+of objects in an editor, where quick access to the properties is important,
+and you switch from one object to another quickly.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+9.1</font></b>
+<blockquote><font color="#3333FF">Use the Properties view to edit the properties
+of an object when quick access is important, and you will switch quickly
+from object to object.</font></blockquote>
+The properties for an object should be quick to calculate.&nbsp; If it
+is too expensive to calculate the properties for an object, the quick access
+to properties offered by the Properties view becomes worthless.&nbsp; In
+this situation, where quick access is not possible, a Properties Dialog
+should be used.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+9.2</font></b>
+<blockquote><font color="#3333FF">Use a Properties Dialog to edit the properties
+of an object which are expensive to calculate.</font></blockquote>
+In some cases, the properties for an object are dependent upon one another,
+such that a change in one will affect another, or even enable / disable
+the option to change another.&nbsp; In this situation, a Properties Dialog
+may be a better way to represent the semantic link between these properties.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+9.3</font></b>
+<blockquote><font color="#3333FF">&nbsp;Use a Properties Dialog to edit
+the properties of an object which contain complex relationships to one
+another.</font></blockquote>
+When both the Properties view and the Properties Dialog are used to present
+and edit properties of an object, the Properties Dialog should contain
+the superset of items shown in the Properties view.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+9.4</font></b>
+<blockquote><font color="#3333FF">&nbsp;Properties Dialog should contain
+the superset of items shown in the Properties view.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h2>
+<a NAME="Standard Components"></a>Standard Components</h2>
+In this section we'll look at the standard components which ship with Eclipse.&nbsp;
+The Eclipse SDK contains a number of views, including the Navigator, Outline,
+Properties, Tasks, and Bookmarks view.&nbsp; Eclipse also contains a default
+text editor and a Resource perspective.
+<p>As a plug-in developer, you should try to add new actions to the existing
+parts.&nbsp; This leads to better integration with the platform, and the
+existing knowledge of the user.
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+10.1</font></b>
+<blockquote><font color="#3333FF">If appropriate, add actions to standard
+components of Eclipse using the plug-in registry.</font></blockquote>
+
+<p><br>When extending the standard components such as the Navigator, Outline,
+Properties, Tasks, and Bookmark views, make sure your specialized components
+carry over the base component's characteristics (drag and drop support,
+keyboard navigation, selection behaviour, etc.)
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+10.2</font></b>
+<blockquote><font color="#3333FF">If you subclass or copy any of the standard
+components, always carry over the standard components' characteristics.</font></blockquote>
+
+<p><br>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Navigator"></a>The Navigator View</h3>
+The Navigator is used to navigate the workspace, create new resources,
+modify resources, and open an editor on a resource.&nbsp; Plug-in developers
+may contribute new actions to the menu, toolbar, and context menu.
+<br>&nbsp;
+<h4>
+Adding Actions</h4>
+This is done by adding an extension to the plug-in registry.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+11.1</font></b>
+<blockquote><font color="#3333FF">Add actions to the Navigator View menu,
+toolbar, and context menu using the plug-in registry.</font></blockquote>
+If object contributions are made to the context menu, try to qualify the
+target object as much as possible, to avoid adding the action to the wrong
+objects in the Navigator.&nbsp; For instance, a Java action may target
+IFiles with a .java extension, or IProjects with a Java nature.&nbsp; It
+will cause confusion if Java actions appear on non-java objects.
+<p>Some actions are a reflection of tool use, rather than object type.&nbsp;
+For instance, a repository plug-in may provide actions for file check in,
+check out, etc.&nbsp; These actions should only appear on the resources
+in the Navigator if the user has actively chosen to use the repository
+tool.&nbsp; To control the visibility of these actions, the plug-in should
+apply a project nature to the managed resources, and use the project nature
+attribute in all context menu contributions.
+<p>For more information on action filtering,&nbsp; refer to <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+ an Eclipse View</a>.&nbsp; The standard attributes for resources are defined
+ in IResourceActionFilter.java (see below).
+<pre>public interface IResourceActionFilter extends IActionFilter {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String NAME = "name";&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String EXTENSION = "extension";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String PATH = "path";&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String READ_ONLY = "readOnly";&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String PROJECT_NATURE = "projectNature";&nbsp;&nbsp;
+}</pre>
+The standard attributes for project filtering are defined in IProjectActionFilter.java.
+<pre>public interface IProjectActionFilter extends IResourceActionFilter {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String NATURE = "nature";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String OPEN = "open";
+}</pre>
+<img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+11.2</font></b>
+<blockquote><font color="#3333FF">Use the attributes defined in IResourceActionFilter.java&nbsp;
+and IProjectActionFilter.java to control the visibility of context menu
+actions in the Navigator.</font></blockquote>
+
+<h4>
+Integration with Other Views and Editors</h4>
+In Eclipse, the use of a "Show In" action is a common way to link the selection
+in one view to the input of another.&nbsp; For instance, a "Show in Packages"
+action is visible in the context menu for a class in the Outline view.&nbsp;
+When invoked, the class in the Outline view is selected and revealed in
+the Packages view.&nbsp; This approach should be used as a general, non
+intrusive pattern for view or editor linking.&nbsp; It is context sensitive,
+and reflects the intentions of the user.
+<p>A "Show In Navigator" action should be included in any view where a
+resource may appear.&nbsp; If invoked, the action should select and reveal
+the resource in the navigator.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+11.3</font></b>
+<blockquote><font color="#3333FF">Use a "Show In Navigator" action in each
+view, to link resources back to the Navigator.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Tasks"></a>The Tasks View</h3>
+The Tasks view is used to display the current tasks, errors and warnings
+in the workspace.&nbsp; A plug-in developer may contribute new tasks, errors,
+and warnings to the workspace, and rely upon the Tasks view to display
+those objects.&nbsp; You can also contribute new actions to the menu, toolbar,
+and context menu.&nbsp; This is done by adding an extension to the plug-in
+registry.
+<h4>
+Adding Tasks</h4>
+A new task, error or warning can be created using the Marker Manager services
+from the Core Resources Management plugin.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+12.1</font></b>
+<blockquote><font color="#3333FF">Add markers (tasks, errors and warnings)
+to the Tasks view using the Marker Manager services from the Core Resources
+Management plugin.</font></blockquote>
+The Tasks view is a table, containing columns for the task image, completion
+status, priority, description, resource, and line number.&nbsp; The description
+text of each marker should be short and concise, so that it will fit in
+the status line of Eclipse.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+12.2</font></b>
+<blockquote><font color="#3333FF">The description text of each marker should
+be short and concise, so that it will fit in the status line of Eclipse.</font></blockquote>
+
+<h4>
+Adding Actions</h4>
+You can contribute new actions to the menu, toolbar, and context menu.&nbsp;
+This is done by adding an extension to the plug-in registry.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+12.3</font></b>
+<blockquote><font color="#3333FF">Add actions to the Tasks view menu, toolbar,
+and context menu using the plug-in registry.</font></blockquote>
+If object contributions are made to the context menu, try to qualify the target
+object as much as possible, to avoid adding the action to the wrong objects in
+the Tasks view.&nbsp; At an implementation level, each object in the Tasks view
+is a <i>marker</i>, a general mechanism for associate notes with a resource.&nbsp;
+Use the attributes within IMarkerActionFilter.java to control the visibility of
+Task object actions (see below).&nbsp; For more information on action filtering,&nbsp;
+refer to <a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_top">Creating
+an Eclipse View</a>.
+<pre>public interface IMarkerActionFilter extends IActionFilter {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String TYPE = "type";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String SUPER_TYPE = "superType";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String PRIORITY = "priority";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String SEVERITY = "severity";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String DONE = "done";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String MESSAGE = "message";
+}</pre>
+
+<p><br><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+12.4</font></b>
+<blockquote><font color="#3333FF">Use the attributes defined in IMarkerActionFilter.java
+to control the visibility of context menu actions in the Tasks view.</font></blockquote>
+
+<h4>
+Integration with Other Views and Editors</h4>
+In an editor, task objects are commonly used to mark a location within
+a document.&nbsp; Once a task has been created, it appears in the Task
+view.&nbsp; If this task is selected (via double clicking), you should
+reopen the editor at the location defined in the task. The focus should
+be changed from the Task view to the editor.
+<p>If appropriate, support for the creation of new task objects in an editor
+should be implemented by the editor.&nbsp; For more information on this,
+see <a href="#Editors">Editors</a>.
+<br>&nbsp;
+<h4>
+Adding F1 Help to Task View</h4>
+Plug-ins should support F1 keyboard action and link it to an infopop that
+gives a detailed description of the selected item in the Task view.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+12.5</font></b>
+<blockquote><font color="#3333FF">Support F1 keyboard action and link it
+to an infopop that gives a detailed description of the selected item in
+the Task view.</font></blockquote>
+
+<p><br>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="The Preference Dialog"></a>The Preference Dialog</h3>
+The Preference Dialog is used to edit the global preference for a feature
+in the workbench.
+<p>A new preference page should be created when you need to expose global
+options to the user.&nbsp; For instance, the global preferences for Java
+compilation are exposed as a group of preference pages in the Preference
+Dialog.&nbsp; If these preferences are changed, they affect the entire
+Java plug-in.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+13.1</font></b>
+<blockquote><font color="#3333FF">Global options should be exposed within
+the Preferences Dialog.</font></blockquote>
+A preference page should not be used to expose the local options for a
+particular instance of a view, editor, or window.&nbsp;&nbsp; In this situation,
+the user will look to the menu and toolbar of the control itself to customize
+it.&nbsp; If these options are exposed in the Preference Dialog, it will
+blur the location of customization, and confuse the user.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+13.2</font></b>
+<blockquote><font color="#3333FF">Expose the preferences for a particular
+view, editor or window in the view itself, via a menu or tool item.</font></blockquote>
+
+<h4>
+Preference Page Design</h4>
+In the simplest case, any plug-in which needs to expose an option to the
+user will define a single preference page.&nbsp; This preference page should
+contain all of the options for the plug-in, until the number of options
+starts to overload the page.&nbsp; At that point a nested design for preference
+pages should be adopted.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+13.3</font></b>
+<blockquote><font color="#3333FF">Start out with a single preference page.&nbsp;
+Then evolve to more if you need to.</font></blockquote>
+In a nested design, a root preference page is added to the preference dialog,
+and then sub pages are added to the root preference page.&nbsp; The root
+preference page should never be blank.&nbsp; Instead, it should contain
+the most commonly used preferences, or those preferences which have a wide
+spread effect upon the plug-in behavior.&nbsp; Beneath the root page, a
+sub page should be created for each major chunk of functionality within
+the plug-in.
+<p>There is no reason to set the focus in a preference page, because focus
+is always set to the tree, by the Eclipse platform, after the preference
+page is made visible.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+13.4</font></b>
+<blockquote><font color="#3333FF">If you create a preference group, use
+the root page for frequently used preferences, or those preferences which
+have wide spread effect.&nbsp; Specialize within the sub pages. The root
+preference page should not be blank.</font></blockquote>
+
+<p><br>Each new plug-in should integrate its plug-in preferences, wizards,
+and views into existing preference, wizard, and view categories where it
+makes sense, rather than the blind creation of new categories for itself.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+13.5</font></b>
+<blockquote><font color="#3333FF">Attempt to integrate plug-in preferences,
+wizards, and views into existing categories for a new plug-in first, before
+considering the creation of a new category.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Outline"></a>The Outline View</h3>
+In Eclipse, there is a special relationship between an editor and the Outline
+view.&nbsp; When an editor is opened, the Outline view will connect to
+the editor, and ask it for an outline model.&nbsp; If the editor answers
+an outline model, that model will be displayed in the Outline view whenever
+the editor is active.&nbsp; The outline is used to navigate through the
+edit data, or interact with the edit data at a higher level of abstraction.
+<p>If you are an editor developer, the relationship between an editor and
+the Outline view is important.&nbsp; For more information on the collaboration
+between these two, see <a href="#Editors">Editors</a>.
+<p>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="The Properties View"></a>The Properties View</h3>
+The Properties view shows the properties for the active part in the workbench,
+or the selection within that part. These properties are supplied by the
+active part itself.&nbsp; The Properties view is simply a container for
+their presentation.
+<p>Within Eclipse, the properties for an object can be exposed using a
+Properties dialog, or the Properties view.&nbsp; The Properties view is
+commonly used to edit the properties for a set of objects in an editor,
+where quick access to the properties is important, and you switch from
+one object to another quickly.
+<p>For more information on the use of the Properties view, or Properties
+dialog, refer to <a href="#Properties">Properties</a>.
+<p>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Bookmarks"></a>The Bookmarks View</h3>
+The Bookmarks view is used to bookmark files, and open them quickly.&nbsp;
+A plug-in developer may contribute new bookmarks to the workspace, and
+rely upon the Bookmarks view to display those bookmarks.&nbsp; You can
+also contribute new actions to the menu, toolbar, and context menu.&nbsp;
+This is done by adding an extension to the plug-in registry.
+<p>In an editor, bookmark objects are commonly used to mark a location
+within a document.&nbsp; Once a bookmark has been created, it appears in
+the Bookmarks view.&nbsp; If this bookmark is selected, you&nbsp; may reopen
+the editor at the location defined in the bookmark.
+<p>If appropriate, support for the creation of new bookmark objects should
+be implemented by the editor.&nbsp; For more information on this, see <a href="#Editors">Editors</a>.
+<p>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Text Editor"></a>The Text Editor</h3>
+The Text Editor is commonly used to edit text files.&nbsp; A plug-in developer
+can contribute new actions to the menu, toolbar, and context menu.&nbsp;
+This is done by adding an extension to the plug-in registry. For more information
+on this, see <a href="#Editors">Editors</a>.
+<p>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h3>
+<a NAME="Resource Perspective"></a>The Resource Perspective</h3>
+The Resource perspective contains a Navigator, Outline, Task view, and
+editor area.&nbsp; Plug-in developers may contribute a new action, action
+set, or view to the Resource perspective.&nbsp; For more information, refer
+to
+<a href="#Perspectives">Perspectives</a>..
+<p>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h2>
+<a NAME="The Tao of IResource"></a>The Tao of Resource</h2>
+In Eclipse, the notion of a tool disappears.&nbsp; In its place, is the
+idea of a universal tool platform - an open, extensible IDE - where tool
+plug-ins are added to extend the capabilities of the platform.&nbsp; These
+plug-ins "teach" Eclipse how to work with things - java files, web content,
+graphics, video - almost anything you can imagine.&nbsp; At an implementation
+level, these plug-ins communicate using resources (projects, folders, and
+files).&nbsp; The resource is the common medium for integration between
+plugins and external tools.
+<p>The resource concept was developed for a number of reasons:
+<br>&nbsp;
+<ol>
+<li>
+Integration between a plug-in from one vendor, and a plug-in from another,
+is only possible if there is a common, well known data abstraction.</li>
+
+<li>
+Integration with external tools is only possible if everything, at some
+level, is a file.</li>
+</ol>
+
+<p><br>Resources are also important at the UI level.&nbsp; If an object
+action, decorator, or property page contribution is made to an IResource,
+the platform will ensure that this contribution is visible in any view
+or editor where the resource appears.&nbsp; For instance, a .java file
+will be visible in the Navigator, the Hierarchy view, and the Packages
+view.&nbsp; To the user, the .java file is the same object, regardless
+of the view where it appears, so the object appearance, context menu, and
+properties should be consistent in each view.
+<p>In some cases, the implementation of a particular view or editor may
+wrap a resource within another object, for presentation purposes.&nbsp;
+If the wrapper is equivalent to a resource, it is important to expose this
+equivalence to the platform.&nbsp; If the resource is exposed, the platform
+may apply resource contributions to the resource equivalent object.&nbsp;
+This ensures presentation consistency for an object in the platform.
+<p>The underlying resource for an object is exposed by implementing IAdaptable
+on the model object, and answering an IContributorResourceAdapter.&nbsp;
+For more information on the implementation of an IContributorResourceAdapter,
+refer to Eclipse Corner.
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+14.1</font></b>
+<blockquote><font color="#3333FF">Expose the resource for resource equivalent
+model objects using an IContributorResourceAdapter.</font></blockquote>
+
+<hr ALIGN="LEFT" WIDTH="100%">
+<h2>
+<a NAME="Accessability"></a>Accessibility</h2>
+In a view, editor, or other control, every features should be accessible
+using a mouse or the keyboard.
+<p><font color="#000000">In a dialog or wizard, a shortcut key should be
+defined for each button or control.&nbsp; The shortcut key should be displayed
+with an underline beneath the appropriate shortcut character.</font>
+<br>&nbsp;
+<p><img SRC="guidelineIndicator.gif" height=16 width=16><b><font color="#3333FF">Guideline
+15.1</font></b>
+<blockquote><font color="#3333FF">All of the features provided by a tool
+should be accessible using a mouse or the keyboard.</font></blockquote>
+
+<h3>
+<a NAME="Standard Accelerators"></a>Standard Accelerators</h3>
+The Eclipse platform has defined a large number of shortcut keys.&nbsp;
+Plug-in developers should make sure that the existing shortcut keys do
+not conflict with the shortcut keys defined in the plug-in.
+<br>&nbsp;
+<br>&nbsp;
+<table BORDER >
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT><b>Key</b></td>
+
+<td ALIGN=LEFT><b>{Key} by itself</b></td>
+
+<td ALIGN=LEFT><b>SHIFT+{Key}</b></td>
+
+<td ALIGN=LEFT><b>CTRL+{Key}</b></td>
+
+<td ALIGN=LEFT><b>CTRL+SHIFT+{Key}</b></td>
+
+<td ALIGN=LEFT><b>ALT+{Key}</b></td>
+
+<td ALIGN=LEFT><b>CTRL+ALT+{Key}</b></td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>A</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Select All</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>B</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Project / Build</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Bookmarks</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>C</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Copy</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>D</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Display</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>E</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Next Problem</td>
+
+<td ALIGN=LEFT>(JDT editor) Previous Problem</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Find/Replace…</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>G</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>H</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Search…</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>I</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>J</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>K</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Tasks</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>L</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Go to Line…</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>M</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Add Import</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT) Refactor / Move…</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>N</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>File / New / Other…</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Navigator</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>O</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Organize Imports</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Outline</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>P</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>File / Print</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(View) Properties</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Q</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Inspect</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>R</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>S</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>File / Save</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>File / Save All</td>
+
+<td ALIGN=LEFT>Window / Switch to Editor…</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>T</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT) Open Type…</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>U</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>V</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Paste</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>W</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>X</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Cut</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT) Refactor / Extract method…</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Y</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Redo</td>
+
+<td ALIGN=LEFT>(JDT) Refactor / Redo</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Z</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>Edit / Undo</td>
+
+<td ALIGN=LEFT>(JDT) Refactor / Undo</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Space</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=RIGHT BGCOLOR="#C0C0C0">&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Content Assist</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Backspace</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Windows: Undo</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Tab</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(JDT editor) Shift Right</td>
+
+<td ALIGN=LEFT>(JDT editor) Shift Left</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Insert</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Windows: Paste</td>
+
+<td ALIGN=LEFT>Windows: Copy</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Delete</td>
+
+<td ALIGN=LEFT>Edit / Delete</td>
+
+<td ALIGN=LEFT>Windows: Cut</td>
+
+<td ALIGN=LEFT>Edit / Delete</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Home</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>End</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Page Up</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Page Down</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Insert</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Delete</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Hyphen (-)</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Show System Menu</td>
+
+<td ALIGN=LEFT>Show View Menu</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Left Arrow</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Right Arrow</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Up Arrow</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>Down Arrow</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F1</td>
+
+<td ALIGN=LEFT>Help</td>
+
+<td ALIGN=LEFT>Help</td>
+
+<td ALIGN=LEFT>Help</td>
+
+<td ALIGN=LEFT>Help</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F2</td>
+
+<td ALIGN=LEFT>(Navigator view) Rename, (JDT editor) Open JavaDoc</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F3</td>
+
+<td ALIGN=LEFT>(JDT editor) Open on Selection</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F4</td>
+
+<td ALIGN=LEFT>(JDT editor) Open Type Hierarchy</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>File / Close All</td>
+
+<td ALIGN=LEFT>File / Close</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F5</td>
+
+<td ALIGN=LEFT>(Navigator view) Refresh, (Properties view) Refresh, (Debug)
+Step Into</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F6</td>
+
+<td ALIGN=LEFT>(Debug) Step Over</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Next Editor</td>
+
+<td ALIGN=LEFT>Previous Editor</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F7</td>
+
+<td ALIGN=LEFT>(Debug) Run to Return</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Next View</td>
+
+<td ALIGN=LEFT>Previous View</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F8</td>
+
+<td ALIGN=LEFT>(Debug) Resume</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F9</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F10</td>
+
+<td ALIGN=LEFT>(Debug) Relaunch last</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F11</td>
+
+<td ALIGN=LEFT>(Debug) Debug</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>(Debug) Run</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+
+<tr VALIGN=BOTTOM>
+<td ALIGN=LEFT>F12</td>
+
+<td ALIGN=LEFT>Activate Editor</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=LEFT>Activate Editor</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+
+<td ALIGN=RIGHT>&nbsp;</td>
+</tr>
+</table>
+
+<p>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h2>
+<a NAME="Checklist For Developers"></a>Checklist For Developers</h2>
+Here is a checklist for developers who are developing UI plugins.&nbsp;
+This <i>could</i> be used for certification purposes.
+<br>&nbsp;
+<h3>
+General</h3>
+
+<p><br><img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">
+Guideline 1.1</font></b>
+<blockquote><font color="#3333FF">Follow and apply good user interface
+design principles: user in control, directness, consistency, forgiveness,
+feedback, aesthetics, and simplicity.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">
+Guideline 1.2</font></b>
+<blockquote><font color="#3333FF">Follow the platform lead for user interface
+conventions.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">
+Guideline 1.3</font></b>
+<blockquote><font color="#3333FF">Be careful not to mix UI metaphors.&nbsp;
+It may blur the original concept, and your own application.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">
+Guideline 1.4</font></b>
+<blockquote><font color="#3333FF">If you have an interesting idea, work
+with the Eclipse community to make Eclipse a better platform for all.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b> <font color="#3333FF">Guideline
+1.5</font></b>
+<blockquote><font color="#3333FF">Use Headline style capitalization for
+all titles, including those used for windows, dialogs, tabs, column headings
+and push buttons. Capitalize the first and last words, and all nouns, pronouns,
+adjectives, verbs and adverbs.&nbsp; Do not include ending punctuation.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">
+Guideline 1.6</font></b>
+<blockquote><font color="#3333FF">Use Sentence style capitalization for
+all control labels in a dialog or window, including those for check boxes,
+radio buttons, group labels, and simple text fields.&nbsp; Capitalize the
+first letter of the first word, and any proper names.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">
+Guideline 1.7</font></b>
+<blockquote><font color="#3333FF">Localize the resources within your plug-in.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+1.8</font></b>
+<blockquote><font color="#3333FF">When an error occurs which requires either
+an explicit user input or immediate attention from users, communicate the
+occurrence with a modal dialog.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+1.9</font></b>
+<blockquote><font color="#3333FF">If a programming error occurs in the
+product, communicate the occurrence with a dialog, and log it.</font></blockquote>
+
+<h3>
+Actions</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+2.1</font></b>
+<blockquote><font color="#3333FF">Each action must have a label, tool tip,
+and full color image.&nbsp; The label and tool tip must use Headline style
+capitalization.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+2.2</font></b>
+<blockquote><font color="#3333FF">The action tooltip should describe the
+result of the action, not the current state of the action.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+2.3</font></b>
+<blockquote><font color="#3333FF">Adopt the labeling terminology of the
+workbench for New, Delete, Add, and Remove actions.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+2.4</font></b>
+<blockquote><font color="#3333FF">An action should only be enabled if it
+can be completed successfully.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+2.5</font></b>
+<blockquote><font color="#3333FF">Action enablement should be quick.&nbsp;
+If action enablement cannot be quick, enable the action optimistically
+and display an appropriate message if the action is invoked, but cannot
+be completed.</font></blockquote>
+
+<h3>
+Dialogs</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+3.1</font></b>
+<blockquote><font color="#3333FF">When a dialog opens, set the initial
+focus to one of the controls in the container.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+3.2</font></b>
+<blockquote><font color="#3333FF">Slush Bucket widget (or Twin Box) should
+flow from left to right with the source objects on the left hand side.
+It should have the >, &lt;, >>, &lt;&lt; control buttons in this order.</font></blockquote>
+
+<h3>
+Wizards</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.1</font></b>
+<blockquote><font color="#3333FF">Use a wizard for any task consisting
+of many steps, which must be completed in a specific order.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.2</font></b>
+<blockquote><font color="#3333FF">Each wizard must contain a header with
+a banner graphic and a text area for user feedback.&nbsp; It must also
+contain Back, Next, Finish, and Cancel buttons in the footer.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.3</font></b>
+<blockquote><font color="#3333FF">Start the wizard with a prompt, not an
+error message.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.4</font></b>
+<blockquote><font color="#3333FF">Seed the fields within the wizard using
+the current workbench state.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.5</font></b>
+<blockquote><font color="#3333FF">Validate the wizard data in tab order.&nbsp;
+Display a prompt when information is absent, and an error when information
+is invalid.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.6</font></b>
+<blockquote><font color="#3333FF">Only enable the Next / Finish buttons
+if all required information in the dialog is present and valid.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.7</font></b>
+<blockquote><font color="#3333FF">Remove all programming message ID's from
+wizard text.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.8</font></b>
+<blockquote><font color="#3333FF">Use a Browse Button whenever an existing
+object is referenced in a wizard.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.9</font></b>
+<blockquote><font color="#3333FF">If a new file is created, open the file
+in an editor.&nbsp; If a group of files are created, open the most important,
+or central file in an editor. Open the readme.html file upon creation of
+an example project.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.10</font></b>
+<blockquote><font color="#3333FF">If a new project is created, change the
+active perspective to suit the project type.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.11</font></b>
+<blockquote><font color="#3333FF">If a new object is created, select and
+reveal the new object in the appropriate view.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.12</font></b>
+<blockquote><font color="#3333FF">Create container objects in a wizard
+if reasonable defaults can be defined.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+4.13</font></b>
+<blockquote><font color="#3333FF">Use the label "Project Name" when the
+item must be a Project; otherwise, use the label "Folder". Do not qualify
+the term.</font></blockquote>
+
+<h3>
+Editors</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.1</font></b>
+<blockquote><font color="#3333FF">Use a editor to edit or browse a file,
+document, or other input object.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.2</font></b>
+<blockquote><font color="#3333FF">Modifications made in an editor must
+follow an open-save-close lifecycle model.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.3</font></b>
+<blockquote><font color="#3333FF">Only one instance of an editor may exist,
+for each editor input, within a page.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.4</font></b>
+<blockquote><font color="#3333FF">It must be possible to open a separate
+instance of an editor for each input.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.5</font></b>
+<blockquote><font color="#3333FF">The editor should be labeled with the
+name of the file, document, or input being edited.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.6</font></b>
+<blockquote><font color="#3333FF">In multipage editors, use a tab control
+for page activation.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.7</font></b>
+<blockquote><font color="#3333FF">All of the actions available in the editor
+should be added to the window menu bar.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.8</font></b>
+<blockquote><font color="#3333FF">Use the standard format for editor contributions
+in the window menu bar.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.9</font></b>
+<blockquote><font color="#3333FF">If an editor has support for Cut, Copy,
+Paste, or any of the global actions, these actions must be executable from
+the same actions in the window menu bar and toolbar.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.10</font></b>
+<blockquote><font color="#3333FF">Fill the editor toolbar with the most
+commonly used items in the view menu.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.11</font></b>
+<blockquote><font color="#3333FF">Fill the context menu with selection
+oriented actions, do not presentation or global actions.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.12</font></b>
+<blockquote><font color="#3333FF">Use the standard format for editor context
+menus.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.13</font></b>
+<blockquote><font color="#3333FF">Fill the context menu with a fixed set
+of actions for each selection type, and then enable or disable each to
+reflect the selection state.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.14</font></b>
+<blockquote><font color="#3333FF">Register all context menus in the editor
+with the platform.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.15</font></b>
+<blockquote><font color="#3333FF">Implement an Action Filter for each object
+type in the editor.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.16</font></b>
+<blockquote><font color="#3333FF">If the input to an editor is deleted,
+and the editor contains no changes, the editor should be closed.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.17</font></b>
+<blockquote><font color="#3333FF">If the input to an editor is deleted,
+and the editor contains changes, the editor should give the user a chance
+to save their changes to another location, and then close.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.18</font></b>
+<blockquote><font color="#3333FF">If the resource is dirty, prefix the resource
+name presented in the editor tab with an asterisk.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.19</font></b>
+<blockquote><font color="#3333FF">Treat read-only editor input as you would
+any other input.&nbsp; Enable the Save As if possible.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.20</font></b>
+<blockquote><font color="#3333FF">If the data within an editor is too extensive
+to see on a single screen, and will yield a structured outline, the editor
+should provide an outline model to the Outline view.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.21</font></b>
+<blockquote><font color="#3333FF">Notification about location between an
+Editor and the Outline view should be two-way. Context menu should be available
+in the Outline view as appropriate.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.22</font></b>
+<blockquote><font color="#3333FF">An error or warning image should be added
+to items with the error or warning respectively. If the item is part of
+a tree, the error or warning image should also be propagated to each ancestor
+of the item. If the ancestor of the item doesn't contain errors or warnings,
+a different error or warning image should be used for the ancestor..</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.23</font></b>
+<blockquote><font color="#3333FF">If appropriate, implement the "Add Task"
+feature in your editor.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.24</font></b>
+<blockquote><font color="#3333FF">If appropriate, implement the "Add Bookmark"
+feature in your editor.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.25</font></b>
+<blockquote><font color="#3333FF">Editors with source lines of text should
+have line numbers, and optionally column numbers..</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.26</font></b>
+<blockquote><font color="#3333FF">Table cell editors should support the
+single-click activation model, and in edit mode, they should render complex
+controls upon single-click.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.27</font></b>
+<blockquote><font color="#3333FF">Changes made in a table cell editor should
+be committed when a user clicks off the cell or hits the "Enter" key. Selection
+should be cancelled when user hits the "Esc" key.First letter navigation
+should be supported as a cursoring mechanism within a cell.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.28</font></b>
+<blockquote><font color="#3333FF">When performing fine-grain error validation
+in an Editor, use the workbench status area for message output.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.29</font></b>
+<blockquote><font color="#3333FF">Use the Task view to show errors found
+when the Save action is invoked.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+5.30</font></b>
+<blockquote><font color="#3333FF">If modifications to a resource are made
+outside of the workbench, users should be prompted to either override the
+changes made outside of the workbench, or back out of the Save operation
+when the Save action is invoked in the editor.</font></blockquote>
+
+<h3>
+Views</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.1</font></b>
+<blockquote><font color="#3333FF">Use a view to navigate a hierarchy of
+information, open an editor, or display the properties of an object.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.2</font></b>
+<blockquote><font color="#3333FF">Modifications made within a view must
+be saved immediately.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.3</font></b>
+<blockquote><font color="#3333FF">Only one instance of a view may exist
+in a perspective.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.4</font></b>
+<blockquote><font color="#3333FF">A view can be opened in one or more perspectives.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.5</font></b>
+<blockquote><font color="#3333FF">A view can be opened from the Perspective
+> Show View menu.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.6</font></b>
+<blockquote><font color="#3333FF">The view label in the title bar must
+be prefixed with the label of the view in the Perspective > Show View menu.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.7</font></b>
+<blockquote><font color="#3333FF">If a view contains more than one control,
+it may be advisable to split it up into two or more views.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.8</font></b>
+<blockquote><font color="#3333FF">When a view first opens, derive the view
+input from the state of the perspective.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.9</font></b>
+<blockquote><font color="#3333FF">If a view displays a resource tree, consider
+using the perspective input as the root of visible information in the view.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.10</font></b>
+<blockquote><font color="#3333FF">Fill the view pulldown menu with presentation
+actions, not selection oriented actions.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.11</font></b>
+<blockquote><font color="#3333FF">Use the standard format for view pulldown
+menus.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.12</font></b>
+<blockquote><font color="#3333FF">Fill the view toolbar with the most commonly
+used items in the view menu.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.13</font></b>
+<blockquote><font color="#3333FF">Fill the context menu with selection
+oriented actions, not presentation actions.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.14</font></b>
+<blockquote><font color="#3333FF">Use the standard format for view context
+menus.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.15</font></b>
+<blockquote><font color="#3333FF">Fill the context menu with a fixed set
+of actions for each selection type, and then enable or disable each to
+reflect the selection state.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.16</font></b>
+<blockquote><font color="#3333FF">If an object appears in more than one
+view, it should have the same context menu in each.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.17</font></b>
+<blockquote><font color="#3333FF">Register all context menus in the view
+with the platform.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.18</font></b>
+<blockquote><font color="#3333FF">Implement an Action Filter for each object
+type in the view.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.19</font></b>
+<blockquote><font color="#3333FF">If a view has support for Cut, Copy,
+Paste, or any of the global actions, these actions must be executable from
+the same actions in the window menu bar and toolbar.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+6.20</font></b>
+<blockquote><font color="#3333FF">Persist the state of each view between
+sessions.</font></blockquote>
+
+<h3>
+Perspectives</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.1</font></b>
+<blockquote><font color="#3333FF">Create a new perspective type for long
+lived tasks, which involve the performance of smaller, non modal tasks.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.2</font></b>
+<blockquote><font color="#3333FF">If you just want to expose a single view,
+or two, extend an existing perspective type.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.3</font></b>
+<blockquote><font color="#3333FF">The size and position of each view in
+a perspective should be defined in a reasonable manner, such that the user
+can resize or move a view if they desire it.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.4&nbsp;</font></b>
+<blockquote><font color="#3333FF">If a perspective has just one part, it
+may be better suited as a view or editor.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.5</font></b>
+<blockquote><font color="#3333FF">If it is undesirable to have an editor
+area in a perspective, hide it.&nbsp; Do not resize the editor area to
+the point where it is no longer visible.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.6</font></b>
+<blockquote><font color="#3333FF">Populate the window menu bar with actions
+and action sets which are appropriate to the task orientation of the perspective,
+and any larger workflow.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.7 </font></b>
+<blockquote><font color="#3333FF">A new perspective should be opened only
+if the user explicitly states a desire to do so.&nbsp; In making this statement,
+the user agrees to leave their old context, and create a new one.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.8</font></b>
+<blockquote><font color="#3333FF">If a new perspective is opened as a side
+effect of another action, the user should be able to turn this behavior
+off.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.9</font></b>
+<blockquote><font color="#3333FF">If a new perspective is opened, it should
+be opened as a page within the current window, or in a new window, depending
+on the user preference.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.10</font></b>
+<blockquote><font color="#3333FF">Consider changing the perspective type
+before you open a new perspective.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+7.11</font></b>
+<blockquote><font color="#3333FF">The list of shortcuts added to the New,
+Open Perspective, and Show View menus should be at most 7 plus / minus
+2 items.</font></blockquote>
+
+<h3>
+Windows</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.1</font></b>
+<blockquote><font color="#3333FF">Use an Action Set to contribute actions
+to the window menu bar and toolbar.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.2</font></b>
+<blockquote><font color="#3333FF">Follow the platform lead when distributing
+actions within an Action Set.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.3</font></b>
+<blockquote><font color="#3333FF">Contribute actions to the window menu
+bar first, and then to the window toolbar if they will be frequently used.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.4</font></b>
+<blockquote><font color="#3333FF">Define each action set with a specific
+task in mind.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.5</font></b>
+<blockquote><font color="#3333FF">An action set should contain the smallest
+possible semantic chunking of actions. Avoid the temptation to provide
+only one action set for an entire plug-in.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.6</font></b>
+<blockquote><font color="#3333FF">Use an action set to share a set of actions
+which are useful in two or more views or editors.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.7</font></b>
+<blockquote><font color="#3333FF">Let the user control the visible action
+set.&nbsp; Don't try to control it for them.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.8</font></b>
+<blockquote><font color="#3333FF">"Open Object" actions must appear in
+the Project pulldown menu of the window.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.9</font></b>
+<blockquote><font color="#3333FF">"Open Application" actions must appear
+in the Window pulldown menu of the window.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+8.10</font></b>
+<blockquote><font color="#3333FF">Always use the global status bar to display
+status related messages.</font></blockquote>
+
+<h3>
+Properties</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+9.1</font></b>
+<blockquote><font color="#3333FF">Use the Properties view to edit the properties
+of an object when quick access is important, and you will switch quickly
+from object to object.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+9.2</font></b>
+<blockquote><font color="#3333FF">Use a Properties Dialog to edit the properties
+of an object which are expensive to calculate.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+9.3</font></b>
+<blockquote><font color="#3333FF">&nbsp;Use a Properties Dialog to edit
+the properties of an object which contain complex relationships to one
+another.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+9.4</font></b>
+<blockquote><font color="#3333FF">&nbsp;Properties Dialog should cotain
+the superset of items shown in the Properties view.</font></blockquote>
+
+<h3>
+Standard Components</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+10.1</font></b>
+<blockquote><font color="#3333FF">If appropriate, add actions to standard
+components of Eclipse using the plug-in registry.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+10.2</font></b>
+<blockquote><font color="#3333FF">If you subclass or copy any of the standard
+components, always carry over the standard components' characteristics.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+11.1</font></b>
+<blockquote><font color="#3333FF">Add actions to the Navigator View menu,
+toolbar, and context menu using the plug-in registry.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+11.2</font></b>
+<blockquote><font color="#3333FF">Use the attributes defined in IResourceActionFilter.java&nbsp;
+and IProjectActionFilter.java to control the visibility of context menu
+actions in the Navigator.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+11.3</font></b>
+<blockquote><font color="#3333FF">Use a "Show In Navigator" action in each
+view, to link resources back to the Navigator.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+12.1</font></b>
+<blockquote><font color="#3333FF">Add markers (tasks, errors and warnings)
+to the Tasks view using the Marker Manager services from the Core Resources
+Management plugin.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+12.2</font></b>
+<blockquote><font color="#3333FF">The description text of each marker should
+be short and concise, so that it will fit in the status line of Eclipse.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+12.3</font></b>
+<blockquote><font color="#3333FF">Add actions to the Tasks view menu, toolbar,
+and context menu using the plug-in registry.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+12.4</font></b>
+<blockquote><font color="#3333FF">Use the attributes defined in IMarkerActionFilter.java
+to control the visibility of context menu actions in the Tasks view.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+12.5</font></b>
+<blockquote><font color="#3333FF">Support F1 keyboard action and link it
+to an infopop that gives a detailed description of the selected item in
+the Task view.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+13.1</font></b>
+<blockquote><font color="#3333FF">Global options should be exposed within
+the Preferences Dialog.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+13.2</font></b>
+<blockquote><font color="#3333FF">Expose the preferences for a particular
+view, editor or window in the view itself, via a menu or tool item.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+13.3</font></b>
+<blockquote><font color="#3333FF">Start out with a single preference page.
+Then evolve to more if you need to.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+13.4</font></b>
+<blockquote><font color="#3333FF">If you create a preference group, use
+the root page for frequently used preferences, or those preferences which
+have wide spread effect.&nbsp; Specialize within the sub pages.</font></blockquote>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+13.5</font></b>
+<blockquote><font color="#3333FF">Attempt to integrate plug-in preferences,
+wizards, and views into existing categories for a new plug-in first, before
+considering the creation of a new category.</font></blockquote>
+
+<h3>
+Resource</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+14.1</font></b>
+<blockquote><font color="#3333FF">Expose the resource for resource equivalent
+model objects using an IContributorResourceAdapter.</font></blockquote>
+
+<h3>
+Accessibility</h3>
+<img SRC="guidelineCheckbox.jpg" height=16 width=16><b><font color="#3333FF">Guideline
+15.1</font></b>
+<blockquote><font color="#3333FF">All of the features provided by a tool
+should be accessible using a mouse or the keyboard.</font></blockquote>
+
+<p><br>
+<hr ALIGN="LEFT" WIDTH="100%">
+<h2>
+<a NAME="Glossary"></a>Glossary</h2>
+
+<dl>
+<dt>
+<b>Action</b></dt>
+
+<dd>
+An <i>action</i> represents a command which can be triggered by the user
+from a menu or toolbar.&nbsp; It has a run method, plus other methods which
+return the menu or tool item presentation (text, image, etc.).&nbsp; In
+Eclipse, you can add actions to a menu or toolbar in a view, editor, or
+window.&nbsp; In a view or editor, actions are added individually, one
+by one.&nbsp; In the window, actions are added using an <i>action set</i>,
+a set of actions which can be turned on or off by the user.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Bookmarks View</b></dt>
+
+<dd>
+A view used to browse the bookmarks in the workbench.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Editor</b></dt>
+
+<dd>
+An editor is a visual component within a workbench page. It is typically
+used to edit or browse a document or input object. The input is identified
+using an &lt;code>IEditorInput&lt;/code>.&nbsp; Modifications made in an
+editor part follow an open-save-close lifecycle model (in contrast to a
+view part, where modifications are saved to the workbench immediately).</dd>
+
+<br>&nbsp;
+<dt>
+<b>File</b></dt>
+
+<dd>
+An object in the workspace, analogous to files in the file system.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Folder</b></dt>
+
+<dd>
+A container for files in the workspace.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Navigator View</b></dt>
+
+<dd>
+A view used to browse the files in the workspace</dd>
+
+<br>&nbsp;
+<dt>
+<b>Outline View</b></dt>
+
+<dd>
+A view, commonly used to view the outline of the active editor.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Perspective</b></dt>
+
+<dd>
+A perspective is a visual container for a set of views and editors (parts).&nbsp;
+These parts exist wholly within the perspective and are not shared.&nbsp;
+A perspective is also like a page within a book.&nbsp; It exists within
+a window along with any number of other perspectives and, like a page within
+a book, only one perspective is visible at any time.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Platform</b></dt>
+
+<dd>
+A generic framework for the integration of tools.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Preferences</b></dt>
+
+<dd>
+A Preference Page is used to edit the preferences for a feature in the
+platform.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Project</b></dt>
+
+<dd>
+A group of files and folders within the workspace.&nbsp; Each project maps
+to a corresponding user specified directory in the file system.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Properties View</b></dt>
+
+<dd>
+A view, typically used to browse the properties for an object in the active
+editor or view.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Properties Dialog</b></dt>
+
+<dd>
+A dialog for editing the properties of an object.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Property Page</b></dt>
+
+<dd>
+A page within a Properties Dialog.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Resource</b></dt>
+
+<dd>
+The generic name for projects, folders and files.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Tasks View</b></dt>
+
+<dd>
+A view used to browse the tasks, errors, and warnings within the workspace.</dd>
+
+<br>&nbsp;
+<dt>
+<b>View</b></dt>
+
+<dd>
+A view is a visual component within a workbench page.&nbsp; It is typically
+used to navigate a hierarchy of information (like the workspace), open
+an editor, or display properties for the active editor.&nbsp; Modifications
+made in a view are saved immediately (in contrast to an editor part, which
+conforms to a more elaborate open-save-close lifecycle).</dd>
+
+<br>&nbsp;
+<dt>
+<b>Wizard</b></dt>
+
+<dd>
+A Wizard is typically used to create new resources, import resources, or
+export resources.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Workbench</b></dt>
+
+<dd>
+The Workbench provides the user interface structure for Eclipse. The purpose
+of the Workbench is to facilitate the seamless integration of tools. These
+tools contribute to extension points defined by the Workbench.&nbsp; The
+Workbench is responsible for the presentation and coordination of the user
+interface.</dd>
+
+<br>&nbsp;
+<dt>
+<b>Workspace</b></dt>
+
+<dd>
+The various tools plugged in to the Eclipse Platform operate on regular
+files in the user's workspace.&nbsp; The workspace consists of one or more
+top level projects, where each project maps to a corresponding user specified
+directory in the file system.&nbsp; Each project contains a collection
+of folders and files.</dd>
+</dl>
+
+<h2>
+
+<hr ALIGN="LEFT" WIDTH="100%"><a NAME="Acknowledgement"></a>Acknowledgement</h2>
+Screenshots contributed to Eclipse.org and used in this document,
+originate from plugins released or under development by the following teams:
+<p>
+<ul>
+<li>
+Java Development Tooling, Eclipse Subproject</li>
+<li>
+WebSphere&reg; Studio Application Developer, IBM Corporation</li>
+<li>
+Rational XDE Professional, Rational Corporation.</li>
+</ul>
+<p>By agreeing to share selected elements of their user interface designs
+(both positive and negative), we feel that these teams have helped make
+the UI guidelines stronger.
+<br>&nbsp;
+<h2>
+
+<hr ALIGN="LEFT" WIDTH="100%"><a NAME="Revision History"></a>Revision History</h2>
+
+<table BORDER WIDTH="100%" >
+<tr>
+<td WIDTH="20%"><b>Date</b></td>
+
+<td><b>Comment</b></td>
+</tr>
+
+<tr>
+<td>Nov. 21, 2001</td>
+
+<td>Created.&nbsp; Dave Springgay, OTI</td>
+</tr>
+
+<tr>
+<td>Dec. 7, 2001&nbsp;</td>
+
+<td>Second Draft.&nbsp; D. Springgay, OTI</td>
+</tr>
+
+<tr>
+<td>Dec. 13, 2001</td>
+
+<td>Third Draft. Jin Li, IBM</td>
+</tr>
+
+<tr>
+<td>Jan. 3, 2002</td>
+
+<td>Fourth Draft. J. Li, IBM</td>
+</tr>
+
+<tr>
+<td>Feb. 27, 2002</td>
+
+<td>Fifth Draft. A. Cho, OTI</td>
+</tr>
+
+</table>
+
+<p>
+<hr WIDTH="100%">
+<br><font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2001 - 2002 Object Technology International, Inc. and others</font></font>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+
+</body>
+</html>
diff --git a/Article-UI-Guidelines/v200202/Idea.jpg b/Article-UI-Guidelines/v200202/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/Idea.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/Index.html b/Article-UI-Guidelines/v200202/Index.html
new file mode 100644
index 0000000..7ce4830
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/Index.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD><TITLE>Eclipse User Interface Guidelines</TITLE>
+</HEAD>
+<FRAMESET border=0 cols=190,50% frameBorder=0 frameSpacing=0>
+<FRAME frameBorder=0 marginHeight=0 marginWidth=2 name=_left noResize
+ src="Toc.html">
+<FRAME frameBorder=0 marginHeight=2 marginWidth=2 name=_right
+ src="Contents.html">
+</FRAMESET>
+</HTML>
diff --git a/Article-UI-Guidelines/v200202/Toc.html b/Article-UI-Guidelines/v200202/Toc.html
new file mode 100644
index 0000000..500f6e1
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/Toc.html
@@ -0,0 +1,162 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Build">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
+ <title>Eclipse UI Guidelines</title>
+<link rel="stylesheet" href="default_style.css">
+</head>
+<body>
+<p align="center"><b><font face="Arial,Helvetica">Eclipse UI Guidelines<br>
+ </font></b><a href="Contents.html" target="_top">View without table of contents</a></p>
+<table CELLSPACING=0 CELLPADDING=0 WIDTH="250" >
+ <tr>
+ <td COLSPAN="2" WIDTH="50">
+ <p><nobr><a href="Contents.html#Introduction" target="_right">Introduction</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td WIDTH="80%">
+ <p><nobr><a href="Contents.html#The Workbench" target="_right">The Workbench</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Projects, Folder and Files" target="_right">Projects,
+ Folders, and Files</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Getting Started" target="_right">Getting
+ Started</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#General UI Guidelines" target="_right">General
+ UI Principles</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td WIDTH="90%">
+ <p><nobr><a href="Contents.html#The Spirit of Eclipse" target="_right">The
+ Spirit of Eclipse</a></nobr> <br>
+ <nobr><a href="Contents.html#Capitalization" target="_right">Capitalization</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Colors" target="_right">Colors</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Language" target="_right">Language</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Error Handling" target="_right">Error Handling</a></nobr>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Component Development" target="_right">Component
+ Development</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td>
+ <p><nobr><a href="Contents.html#Actions" target="_right">Actions</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Dialogs" target="_right">Dialogs</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Wizards" target="_right">Wizards</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Editors" target="_right">Editors</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Views" target="_right">Views</a></nobr> <br>
+ <nobr><a href="Contents.html#Perspectives" target="_right">Perspectives</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Windows" target="_right">Windows</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Properties" target="_right">Properties</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Standard Components" target="_right">Standard
+ Components</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td>
+ <p><nobr><a href="Contents.html#Navigator" target="_right">The Navigator
+ View</a></nobr> <br>
+ <nobr><a href="Contents.html#Tasks" target="_right">The Tasks View</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#The Preference Dialog" target="_right">The
+ Preferences Dialog</a></nobr> <br>
+ <nobr><a href="Contents.html#Outline" target="_right">The Outline View</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#The Properties View" target="_right">The
+ Properties View</a></nobr> <br>
+ <nobr><a href="Contents.html#Bookmarks" target="_right">The Bookmarks
+ View</a></nobr> <br>
+ <nobr><a href="Contents.html#Text Editor" target="_right">The Text Editor</a></nobr>
+ <br>
+ <nobr><a href="Contents.html#Resource Perspective" target="_right">The
+ Resource Perspective</a></nobr> </p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><a href="Contents.html#The Tao of IResource" target="_right">The Tao
+ of Resource</a></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><a href="Contents.html#Accessability" target="_right">Accessability</a></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>&nbsp;</p>
+ </td>
+ <td>
+ <p><a href="Contents.html#Standard Accelerators" target="_right">Standard
+ Accelerators</a></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Checklist For Developers" target="_right">Checklist
+ for Developers</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Glossary" target="_right">Glossary</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Acknowledgement" target="_right">Acknowledgement</a></nobr></p>
+ </td>
+ </tr>
+ <tr>
+ <td COLSPAN="2">
+ <p><nobr><a href="Contents.html#Revision History" target="_right">Revision
+ History</a></nobr></p>
+ </td>
+ </tr>
+</table>
+
+<hr ALIGN=LEFT WIDTH="100%"><font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2001 - 2002 Object Technology International, Inc.</font></font>
+</body>
+</html>
diff --git a/Article-UI-Guidelines/v200202/actionExamples.jpg b/Article-UI-Guidelines/v200202/actionExamples.jpg
new file mode 100644
index 0000000..0b43c0a
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/actionExamples.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/badHilight.jpg b/Article-UI-Guidelines/v200202/badHilight.jpg
new file mode 100644
index 0000000..7c3b101
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/badHilight.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/badTooltips.jpg b/Article-UI-Guidelines/v200202/badTooltips.jpg
new file mode 100644
index 0000000..8a0ccb4
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/badTooltips.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/badWizardInit.jpg b/Article-UI-Guidelines/v200202/badWizardInit.jpg
new file mode 100644
index 0000000..e287a3e
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/badWizardInit.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/cell1.jpg b/Article-UI-Guidelines/v200202/cell1.jpg
new file mode 100644
index 0000000..72bb2fc
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/cell1.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/cell2.jpg b/Article-UI-Guidelines/v200202/cell2.jpg
new file mode 100644
index 0000000..1213762
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/cell2.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/cell3.jpg b/Article-UI-Guidelines/v200202/cell3.jpg
new file mode 100644
index 0000000..3d5409a
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/cell3.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/cellTableEditor.jpg b/Article-UI-Guidelines/v200202/cellTableEditor.jpg
new file mode 100644
index 0000000..cf38df8
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/cellTableEditor.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/default_style.css b/Article-UI-Guidelines/v200202/default_style.css
new file mode 100644
index 0000000..16277c9
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/default_style.css
@@ -0,0 +1,11 @@
+p { font-family: arial, helvetica, geneva; font-size: 10pt}
+td { font-family: arial,helvetica,geneva; font-size: -1}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+th { font-family: arial,helvetica,geneva; font-size: 11px; font-weight: bold}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
diff --git a/Article-UI-Guidelines/v200202/dirtyEditor.jpg b/Article-UI-Guidelines/v200202/dirtyEditor.jpg
new file mode 100644
index 0000000..f41dd05
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/dirtyEditor.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/editorTitles.jpg b/Article-UI-Guidelines/v200202/editorTitles.jpg
new file mode 100644
index 0000000..0ca3a19
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/editorTitles.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/errorsInOutline.jpg b/Article-UI-Guidelines/v200202/errorsInOutline.jpg
new file mode 100644
index 0000000..930f941
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/errorsInOutline.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/fileDeletedDialog.jpg b/Article-UI-Guidelines/v200202/fileDeletedDialog.jpg
new file mode 100644
index 0000000..802a3e0
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/fileDeletedDialog.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/folderSelection.jpg b/Article-UI-Guidelines/v200202/folderSelection.jpg
new file mode 100644
index 0000000..22fba96
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/folderSelection.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/goodParentCreation.jpg b/Article-UI-Guidelines/v200202/goodParentCreation.jpg
new file mode 100644
index 0000000..db52823
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/goodParentCreation.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/goodTooltips.jpg b/Article-UI-Guidelines/v200202/goodTooltips.jpg
new file mode 100644
index 0000000..bb37f36
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/goodTooltips.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/goodWizardInit.jpg b/Article-UI-Guidelines/v200202/goodWizardInit.jpg
new file mode 100644
index 0000000..f32fba3
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/goodWizardInit.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/guidelineCheckbox.jpg b/Article-UI-Guidelines/v200202/guidelineCheckbox.jpg
new file mode 100644
index 0000000..29a752a
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/guidelineCheckbox.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/guidelineIndicator.gif b/Article-UI-Guidelines/v200202/guidelineIndicator.gif
new file mode 100644
index 0000000..05bfab6
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/guidelineIndicator.gif
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/showViewMenu.jpg b/Article-UI-Guidelines/v200202/showViewMenu.jpg
new file mode 100644
index 0000000..d6cf86d
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/showViewMenu.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/slushBucket.jpg b/Article-UI-Guidelines/v200202/slushBucket.jpg
new file mode 100644
index 0000000..881a05c
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/slushBucket.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/tooltipCaps.jpg b/Article-UI-Guidelines/v200202/tooltipCaps.jpg
new file mode 100644
index 0000000..c96e377
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/tooltipCaps.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/wizardAppearance.jpg b/Article-UI-Guidelines/v200202/wizardAppearance.jpg
new file mode 100644
index 0000000..89b81f3
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/wizardAppearance.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/wizardErrorMsgs.jpg b/Article-UI-Guidelines/v200202/wizardErrorMsgs.jpg
new file mode 100644
index 0000000..28ca207
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/wizardErrorMsgs.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/wizardErrorMsgs2.jpg b/Article-UI-Guidelines/v200202/wizardErrorMsgs2.jpg
new file mode 100644
index 0000000..4389391
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/wizardErrorMsgs2.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/wizardFieldPopulation.jpg b/Article-UI-Guidelines/v200202/wizardFieldPopulation.jpg
new file mode 100644
index 0000000..0fad27c
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/wizardFieldPopulation.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/wizardMsgs.jpg b/Article-UI-Guidelines/v200202/wizardMsgs.jpg
new file mode 100644
index 0000000..58cbfc8
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/wizardMsgs.jpg
Binary files differ
diff --git a/Article-UI-Guidelines/v200202/workbench_decomposed.jpg b/Article-UI-Guidelines/v200202/workbench_decomposed.jpg
new file mode 100644
index 0000000..6bfe60d
--- /dev/null
+++ b/Article-UI-Guidelines/v200202/workbench_decomposed.jpg
Binary files differ
diff --git a/Article-UI-Workbench/images/LayoutPart_hierarchy.png b/Article-UI-Workbench/images/LayoutPart_hierarchy.png
new file mode 100644
index 0000000..1247170
--- /dev/null
+++ b/Article-UI-Workbench/images/LayoutPart_hierarchy.png
Binary files differ
diff --git a/Article-UI-Workbench/images/PartSashContainer.png b/Article-UI-Workbench/images/PartSashContainer.png
new file mode 100644
index 0000000..ffdb39f
--- /dev/null
+++ b/Article-UI-Workbench/images/PartSashContainer.png
Binary files differ
diff --git a/Article-UI-Workbench/images/PartStack.png b/Article-UI-Workbench/images/PartStack.png
new file mode 100644
index 0000000..31d98a6
--- /dev/null
+++ b/Article-UI-Workbench/images/PartStack.png
Binary files differ
diff --git a/Article-UI-Workbench/images/action_bar_flow.png b/Article-UI-Workbench/images/action_bar_flow.png
new file mode 100644
index 0000000..f215689
--- /dev/null
+++ b/Article-UI-Workbench/images/action_bar_flow.png
Binary files differ
diff --git a/Article-UI-Workbench/images/action_set_formula.png b/Article-UI-Workbench/images/action_set_formula.png
new file mode 100644
index 0000000..e9d1b17
--- /dev/null
+++ b/Article-UI-Workbench/images/action_set_formula.png
Binary files differ
diff --git a/Article-UI-Workbench/images/anatomy_of_a_part.png b/Article-UI-Workbench/images/anatomy_of_a_part.png
new file mode 100644
index 0000000..e43891e
--- /dev/null
+++ b/Article-UI-Workbench/images/anatomy_of_a_part.png
Binary files differ
diff --git a/Article-UI-Workbench/images/drag_regions.png b/Article-UI-Workbench/images/drag_regions.png
new file mode 100644
index 0000000..a067806
--- /dev/null
+++ b/Article-UI-Workbench/images/drag_regions.png
Binary files differ
diff --git a/Article-UI-Workbench/images/example_LayoutTree.png b/Article-UI-Workbench/images/example_LayoutTree.png
new file mode 100644
index 0000000..6840018
--- /dev/null
+++ b/Article-UI-Workbench/images/example_LayoutTree.png
Binary files differ
diff --git a/Article-UI-Workbench/images/left_arrow.png b/Article-UI-Workbench/images/left_arrow.png
new file mode 100644
index 0000000..0ba0e1f
--- /dev/null
+++ b/Article-UI-Workbench/images/left_arrow.png
Binary files differ
diff --git a/Article-UI-Workbench/images/part_creation_msc.png b/Article-UI-Workbench/images/part_creation_msc.png
new file mode 100644
index 0000000..3c573cb
--- /dev/null
+++ b/Article-UI-Workbench/images/part_creation_msc.png
Binary files differ
diff --git a/Article-UI-Workbench/images/part_states.png b/Article-UI-Workbench/images/part_states.png
new file mode 100644
index 0000000..1110668
--- /dev/null
+++ b/Article-UI-Workbench/images/part_states.png
Binary files differ
diff --git a/Article-UI-Workbench/images/perspective1.png b/Article-UI-Workbench/images/perspective1.png
new file mode 100644
index 0000000..f9aa697
--- /dev/null
+++ b/Article-UI-Workbench/images/perspective1.png
Binary files differ
diff --git a/Article-UI-Workbench/images/perspective1_2_instances.png b/Article-UI-Workbench/images/perspective1_2_instances.png
new file mode 100644
index 0000000..1b45a05
--- /dev/null
+++ b/Article-UI-Workbench/images/perspective1_2_instances.png
Binary files differ
diff --git a/Article-UI-Workbench/images/perspective2.png b/Article-UI-Workbench/images/perspective2.png
new file mode 100644
index 0000000..c474fec
--- /dev/null
+++ b/Article-UI-Workbench/images/perspective2.png
Binary files differ
diff --git a/Article-UI-Workbench/images/right_arrow.png b/Article-UI-Workbench/images/right_arrow.png
new file mode 100644
index 0000000..1ce217c
--- /dev/null
+++ b/Article-UI-Workbench/images/right_arrow.png
Binary files differ
diff --git a/Article-UI-Workbench/images/what_you_see.png b/Article-UI-Workbench/images/what_you_see.png
new file mode 100644
index 0000000..31b26f9
--- /dev/null
+++ b/Article-UI-Workbench/images/what_you_see.png
Binary files differ
diff --git a/Article-UI-Workbench/images/workbench_high_level.png b/Article-UI-Workbench/images/workbench_high_level.png
new file mode 100644
index 0000000..ba7d078
--- /dev/null
+++ b/Article-UI-Workbench/images/workbench_high_level.png
Binary files differ
diff --git a/Article-UI-Workbench/workbench.html b/Article-UI-Workbench/workbench.html
new file mode 100644
index 0000000..3cfcf77
--- /dev/null
+++ b/Article-UI-Workbench/workbench.html
@@ -0,0 +1,1112 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type"
+ content="text/html; charset=windows-1252">
+<title>Inside the Workbench: A guide to the workbench internals</title>
+
+<link rel="stylesheet" href="../default_style.css">
+</head>
+<body link="#0000ff" vlink="#800080">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif"
+ size="2">Copyright © 2005 International Business Machines Corp.</font>
+<table border="0" cellpadding="2" cellspacing="0" width="100%">
+ <tbody>
+ <tr>
+ <td colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font
+ face="Arial,Helvetica"><font color="#ffffff">&nbsp;Eclipse Corner
+ Article</font></font></b></td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<div align="left">
+<h1><a class="mozTocH1" name="mozTocId282580"></a><img
+ src="../images/Idea.jpg" align="middle" height="86" width="120" alt=""></h1>
+</div>
+<p>&nbsp;</p>
+<h1 align="center"><a class="mozTocH1" name="mozTocId119947"></a>Inside
+the Workbench<br>
+A guide to the workbench internals<br>
+</h1>
+<blockquote><b>Summary</b> <br>
+This article describes how the Eclipse 3.1 workbench works, in
+particular the infrastructure for views and editors. The goal is to
+teach you about important classes in the workbench, and how they
+interact. A familiarity with the basic workbench APIs for views,
+editors, action sets, and so forth is assumed.
+<p><b>Stefan Xenos, IBM</b> <br>
+<font size="-1">October 20, 2005</font></p>
+</blockquote>
+<br>
+<hr style="width: 100%; height: 2px;">
+<h1><a class="mozTocH1" name="mozTocId744856"></a>Table of Contents</h1>
+<ul id="mozToc">
+ <!--mozToc h2 1 h3 2 h4 3 h5 4 h6 5-->
+ <li><a href="#mozTocId917303">1 Introduction </a></li>
+ <li><a href="#mozTocId270357">2 Inside a part </a>
+ <ul>
+ <li><a href="#mozTocId713423">2.1 Part Lifecycle </a></li>
+ <li><a href="#mozTocId789670">2.2 Part Construction</a></li>
+ </ul>
+ </li>
+ <li><a href="#mozTocId409413">3 Workbench Layout </a>
+ <ul>
+ <li><a href="#mozTocId95893">3.1 An example layout</a></li>
+ <li><a href="#mozTocId114962">3.2 Zoom / Unzoom protocol </a></li>
+ <li><a href="#mozTocId977378">3.3 Layout protocol </a></li>
+ <li><a href="#mozTocId162591">3.4 PartStack: Communicating with the
+ Presentation API </a></li>
+ <li><a href="#mozTocId479574">3.5 PartSashContainer: The main
+ workbench layout </a></li>
+ <li><a href="#mozTocId887241">3.6 Drag / Drop</a></li>
+ </ul>
+ </li>
+ <li><a href="#mozTocId443855">4 Action Bars</a>
+ <ul>
+ <li><a href="#mozTocId652269">4.1 Editor Action Bars </a></li>
+ <li><a href="#mozTocId340925">4.2 Action Sets </a></li>
+ <li><a href="#mozTocId277128">4.3 View Actions</a></li>
+ </ul>
+ </li>
+ <li><a href="#mozTocId642161">5 General Conventions</a>
+ <ul>
+ <li><a href="#mozTocId892615">5.1 Objects must not be returned through
+ API until they are fully initialized</a></li>
+ <li><a href="#mozTocId308622">5.2 No method may open a modal dialog
+ unless its JavaDoc says so</a></li>
+ <li><a href="#mozTocId753192">5.3 Lazy creation should happen as late
+ as possible </a></li>
+ <li><a href="#mozTocId921869">5.4 getters should not modify the thing
+ they are supposed to measure </a></li>
+ </ul>
+ </li>
+</ul>
+<br>
+<div style="margin-left: 40px;"><span style="font-weight: bold;"></span></div>
+<h2><a class="mozTocH2" name="mozTocId917303"></a><span
+ style="font-weight: bold;"></span><span style="font-weight: bold;">1
+Introduction</span> <br>
+</h2>
+<span style="font-weight: bold;"></span>
+This document describes workbench internals and not API. The design of
+internals changes frequently. For information on newer Eclipse versions,
+the latest version of this document can be found on the
+<a
+ href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-ui-home/dev.html">UI
+development resources page</a>
+.
+<br>
+<br>
+<br>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+1: Ownership of views and editors<br>
+<br>
+</span></div>
+<div style="text-align: center;"><img alt=""
+ src="images/workbench_high_level.png"
+ style="width: 600px; height: 340px;"><br>
+</div>
+<br>
+Figure 1 shows how views and editors are owned by the workbench.
+<br>
+<br>
+The Workbench contains one or more WorkbenchWindows, each of which
+contain zero or more WorkbenchPages. The WorkbenchWindow supplies the
+trim widgets, and the WorkbenchPage supplies the window contents. In
+theory, a WorkbenchWindow can contain any number of pages, but in
+practice there is never more than 1 page in a window.
+<br>
+<br>
+Views and editors are owned by the page, through a ViewFactory and
+EditorManager respectively. EditorManager stores the list of editors and
+their shared resources, and ViewFactory stores a reference counted list
+of views. The workbench works in terms of EditorReferences and
+ViewReferences, and in this article the terms "editor" or "view" will
+refer to these classes specifically. In situations where the distinction
+between editors and views is not important, we will simply use the term
+"part". The implementation of the part (typically an IEditorPart or
+IViewPart) is created lazily when it is first needed. As shown in Figure
+2, a part reference exists for every tab but the implementation is only
+created the first time it becomes visible.
+<br>
+<br>
+The page owns a set of perspectives. Perspectives contain a layout and
+information about what action sets to enable. Although perspectives
+appear to contain views and the editor area, they only own a layout. The
+page itself maintains a reference count for how many perspectives are
+using each view, and has complete ownership of the parts and editor
+area.
+<br>
+<br>
+Not shown in figure 1 are the classes PerspectiveHelper and
+EditorAreaHelper. These classes exist largely for historic purposes, and
+in this article we will treat the former as though it were part of the
+Perspective class and the latter as part of the WorkbenchPage class.
+<br>
+<br>
+<br>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+2: Workbench objects and what they look like<br>
+<br>
+</span></div>
+<div style="text-align: center;"><img alt=""
+ src="images/what_you_see.png" style="width: 892px; height: 700px;"><br>
+</div>
+<br>
+<h2><a class="mozTocH2" name="mozTocId270357"></a>2 Inside a part<br>
+</h2>
+<div style="text-align: center;"><span style="font-weight: bold;">
+Figure 3: Anatomy of a part</span><br>
+</div>
+<div style="text-align: center;"><img alt=""
+ src="images/anatomy_of_a_part.png" style="width: 420px; height: 280px;"><br>
+</div>
+Internally, a part consists of several objects (Figure 3).
+WorkbenchPartReference is the topmost representation of the part.
+Depending on where it is used, the part reference is often exposed as
+IWorkbenchPartReference, IViewReference, IEditorRefenece, or
+IPresentablePart, or PartPane. These are essentially different
+interfaces to the same object. The I*Reference interfaces are
+implemented directly by WorkbenchPartReference and its subclasses.
+IPresentablePart is a simple adapter that redirects its methods directly
+to the part. PartPane implements the LayoutPart protocol which is needed
+to insert the part into the workbench layout. PartPane also manages the
+SWT resources (such as a top-level control) that are needed to include
+the control in the workbench layout.
+<br>
+<br>
+The part implementation (the IEditorPart or IViewPart) is owned by the
+reference. When the implementation is created, it is given a PartSite.
+The PartSite (seen by client code as an IWorkbenchPartSite, IEditorSite,
+or IViewSite) allows the client code to communicate with the reference
+and manages services created for the implementation.
+<br>
+<br>
+WorkbenchPartReferences allocates SWT resources lazily as needed. Once
+created, the part reference must be explicitly disposed. Disposing the
+reference cleans up all of its resources (including the part
+implementation itself) and guarantees that the reference will never
+allocate additional resources. The workbench page disposes the part
+reference once it is certain that it will never need to use that part
+again. Unlike SWT controls, it is valid to continue using the reference
+after it has been disposed. A disposed part reference is unlikely to do
+anything interesting besides returning its name and cannot be used with
+any methods in the workbench page. Since it is hard (or impossible) for
+clients to track the lifecycle of the reference, they are permitted to
+continue using its public interface after disposal.
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId713423"></a>2.1 Part Lifecycle<br>
+</h3>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+4: WorkbenchPartReference states<br>
+<br>
+</span></div>
+<div style="text-align: center;"><img alt=""
+ src="images/part_states.png" style="width: 445px; height: 590px;"><br>
+</div>
+Figure 4 shows the part lifecycle as a state machine. The part reference
+stores its current state in the integer state field.
+<br>
+<br>
+Notes:
+<br>
+<ul>
+ <li>The part is in a distinct state while it is in the process of
+ creating the implementation. It cannot be recursively re-created or
+ disposed while it is in this state.</li>
+ <li>The part implementation cannot be recreated once the reference has
+ been disposed.</li>
+ <li>Parts cannot return to the lazy state once they have been created.
+ This is a limitation in the 3.1 implementation, not a functional
+ requirement.</li>
+ <li>It is valid to continue using the public interface of
+ WorkbenchPartReference once it has been disposed, however a disposed
+ reference cannot be passed to methods in workbench page (since it is,
+ by definition, no longer part of any page).</li>
+</ul>
+<h3><a class="mozTocH3" name="mozTocId789670"></a>2.2 Part Construction</h3>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+5: Message sequence for creating a part<br>
+<br>
+</span></div>
+<div style="text-align: center;"><img alt=""
+ src="images/part_creation_msc.png" style="width: 892px; height: 700px;"><br>
+</div>
+<br>
+Figure 5 shows the process for creating a part. The horizontal line
+separates the two phases of creating a part. First the part is added to
+the layout, and then a real implementation is attached. These are two
+distinct operations, and the part can exist as a tab in the page with no
+implementation for some time before it becomes visible. This diagram
+focuses on the interactions with the part reference, and skips the
+details of adding the part to the presentation and creating the part
+site.
+<br>
+<br>
+Suggestion: there are situations where it would be useful to only add
+the part to the layout if it can be created successfully (this would be
+necessary to pass a PartInitException thrown in the implementation's
+init method up through IWorkbenchPage.openEditor). In these situations,
+it would be possible to merge both operations into one atomic operation
+by creating the part before adding it to the layout. It is unknown if
+this would create event ordering bugs in client code.
+<br>
+<br>
+<span style="font-weight: bold;"></span>
+<h2><a class="mozTocH2" name="mozTocId409413"></a>3 Workbench Layout<br>
+</h2>
+<br>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+6: LayoutPart hierarchy</span><br>
+<img alt="" src="images/LayoutPart_hierarchy.png"
+ style="width: 302px; height: 412px;"><br>
+</div>
+<br>
+The workbench layout provides supports arranging parts using drag &amp;
+drop, resizing and detaching parts, fast views, etc. This section gives
+a quick overview of the layout mechanism.
+<br>
+<br>
+Anything in the workbench layout is a LayoutPart. A LayoutPart manages a
+set of widgets in a rectangular region of the screen, can contain or
+arrange other layout parts, returns size constraints, responds to drag
+events, etc. To this extent, a LayoutPart is very similar to a custom
+SWT Control. However, LayoutPart differs from Control in several
+important ways.
+<br>
+<ul>
+ <li>The LayoutPart hierarchy is not the same as the widget hierarchy.
+ Even though one LayoutPart may contain another, their widgets may be
+ peers. This allows drag and drop to work on platforms where SWT doesn't
+ support reparenting, since a LayoutPart can be reparented without
+ reparenting its widgets.<br>
+ </li>
+ <li>LayoutParts mainly perform layout-related tasks, unlike Controls
+ which also supply behavior and appearance. The behavior of a LayoutPart
+ is supplied by the widgets it arranges.<br>
+ </li>
+ <li>LayoutParts know about higher-level concepts like zoom, and can
+ specify constraints about their own size.<br>
+ </li>
+</ul>
+Figure 6 shows the LayoutPart hierarchy. Notice the symmetry between the
+View* classes and the Editor* classes. These classes exist largely for
+historical reasons, and it should be possible to move all of the
+functionality into the Part* base classes or other objects in the
+system. Since all of the interesting behavior comes from the Part*
+classes, the remainder of this section will focus on them without
+describing the minor differences between views and editors.
+<br>
+<br>
+PartSashContainer arranges a set of child parts separated by a bunch of
+sashes. This is the object that implements the most visible aspects of
+the workbench layout. It arranges rectangular regions separated by
+sashes, and allows new regions to be created by splitting old ones. It
+also supports the size constraints that make minimized views possible,
+and determines what it means for one of these regions to be maximized.
+Typically, a PartSashContainer contains a bunch of PartStacks, although
+it is also possible for it to contain another PartSashContainer. The
+latter case occurs since the editor area and the perspective both use a
+PartSashContainer for their layout and one is embedded inside the other.
+PartSashContainer owns its stacks but does not own an embedded
+PartSashContainer. In a workbench window, there is one PartSashContainer
+for each perspective and one for the editor area itself.
+<br>
+<br>
+PartStack arranges a stack of PartPanes. PartStack allows the
+presentation API to participate in the workbench layout. The code for
+creating the tabs and arranging parts is supplied by the active
+presentation.
+<br>
+<br>
+PartPane allows views and editors to participate in the workbench
+layout. Although PartPanes are arranged by PartStacks they belong to
+part reference, not the stack. The same PartPane can exist in more than
+one PartStack at a time if that part appears in more that one
+perspective.
+<span style="font-weight: bold;"><br>
+<br>
+</span>
+<h3><a class="mozTocH3" name="mozTocId95893"></a>3.1 An example layout</h3>
+LayoutParts are best explained through example. Imagine a
+WorkbenchWindow that contains custom Java and Java Browsing perspectives
+that look like Figure 7 and Figure 8 respectively.
+<br>
+<br>
+<br>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+7: Example Java Perspective</span><br>
+<img alt="" src="images/perspective1.png"
+ style="width: 571px; height: 495px;"><br>
+<br>
+<span style="font-weight: bold;">Figure 8: Example Java Browsing
+perspective</span><br>
+<img alt="" src="images/perspective2.png"
+ style="width: 571px; height: 495px;"><br>
+</div>
+<br>
+<br>
+Assume that the window resembles Figure 7. In this case, the Java
+perspective is active, the Java Browsing perspective is hidden, and the
+objects are connected as shown in Figure 9:
+<br>
+<br>
+<br>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+9: LayoutPart instances when two perspectives are open</span><br>
+<img alt="" src="images/perspective1_2_instances.png"
+ style="width: 555px; height: 670px;"><br>
+<div style="text-align: left;"><br>
+</div>
+</div>
+<br>
+<br>
+All LayoutParts have a container pointer that points to the object that
+is currently managing their position. Since the same LayoutPart instance
+may exist in more than one perspective at once, this pointer points to
+the part's container in the currently-active perspective. In the case of
+the projects view, above, the part is not in the current perspective so
+its container pointer is null. When another perspective becomes active,
+all the container pointers move to the new perspective. For historical
+reasons, this is accomplished by setting and clearing the contianer
+pointer when the container becomes visible or invisible. This works
+since only one perspective is visible at a time, but it also means that
+perspectives cannot be manipulated when they are invisible.
+<br>
+<br>
+The diagram shows the internal objects that make up the only editor.
+Although this detail has been omitted for the views, they would look
+similar. Each view's PartPane is owned by a part reference which may
+have an associated part implementation.
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId114962"></a>3.2 Zoom / Unzoom
+protocol<br>
+</h3>
+The notion of "zoom" is defined locally between a part and its immediate
+container. Zoom changes are triggered bottom-up. A part asks its parent
+to "zoom me", and the parent either does something with the request or
+forwards the request up to its parent. Each container determines what it
+means for a child to be zoomed. Once a part's zoom state changes, its
+parent notifies it by calling setZoomed. The part may in turn zoom or
+unzoom one or more of its children.
+<br>
+<br>
+Anything that can contain LayoutParts must implement the following
+methods, to support zooming:
+<br>
+<span style="font-family: monospace;"><br>
+</span>
+<code>&nbsp;&nbsp;&nbsp; /**<br>
+&nbsp;&nbsp;&nbsp;&nbsp; * Called by child parts to request a zoom in,
+given an immediate child <br>
+&nbsp;&nbsp;&nbsp;&nbsp; * <br>
+&nbsp;&nbsp;&nbsp;&nbsp; * @param toZoom part to zoom in on<br>
+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
+&nbsp;&nbsp;&nbsp; public void childRequestZoomIn(LayoutPart toZoom);<br>
+&nbsp;&nbsp;&nbsp; <br>
+&nbsp;&nbsp;&nbsp; /**<br>
+&nbsp;&nbsp;&nbsp;&nbsp; * Called by child parts to request a zoom out<br>
+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
+&nbsp;&nbsp;&nbsp; public void childRequestZoomOut();<br>
+&nbsp;&nbsp;&nbsp; <br>
+&nbsp;&nbsp;&nbsp; /**<br>
+&nbsp;&nbsp;&nbsp;&nbsp; * Returns true iff the given child is obscured
+due to the fact that the container is zoomed into<br>
+&nbsp;&nbsp;&nbsp;&nbsp; * another part. <br>
+&nbsp;&nbsp;&nbsp;&nbsp; * <br>
+&nbsp;&nbsp;&nbsp;&nbsp; * @param toTest part to test<br>
+&nbsp;&nbsp;&nbsp;&nbsp; * @return true iff the part is currently
+obscured <br>
+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
+&nbsp;&nbsp;&nbsp; public boolean childObscuredByZoom(LayoutPart
+toTest);<br>
+&nbsp;&nbsp;&nbsp; <br>
+&nbsp;&nbsp;&nbsp; /**<br>
+&nbsp;&nbsp;&nbsp;&nbsp; * Returns true iff we are zoomed into the given
+part, given an immediate child of this container.<br>
+&nbsp;&nbsp;&nbsp;&nbsp; * <br>
+&nbsp;&nbsp;&nbsp;&nbsp; * @param toTest part to test<br>
+&nbsp;&nbsp;&nbsp;&nbsp; * @return true iff this contianer is currently
+zooming in on the given part<br>
+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
+&nbsp;&nbsp;&nbsp; public boolean childIsZoomed(LayoutPart toTest);<br>
+<br>
+</code>
+<br>
+Consider again Figure 7. If we were to double-click on the java editor
+to zoom it, the LayoutParts would send messages to one another in the
+following sequence. (In this diagram, each cell represents a method
+call. Each column is an object. The reciever's column shows the method
+name and the caller contains an arrow. Rows are in ascending order of
+time.)
+<br>
+<br>
+<table style="width: 100%; text-align: left;" border="1" cellpadding="2"
+ cellspacing="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top; font-weight: bold;">Java Editor
+ (PartPane)<br>
+ </td>
+ <td style="vertical-align: top; font-weight: bold;">PartStack<br>
+ </td>
+ <td style="vertical-align: top; font-weight: bold;">editor area
+ (EditorSashContainer)<br>
+ </td>
+ <td style="vertical-align: top; font-weight: bold;">ViewSashContainer<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;">requestZoomIn<br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><img alt=""
+ src="images/right_arrow.png" style="width: 42px; height: 17px;"><br>
+ </td>
+ <td style="vertical-align: top;">childRequestZoomIn(java editor)<br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><img alt=""
+ src="images/right_arrow.png" style="width: 42px; height: 17px;"><br>
+ </td>
+ <td style="vertical-align: top;">childRequestZoomIn(java editor's
+ part stack)<br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">if there were other editor stacks in
+ the layout, we would call setVisible(false) on them here</td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">remember the partStack as the zoomed
+ part<br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">setZoomed(true)<br>
+ </td>
+ <td style="vertical-align: top;"><img alt=""
+ src="images/left_arrow.png" style="width: 42px; height: 17px;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;">setZoomed(true)<br>
+ </td>
+ <td style="vertical-align: top;"><img alt=""
+ src="images/left_arrow.png" style="width: 42px; height: 17px;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><img alt=""
+ src="images/right_arrow.png" style="width: 42px; height: 17px;"><br>
+ </td>
+ <td style="vertical-align: top;">childRequestZoomIn(editor area)<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">call setVisible(false) on all
+ PartStacks for views in the perspective<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">remember the editor area as the
+ zoomed part<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">setZoomed(true)<br>
+ </td>
+ <td style="vertical-align: top;"><img alt=""
+ src="images/left_arrow.png" style="width: 42px; height: 17px;"></td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">trigger a layout<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">setBounds(zoomed bounds)<br>
+ </td>
+ <td style="vertical-align: top;"><img alt=""
+ src="images/left_arrow.png" style="width: 42px; height: 17px;"></td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">setBounds(zoomed bounds)</td>
+ <td style="vertical-align: top;"><img alt=""
+ src="images/left_arrow.png" style="width: 42px; height: 17px;"></td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;">setBounds(zoomed bounds)</td>
+ <td style="vertical-align: top;"><img alt=""
+ src="images/left_arrow.png" style="width: 42px; height: 17px;"></td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">trigger a layout (nothing to do)<br>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br>
+<h3><a class="mozTocH3" name="mozTocId977378"></a>3.3 Layout protocol<br>
+</h3>
+Every LayoutPart can specify constraints on their size. Parts specify
+constraints by implementing the ISizeProvider interface. ISizeProvider
+serves a similar function as the computeSize method on an SWT control,
+in that the parent layout uses it to consult with the part when
+computing the part's size. ISizeProvider can provide a variety of
+constraints:
+<br>
+<br>
+<table style="width: 100%; text-align: left;" border="1" cellpadding="2"
+ cellspacing="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top; font-weight: bold;">Constraint type<br>
+ </td>
+ <td style="vertical-align: top; font-weight: bold;">Meaning<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;">Minimum size<br>
+ </td>
+ <td style="vertical-align: top;">Given the available space along one
+ dimension, the part returns the minimum size that it can be
+ compressed to along the other dimension. For example, a stack would
+ typically set its minimum size to be large enough to fit its tabs.
+ The information about available perpendicular space could allow a
+ stack to have wrapping tabs and still reserve enough vertical space
+ for the tabs once they are wrapped to fill the available horizontal
+ space.<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;">Maximum size<br>
+ </td>
+ <td style="vertical-align: top;">Given the available space along one
+ dimension, the part returns the maximum size that it can utilize
+ along the other dimension. For example, minimized stacks are
+ implemented by setting their maximum size to the minimized size.
+ Non-minimized stacks typically have an unbounded maximum size.<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;">Preferred size<br>
+ </td>
+ <td style="vertical-align: top;">Given the availble space along one
+ dimension and a preferred size, this returns the size closest to the
+ preferred size at which the part would look best. Parts can use this
+ to quantize their size. For example, a part can ensure that its size
+ is always chosen such that it can be completely filled with toolbar
+ icons leaving no space left over.<br>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br>
+Although there are three kinds of constraints, they are all returned
+using a single method. See the JavaDoc on ISizeProvider for more
+information.
+<br>
+<br>
+Whenever a size constraint changes, the part notifies its contianer by
+calling resizeChild(part). This tells the container to respond to the
+new constraints, and to resize the child if necessary (suggestion: if
+this is ever exposed as API, it would be better to separate the concerns
+of notifying the parent of changes and triggering a layout. In general,
+it may be possible for more than one part to change without requiring a
+layout between each change).
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId162591"></a>3.4 PartStack:
+Communicating with the Presentation API<br>
+</h3>
+PartStack allows presentation to participate in the workbench layout. As
+shown in Figure 10, it wraps a single instance of StackPresentation, and
+allows it the presentation to manipulate parts by converting each
+visible part into an IPresentablePart. The part stack outlives the
+StackPresentation. Whenever the part stack needs widgets, it creates the
+StackPresentation. If the widgets are no longer needed, it disposes the
+StackPresentation and remembers its persisted form. Whenever the
+PartStack persists its StackPresenation, it remembers the presentation
+ID so that it will not try to restore one StackPresentation from state
+saved by an incompatible presentation.
+<br>
+<br>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+10: Anatomy of PartStack</span><br>
+<img alt="" src="images/PartStack.png"
+ style="width: 430px; height: 225px;"><br>
+<div style="text-align: left;"><br>
+Suggestion: it would be useful to update this document with a state
+diagram for PartStack, and message sequence charts for initializaiton
+and part activation.<br>
+<br>
+</div>
+</div>
+<h3><a class="mozTocH3" name="mozTocId479574"></a>3.5 PartSashContainer:
+The main workbench layout <br>
+</h3>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+11: PartSashContainer</span><br>
+<img alt="" src="images/PartSashContainer.png"
+ style="width: 428px; height: 305px;"><br>
+</div>
+<br>
+PartSashContainer implements the main layout for a perspective and the
+editor area. As shown in Figure 11, PartSashContainer contains a list of
+children, a (possibly null) zoomed part, and a LayoutTree that manages
+the actual layout.
+<br>
+<br>
+LayoutTree is a binary tree (technically, a KD tree). Each internal node
+is an instance of LayoutTreeNode. It contains a draggable sash
+(LayoutPartSash) that divides its area among its left and right
+children. LayoutTreeNodes can be horizontal or vertical based on the
+orientation of the sash. For horizontal nodes, the "left" child is on
+top and the "right" child is on the bottom. Leaf nodes are instances of
+LayoutTree (the base class), and they point to a LayoutPart that
+occupies that region of the screen. Normally, this is a PartStack, but
+in general it can be any LayoutPart.
+<br>
+<br>
+Each LayoutTree occupies a recangular region of the screen that
+encompasses its children. Internal nodes keep track of an integer size
+for each child (implementation note: the sizes are stored in the
+associated LayoutPartSash, not the LayoutTreeNode itself). Normally, the
+left and right sizes are used as a ratio for dividing up the available
+space. However, when one child contains the editor area, the other
+becomes "non-compressible". If one side in non-compressible, the size
+value is interpreted as a fixed pixel size rather than a ratio. When the
+sash is moved, the size values are set to the current pixel sizes of the
+left and right children.
+<br>
+<br>
+Figure 12 shows an example LayoutTree. If this tree were rendered in a
+workbench window, it would resemble Figure 3.5.3. The tall vertical sash
+separating the package explorer from the editor area is the root node.
+The left child is the leaf node holding the package explorer's stack.
+The right node is the horizontal sash separating the problems view from
+the editor area. The editor area itself is a PartSashContainer, which
+has its own LayoutTree. Note that the rounded rectangles in Figure 3.5.2
+are LayoutParts. The upper portion of the rectangle is the part type and
+the lower portion is some text to help locate the part in the
+screenshot. In this example, every internal node has the editor area on
+one side of it, so all sizes are interpreted as pixel sizes and not
+ratios.
+<br>
+<div style="text-align: center;"><span style="font-weight: bold;"></span><br>
+<span style="font-weight: bold;">Figure 12: Example LayoutTree</span><br
+ style="font-weight: bold;">
+<img alt="" src="images/example_LayoutTree.png"
+ style="width: 480px; height: 462px; font-weight: bold;"><br>
+<span style="font-weight: bold;"><br>
+Figure 13: Example perspective</span><br style="font-weight: bold;">
+<img alt="" src="images/perspective1.png"
+ style="width: 571px; height: 495px; font-weight: bold;"><br>
+</div>
+<br>
+Like LayoutParts, LayoutTrees also implement ISizeProvider and support
+size constraints. For external nodes, the size constraints come directly
+from the LayoutPart. For internal nodes, the size constraints are
+computed from the child nodes as follows:
+<br>
+<ol>
+ <li>When computing a constraint perpendicular to the sash, the result
+ is the sum of the constraints of the children plus the width of the
+ sash.</li>
+ <li>When computing a constraint parallel to the sash, the result is the
+ maximum of the constraints of the children<br>
+ </li>
+</ol>
+An example can help make this a little less abstract. Imagine we're
+computing the minimum width for the root node in Figure 12, which is a
+tall vertical sash. Width measurements are perpendicular to the sash, so
+we end up with case 1. The minimum width is the minimum width of the
+left stack plus the sash width plus the minimum width of the right
+child. This makes sense because if we made the root node any smaller,
+one of the three would need to be truncated or made smaller than their
+minimum size.
+<br>
+<br>
+The "right child" mentioned above is the horizontal sash separating the
+problems view from the editor area. When computing its minimum width, we
+hit case 2: the minimum width of a horizantal sash is the maximum of the
+minimum widths of each child. Intuitively, this means that the child
+with the larger minimum size will be the first to reach its minimum when
+the layout gets small.
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId887241"></a>3.6 Drag / Drop</h3>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+14: LayoutPart drop regions</span><br>
+</div>
+<div style="text-align: center;"><img alt=""
+ src="images/drag_regions.png" style="width: 571px; height: 495px;"><br>
+<div style="text-align: left;"><br>
+Dragging a workbench part is triggered by calling DragUtil.performDrag.
+SWT controls can respond to drag / drop by registering an
+IDragOverListener with DragUtil .addDragTarget. If multiple drag
+listeners are registered for the same screen position, the one
+associated with the most specific control gets precidence.<br>
+<br>
+Rather than register drag listeners directly, LayoutParts implement a
+getDropTarget method. When the window recieves a drag event, it
+delegates to the top-level LayoutPart's getDropTarget. Each part either
+delegates to one of its children or handles the drag event directly. If
+the part returns null from getDropTarget, this means that the part has
+no special preference for the drop event, and the parent may provide a
+default behavior. Unlike IDragOverListener, getDropTarget works
+top-down. The parent may overload any drag regions that are recognized
+by the child, or provide default behaviors for drag regions not
+recognized by the child.<br>
+<br>
+Figure 14 shows regions of the workbench where LayoutParts can be
+dropped. The workbench checks these regions in the following order:<br>
+<br>
+<table style="width: 100%; text-align: left;" border="1" cellpadding="2"
+ cellspacing="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;"><span style="color: rgb(0, 51, 0);">1.
+ green region</span><br>
+ </td>
+ <td style="vertical-align: top;">The fast view bar registers a
+ IDragOverListener that responds to views being dragged.<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="background-color: rgb(0, 0, 0);"><span
+ style="background-color: rgb(255, 255, 255);">2. black regions</span></span><br>
+ </td>
+ <td style="vertical-align: top;">These areas are reserved by
+ PartSashContainer.getDropTarget. When the user drags a part over this
+ region, the PartSashContainer interprets this as a split and does not
+ ask its child to participate in the drag. This ensures that it is
+ never possible for the child to prevent splitting by reserving its
+ entire area as a drop region. The region outside the
+ PartSashContainer's client area is handled by an IDragOverListener
+ registered with the shell. This allows parts to be attached to the
+ edge of the layout by dragging over the window trim.<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span style="color: rgb(255, 0, 0);">3.
+ red regions</span><br>
+ </td>
+ <td style="vertical-align: top;">For most of the screen area,
+ PartSashContainer delegates to its child (PartStack.getDropTarget).
+ PartStack filters out objects that don't belong in the stack (no
+ editors in view stacks, etc) and delegates to the presentation
+ (StackPresentation.dragOver). The default presentation recognizes the
+ tabs and title area as drop targets, but returns null everywhere
+ else. This is the best practice for presentations and PartStack since
+ it permits PartSashContainer to extend the split regions where
+ possible.<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span style="color: rgb(0, 0, 153);">4.
+ blue regions</span><br>
+ </td>
+ <td style="vertical-align: top;">If the child doesn't have any
+ particular use for the drop location, the PartSashContainer extends
+ the split regions. If the child allows objects of this type to be
+ added (determined by calling LayoutPart.allowsAdd), it uses the
+ center of the rectangle for stacking. Otherwise, the entire region is
+ used for splitting. The latter case occurs when dragging views over
+ the editor area or when dragging over a standalone view.<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;">5. outside the window (not shown)<br>
+ </td>
+ <td style="vertical-align: top;">The workbench page registers an
+ IDragOverListener that responds to views being dragged outside the
+ workbench window, and interprets this as a detach operation.<br>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br>
+By convention, all methods used for drag / drop work in display
+coordinates.<br>
+<br>
+</div>
+</div>
+<h2><a class="mozTocH2" name="mozTocId443855"></a>4 Action Bars</h2>
+Parts contribute to menus, toolbars, coolbars, popup menus, etc. using
+action bars. Each action bar implements IActionBars. It is possible to
+create one action bar as a child of another. In this situation, the
+parent and child share the same widgets, but the child may be disabled
+independently of the parent. Figure 15 shows how the workbench action
+bars are constructed. The rectangles indicate instances of IActionBars,
+and the ovals indicate other entities that create or modify action bars.
+<br>
+<br>
+<div style="text-align: center;"><span style="font-weight: bold;">Figure
+15: Action bar information flow</span><br>
+<img alt="" src="images/action_bar_flow.png"
+ style="width: 800px; height: 600px;"><br>
+<div style="text-align: left;">
+<p
+ colors="#FFFFFF,#000000,#808080,#000000,#00CC99,#3333CC,#CCCCFF,#B2B2B2"></p>
+<div class="O">
+<div style=""><span style="font-size: 50%;"><br>
+</span><span style="font-family: Symbol; font-size: 50%;"></span><span
+ style="font-size: 50%;"></span><span
+ style="font-family: Symbol; font-size: 50%;"></span><span
+ style="font-size: 50%;"></span><span
+ style="font-family: Symbol; font-size: 50%;"></span><span
+ style="font-size: 50%;"></span></div>
+<div style=""><span style="display: none;"> </span></div>
+</div>
+</div>
+</div>
+<br>
+The workbench window has a top level IActionBars instance that
+contributes to the main menubar, coolbar, etc. (this top-level object is
+returned by WorkbenchWindow.getActionBars()).
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId652269"></a>4.1 Editor Action Bars<br>
+</h3>
+Each type of editor gets a reference-counted IActionBars instance that
+is a child of the window's action bars. For example, if the workbench
+contains 10 java editors and 10 text editors, it will create one
+IActionBars to be shared among the Java editors and another IActionBars
+to be shared among the text editors. Editors can access this shared
+instance by calling getSite().getActionBars(). Editor action bars are
+initialized by an instance of IEditorActionBarContributor, and
+additional actions are added by the editorActions extension point.
+<br>
+<br>
+The reference counted IEditorActionBars are managed by the
+EditorManager, along with the IActionBarContributor.
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId340925"></a>4.2 Action Sets<br>
+</h3>
+An action set is an action bar that is identified by ID. Action sets are
+contributed by the actionSets extension point, and their action bars are
+a child of the workbench window's root action bars. Visibility of action
+sets is controlled by the following function:
+<br>
+<br>
+<div style="margin-left: 40px;"><img alt=""
+ src="images/action_set_formula.png" style="width: 208px; height: 29px;"><br>
+</div>
+<br>
+Where:
+<br>
+<br>
+<div style="margin-left: 40px;">P = set of actions enabled in the
+perspective. Returned by Perspective.getAlwaysOnActionSets().
+Initialized by the perspective factory, perspective extensions extension
+point, and IWonkbenchPage.showActionSet.<br>
+A = action sets associated with the active part (associated by the
+actionSetPartAssociations extension point).<br>
+E = action sets associated with the active editor (associated by the
+actionSetPartAssociations extension point).<br>
+D = action sets that are enabled by default (a property of the
+actionSets extension markup).<br>
+N = action sets that are explicitly disabled in the current perspective.
+Initialized by IWorkbenchPage.hideActionSet.<br>
+</div>
+<br>
+The sets P and N are persisted with the current perspective between
+sessions. The sets A and E can change every time the active part or
+editor changes.
+<br>
+<br>
+The workbench page uses the class ActionSetManager to compute action set
+enablement. This class keeps two reference counts for each action set:
+<br>
+<ul>
+ <li>a "showCount" indicates how many of P, A, E, and D the action set
+ appears in</li>
+ <li>a "hideCount" indicates whether the action set appears in N</li>
+</ul>
+The action set is visible iff showCount is nonzero and hideCount is
+zero.
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId277128"></a>4.3 View Actions</h3>
+Each view instance is given its own IActionBars instance. Unlike editor
+action bars, these are not shared and are not a child of the workbench
+window's root action bars. This means that view instances can
+programmatically add actions to their action bar. Additional actions are
+also added to a view's action bars through the viewActions extension
+point.
+<br>
+<br>
+<h2><a class="mozTocH2" name="mozTocId642161"></a>5 General Conventions</h2>
+This section describes coding conventions that apply to the entire
+workbench.
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId892615"></a>5.1 Objects must not
+be returned through API until they are fully initialized</h3>
+Some objects require several public methods to be called in a specific
+order before they are considered fully initialized. For example, to
+initialize an IViewPart, it is necessary to call the constructor,
+setInitializationData, init, and createPartControl before the part is
+considered initialized. Until
+<span style="font-style: italic;">all</span>
+of the above have happened successfully, it must not be possible to
+reach the object through any API method.
+<br>
+<br>
+Keep in mind that the object may trigger other client code during its
+own initialization, so it should not even be possible for an object to
+find itself during construction.
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId308622"></a>5.2 No method may open
+a modal dialog unless its JavaDoc says so</h3>
+Any method that has the possibility of opening a modal (or of calling
+Display.readAndDispatch through any other means) needs to be clearly
+documented. All callers of that method must be prepared to handle
+background threads running arbitrary code in *syncExecs during the
+method call. It is always a bug to open a modal dialog when extending or
+overloading a method unless the JavaDoc in the base class says
+otherwise. Permitting opening of dialogs in a method that did not
+previously do so is a breaking change for all callers of that method.
+<br>
+<br>
+Some common bugs:
+<br>
+<ul>
+ <li>Views are never allowed to call MessageDialog.openError from their
+ createPartControls method, especially when handling an exception.</li>
+ <li>Parts can be closed in a *syncExec. If a part calls a method that
+ opens dialogs, it might not still exist when the method returns. After
+ calling the method, the part must check that it hasn't been disposed
+ before using their widgets or accessing any members that would have
+ been deallocated by the disposal.</li>
+</ul>
+<br>
+<h3><a class="mozTocH3" name="mozTocId753192"></a>5.3 Lazy creation
+should happen as late as possible<br>
+</h3>
+Part implementations should be created at the latest possible moment.
+The workbench's internal state should be restored as much as possible
+before the first object is created from an extension point. Parts should
+not be materialized until they are needed.
+<br>
+<br>
+<h3><a class="mozTocH3" name="mozTocId921869"></a>5.4 getters should not
+modify the thing they are supposed to measure<br>
+</h3>
+This applies to any situation where there is a getter and an associated
+listener that monitors changes in the getter's value. The getter should
+never cause such a property change to be fired while computing its
+return value.
+<br>
+<br>
+For example, IWorkbenchPage.getActivePart() should never create the
+active part. Unless the active part already exists and a property change
+was fired to all IPartListeners, getActivePart must return null.
+<br>
+<br>
+<hr>
+<p>To discuss or report problems in this article see <a
+ href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=103958">bug 103958</a>.</p>
+
+<p><small>IBM is trademark of International Business Machines
+Corporation in the United States, other countries, or both.</small></p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or
+registered trademarks of Sun Microsystems, Inc. in the United States,
+other countries, or both.</small></p>
+<p><small>Microsoft and Windows are trademarks of Microsoft Corporation
+in the United States, other countries, or both.</small></p>
+<p><small>Other company, product, and service names may be trademarks or
+service marks of others.</small></p>
+
+
+</body>
+</html>
diff --git a/Article-Understanding Layouts/Understanding Layouts.htm b/Article-Understanding Layouts/Understanding Layouts.htm
new file mode 100644
index 0000000..1e54089
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts.htm
@@ -0,0 +1,3882 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml"
+xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List href="./Understanding%20Layouts_files/filelist.xml">
+<link rel=OLE-Object-Data href="./Understanding%20Layouts_files/oledata.mso">
+<!--[if !mso]>
+<style>
+v\:* {behavior:url(#default#VML);}
+o\:* {behavior:url(#default#VML);}
+w\:* {behavior:url(#default#VML);}
+.shape {behavior:url(#default#VML);}
+</style>
+<![endif]-->
+<title>Understanding Layouts in SWT</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Author>OTI EMPLOYEE</o:Author>
+ <o:LastAuthor>Dave Thomson</o:LastAuthor>
+ <o:Revision>19</o:Revision>
+ <o:TotalTime>4133</o:TotalTime>
+ <o:LastPrinted>2001-03-07T20:56:00Z</o:LastPrinted>
+ <o:Created>2001-06-04T02:06:00Z</o:Created>
+ <o:LastSaved>2001-06-04T16:29:00Z</o:LastSaved>
+ <o:Pages>27</o:Pages>
+ <o:Words>5576</o:Words>
+ <o:Characters>31787</o:Characters>
+ <o:Company>OBJECT TECHNOLOGY INTL</o:Company>
+ <o:Lines>264</o:Lines>
+ <o:Paragraphs>63</o:Paragraphs>
+ <o:CharactersWithSpaces>39036</o:CharactersWithSpaces>
+ <o:Version>9.2720</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:ActiveWritingStyle Lang="EN-US" VendorID="8" DLLVersion="513" NLCheck="0">1</w:ActiveWritingStyle>
+ <w:DoNotHyphenateCaps/>
+ <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
+ <w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>
+ <w:UseMarginsForDrawingGridOrigin/>
+ <w:Compatibility>
+ <w:UsePrinterMetrics/>
+ <w:WW6BorderRules/>
+ <w:FootnoteLayoutLikeWW8/>
+ <w:ShapeLayoutLikeWW8/>
+ <w:AlignTablesRowByRow/>
+ <w:ForgetLastTabAlignment/>
+ <w:LayoutRawTableWidth/>
+ <w:LayoutTableRowsApart/>
+ </w:Compatibility>
+ </w:WordDocument>
+</xml><![endif]-->
+<link rel=Stylesheet type="text/css" media=all
+href="Understanding%20Layouts_files\default_style.css">
+<style>
+<!--
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+h1
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:21.0pt;
+ font-family:Arial;
+ color:windowtext;
+ mso-font-kerning:14.0pt;
+ font-weight:bold;}
+h2
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-line-height-alt:10.5pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:2;
+ font-size:18.0pt;
+ font-family:Arial;
+ color:windowtext;
+ font-weight:bold;}
+h3
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:3;
+ font-size:14.0pt;
+ font-family:Arial;
+ color:windowtext;
+ font-weight:bold;}
+h4
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:4;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+h5
+ {mso-style-next:Normal;
+ margin:0in;
+ margin-bottom:.0001pt;
+ text-align:center;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:5;
+ mso-list:skip;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc1, li.MsoToc1, div.MsoToc1
+ {mso-style-next:Normal;
+ margin-top:.25in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ text-transform:uppercase;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc2, li.MsoToc2, div.MsoToc2
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc3, li.MsoToc3, div.MsoToc3
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:10.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc4, li.MsoToc4, div.MsoToc4
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:20.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc5, li.MsoToc5, div.MsoToc5
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:30.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc6, li.MsoToc6, div.MsoToc6
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:40.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc7, li.MsoToc7, div.MsoToc7
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:50.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc8, li.MsoToc8, div.MsoToc8
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:60.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc9, li.MsoToc9, div.MsoToc9
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:70.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoHeader, li.MsoHeader, div.MsoHeader
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoFooter, li.MsoFooter, div.MsoFooter
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoBodyText, li.MsoBodyText, div.MsoBodyText
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:red;}
+p.MsoBodyText2, li.MsoBodyText2, div.MsoBodyText2
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in;
+ layout-grid-mode:char;
+ font-size:9.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:black;}
+a:link, span.MsoHyperlink
+ {color:blue;
+ text-decoration:underline;
+ text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+ {color:purple;
+ text-decoration:underline;
+ text-underline:single;}
+strong
+ {mso-bidi-font-weight:normal;}
+em
+ {mso-bidi-font-style:normal;}
+p
+ {margin-top:5.0pt;
+ margin-right:0in;
+ margin-bottom:5.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:Arial;
+ mso-fareast-font-family:"Times New Roman";
+ color:black;}
+code
+ {mso-ansi-font-size:8.5pt;
+ mso-bidi-font-size:8.5pt;
+ mso-ascii-font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-hansi-font-family:"Courier New";
+ mso-bidi-font-family:"Courier New";}
+pre
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;
+ font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Courier New";
+ color:windowtext;}
+p.Code, li.Code, div.Code
+ {mso-style-name:Code;
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in 2.25in 2.5in 2.75in 3.0in 3.25in 3.5in 3.75in 4.0in 4.25in 4.5in 4.75in 5.0in 5.25in 5.5in 5.75in;
+ layout-grid-mode:char;
+ font-size:9.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:windowtext;}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-title-page:yes;
+ mso-even-footer:url("./Understanding%20Layouts_files/header.htm") ef1;
+ mso-footer:url("./Understanding%20Layouts_files/header.htm") f1;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+ /* List Definitions */
+@list l0
+ {mso-list-id:-2;
+ mso-list-type:simple;
+ mso-list-template-ids:-1;}
+@list l0:level1
+ {mso-level-start-at:0;
+ mso-level-text:*;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:0in;
+ text-indent:0in;}
+@list l1
+ {mso-list-id:346905124;
+ mso-list-type:hybrid;
+ mso-list-template-ids:-640262218 1992605384 -1164151212 196216344 207768582 -465804808 -978527370 -445462926 -1247488604 2084046000;}
+@list l1:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l2
+ {mso-list-id:400176146;
+ mso-list-type:hybrid;
+ mso-list-template-ids:-1883319026 -1449079578 1246159260 -1325105612 57442112 507803072 -1579807020 720565274 476881622 -2006260142;}
+@list l2:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.75in;
+ mso-level-number-position:left;
+ margin-left:.75in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l3
+ {mso-list-id:605164106;
+ mso-list-type:hybrid;
+ mso-list-template-ids:832965996 1120049284 -1716494676 1491470454 296799966 -1824480168 1890771820 895397522 -1654206448 1985668936;}
+@list l3:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.75in;
+ mso-level-number-position:left;
+ margin-left:.75in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l4
+ {mso-list-id:1030568495;
+ mso-list-type:hybrid;
+ mso-list-template-ids:-170775920 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
+@list l4:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:26.65pt;
+ mso-level-number-position:left;
+ margin-left:26.65pt;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l5
+ {mso-list-id:1666586583;
+ mso-list-type:hybrid;
+ mso-list-template-ids:-170775920 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
+@list l5:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:26.65pt;
+ mso-level-number-position:left;
+ margin-left:26.65pt;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l0:level1 lfo2
+ {mso-level-number-format:bullet;
+ mso-level-numbering:continue;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ mso-level-legacy:yes;
+ mso-level-legacy-indent:.25in;
+ mso-level-legacy-space:0in;
+ margin-left:.25in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+ol
+ {margin-bottom:0in;}
+ul
+ {margin-bottom:0in;}
+-->
+</style>
+<!--[if gte mso 9]><xml>
+ <o:shapedefaults v:ext="edit" spidmax="1102"/>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <o:shapelayout v:ext="edit">
+ <o:idmap v:ext="edit" data="1"/>
+ </o:shapelayout></xml><![endif]-->
+</head>
+
+<body lang=EN-US link=blue vlink=purple style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p class=MsoNormal align=right style='margin-top:14.2pt;margin-right:0in;
+margin-bottom:0in;margin-left:17.0pt;margin-bottom:.0001pt;text-align:right'><a
+name="_Toc496069418"></a><a name="_Toc509864523"><span style='mso-bookmark:
+_Toc496069418'><span style='font-size:8.0pt;mso-bidi-font-size:10.0pt'>Copyright
+© 2001 Object Technology International, Inc.<o:p></o:p></span></span></a></p>
+
+<table border=0 cellspacing=0 cellpadding=0 width="100%" style='width:100.0%;
+ mso-cellspacing:0in;margin-left:17.0pt;mso-padding-alt:1.5pt 1.5pt 1.5pt 1.5pt'>
+ <tr>
+ <td valign=top style='background:#0080C0;padding:1.5pt 1.5pt 1.5pt 1.5pt'>
+ <p class=MsoNormal><span style='mso-bookmark:_Toc509864523'><span
+ style='mso-bookmark:_Toc496069418'><b><span style='font-family:Arial;
+ color:white'>&nbsp;Eclipse Corner Article</span></b></span></span><span
+ style='mso-bookmark:_Toc509864523'><span style='mso-bookmark:_Toc496069418'><span
+ style='mso-bidi-font-size:12.0pt'><o:p></o:p></span></span></span></p>
+ </td>
+ <span style='mso-bookmark:_Toc509864523'><span style='mso-bookmark:_Toc496069418'></span></span>
+ </tr>
+</table>
+
+<h1 style='margin-left:17.0pt'><span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'><img width=120 height=86 id="_x0000_i1060"
+src="Understanding%20Layouts_files\idea.jpg" align=CENTER></span></span><span
+style='mso-bookmark:_Toc509864523'><span style='mso-bookmark:_Toc496069418'><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt'><o:p></o:p></span></span></span></h1>
+
+<h1 align=center style='margin-left:17.0pt;text-align:center'><span
+style='mso-bookmark:_Toc509864523'><span style='mso-bookmark:_Toc496069418'>Understanding
+Layouts in SWT</span></span></h1>
+
+<p class=MsoNormal style='margin-left:17.0pt;text-indent:.5in'><span
+style='mso-bookmark:_Toc509864523'><span style='mso-bookmark:_Toc496069418'><b><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></span></span></p>
+
+<p class=MsoNormal style='margin-top:0in;margin-right:.5in;margin-bottom:0in;
+margin-left:53.0pt;margin-bottom:.0001pt'><span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'><b>Summary</b> <br>
+When writing applications in SWT, you may need to use <i style='mso-bidi-font-style:
+normal'>layouts</i> to give your windows a specific look. A layout controls the
+position and size of children in a <i style='mso-bidi-font-style:normal'>Composite</i>.
+Layout classes are subclasses of the abstract class <i style='mso-bidi-font-style:
+normal'>Layout</i>. This article shows you how to work with standard layouts,
+and write your own custom layout class.</span></span><span style='mso-bookmark:
+_Toc509864523'><span style='mso-bookmark:_Toc496069418'><span lang=EN-CA
+style='mso-bidi-font-size:12.0pt;mso-ansi-language:EN-CA'><o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-top:0in;margin-right:.5in;margin-bottom:0in;
+margin-left:53.0pt;margin-bottom:.0001pt'><span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'><b><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></span></span></p>
+
+<p class=MsoNormal style='margin-top:0in;margin-right:.5in;margin-bottom:0in;
+margin-left:53.0pt;margin-bottom:.0001pt'><span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'><b>By Carolyn MacLeod, OTI<o:p></o:p></b></span></span></p>
+
+<p class=MsoNormal style='margin-top:0in;margin-right:.5in;margin-bottom:0in;
+margin-left:53.0pt;margin-bottom:.0001pt'><span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'><span style='font-size:10.0pt'>March 22,
+2001<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-top:0in;margin-right:.5in;margin-bottom:0in;
+margin-left:53.0pt;margin-bottom:.0001pt'><span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'><b><span style='font-size:8.0pt;mso-bidi-font-size:
+10.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></b></span></span></p>
+
+
+<div class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><span
+style='mso-bookmark:_Toc509864523'><span style='mso-bookmark:_Toc496069418'>
+
+<hr size=2 width="100%" align=center>
+
+</span></span></div>
+
+<b style='mso-bidi-font-weight:normal'><span style='font-size:21.0pt;
+font-family:Arial;mso-fareast-font-family:"Times New Roman";mso-font-kerning:
+14.0pt;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
+AR-SA'><br clear=all style='page-break-before:always'>
+</span></b>
+
+<h1 style='margin-left:17.0pt'><span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'>Layouts</span></span></h1>
+
+<h2 style='margin-left:17.0pt'><a name="_Toc496069419"></a><a
+name="_Toc496069776"></a><a name="_Toc509864524"><span style='mso-bookmark:
+_Toc496069776'><span style='mso-bookmark:_Toc496069419'>Overview</span></span></a></h2>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>When writing
+applications in SWT, you may need to use <i style='mso-bidi-font-style:normal'>layouts</i>
+to give your windows a specific look. A layout controls the position and size
+of children in a <i style='mso-bidi-font-style:normal'>Composite</i>. Layout
+classes are subclasses of the abstract class <i style='mso-bidi-font-style:
+normal'>Layout</i>. SWT provides several standard layout classes, and you can
+write custom layout classes.</p>
+
+<p class=MsoHeader style='margin-left:17.0pt;tab-stops:.5in center 3.0in right 6.0in'><a
+name="_Toc496069420"></a><a name="_Toc496069777"><span style='mso-bookmark:
+_Toc496069420'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></a></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069777'><span
+style='mso-bookmark:_Toc496069420'>In SWT, positioning and sizing does not
+happen automatically. Applications can decide to size and place a <i
+style='mso-bidi-font-style:normal'>Composite</i>’s children initially or in a
+resize listener – or they can specify a layout class to position and size the
+children. If children are not given a size, they will have zero size and they
+cannot be seen.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069777'><span
+style='mso-bookmark:_Toc496069420'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069777'><span
+style='mso-bookmark:_Toc496069420'>The diagram below illustrates a few general
+terms that are used when discussing layouts. The <i>Composite</i> (in this
+case, a <i>TabFolder</i>) has a <b>location</b>, <b>clientArea</b> and <b>trim</b>.
+The size of the <i>Composite</i> is the size of the <b>clientArea</b> plus the
+size of the <b>trim</b>. The <i>Composite</i> has two children that are laid
+out side by side. A <i>Layout</i> is managing the size and position of the
+children. This <i>Layout</i> allows <b>spacing</b> between the children, and a <b>margin</b>
+between the children and the edges of the <i>Layout</i>. The size of the <i>Layout</i>
+is the same as the size of the <i>Composite</i>’s <b>clientArea</b>.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069777'><span
+style='mso-bookmark:_Toc496069420'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><!--[if gte vml 1]><o:wrapblock><v:shapetype
+ id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"
+ path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
+ <v:stroke joinstyle="miter"/>
+ <v:formulas>
+ <v:f eqn="if lineDrawn pixelLineWidth 0"/>
+ <v:f eqn="sum @0 1 0"/>
+ <v:f eqn="sum 0 0 @1"/>
+ <v:f eqn="prod @2 1 2"/>
+ <v:f eqn="prod @3 21600 pixelWidth"/>
+ <v:f eqn="prod @3 21600 pixelHeight"/>
+ <v:f eqn="sum @0 0 1"/>
+ <v:f eqn="prod @6 1 2"/>
+ <v:f eqn="prod @7 21600 pixelWidth"/>
+ <v:f eqn="sum @8 21600 0"/>
+ <v:f eqn="prod @7 21600 pixelHeight"/>
+ <v:f eqn="sum @10 21600 0"/>
+ </v:formulas>
+ <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
+ <o:lock v:ext="edit" aspectratio="t"/>
+ </v:shapetype><v:shape id="_x0000_s1067" type="#_x0000_t75" style='position:absolute;
+ left:0;text-align:left;margin-left:0;margin-top:0;width:390pt;height:222pt;
+ z-index:6'>
+ <v:imagedata src="./Understanding%20Layouts_files/image001.png" o:title=""/>
+ <w:wrap type="topAndBottom" anchorx="page"/>
+ </v:shape><![if gte mso 9]><o:OLEObject Type="Embed" ProgID="PBrush"
+ ShapeID="_x0000_s1067" DrawAspect="Content" ObjectID="_1053162908">
+ </o:OLEObject>
+ <![endif]><![endif]--><![if !vml]><img width=520 height=296
+ src="./Understanding%20Layouts_files/image002.jpg" v:shapes="_x0000_s1067"><![endif]><!--[if gte vml 1]></o:wrapblock><![endif]--><br
+style='mso-ignore:vglayout' clear=ALL>
+<span style='mso-bookmark:_Toc496069777'><span style='mso-bookmark:_Toc496069420'>The
+<i>preferred size</i> of a widget is the minimum size needed to show its
+content. In the case of a <i>Composite</i>, the preferred size is the smallest
+rectangle that contains all of its children. If children have been positioned
+by the application, the <i style='mso-bidi-font-style:normal'>Composite</i>
+computes its own preferred size based on the size and position of the children.
+If a <i style='mso-bidi-font-style:normal'>Composite</i> is using a layout
+class to position its children, it asks the <i style='mso-bidi-font-style:normal'>Layout</i>
+to compute the size of its <b>clientArea</b>, and then it adds in the <b>trim</b>
+to determine its preferred size.</span></span></p>
+
+<span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h2 style='margin-left:17.0pt;mso-list:skip'><span style='mso-bookmark:_Toc496069777'><span
+style='mso-bookmark:_Toc496069420'><a name="_Toc509864525">Standard Layouts</a></span></span></h2>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>The standard layout
+classes in the SWT library are:</p>
+
+<p class=MsoNormal style='margin-left:35.0pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]><i style='mso-bidi-font-style:normal'>FillLayout</i> –
+lays out equal-sized widgets in a single row or column</p>
+
+<p class=MsoNormal style='margin-left:35.0pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]><i style='mso-bidi-font-style:normal'>RowLayout</i> –
+lays out widgets in a row or rows, with fill, wrap, and spacing options</p>
+
+<p class=MsoNormal style='margin-left:35.0pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]><i style='mso-bidi-font-style:normal'>GridLayout</i> –
+lays out widgets in a grid</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>To use the standard
+layouts, you need to import the SWT layout package:</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'><span
+style='mso-tab-count:1'>    </span>import</span> org.eclipse.swt.layout.*;</p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>Layouts are
+pluggable. To set a layout into a <i style='mso-bidi-font-style:normal'>Composite</i>
+widget, you use the widget’s <b style='mso-bidi-font-weight:normal'>setLayout(Layout)</b>
+method. In the following code, a <i style='mso-bidi-font-style:normal'>Shell </i>(a
+subclass of<i style='mso-bidi-font-style:normal'> Composite</i>) is told to
+position its children using a <i style='mso-bidi-font-style:normal'>RowLayout</i>:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>Shell
+shell = <span style='color:navy'>new</span> Shell();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>shell.setLayout(<span
+style='color:navy'>new</span> RowLayout());</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>A layout class may
+have a corresponding layout data class – a subclass of <i style='mso-bidi-font-style:
+normal'>Object</i> that contains layout data for a specific child. By
+convention, layout data classes are identified by substituting <i
+style='mso-bidi-font-style:normal'>Data</i> for <i style='mso-bidi-font-style:
+normal'>Layout</i> in the class name. For example, the standard layout class <i
+style='mso-bidi-font-style:normal'>RowLayout</i> has a layout data class called
+<i style='mso-bidi-font-style:normal'>RowData</i>, and the layout class <i
+style='mso-bidi-font-style:normal'>GridLayout</i> uses a layout data class
+called <i style='mso-bidi-font-style:normal'>GridData</i>. Layout data classes
+are set into a widget as follows:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>Button
+button = <span style='color:navy'>new</span> Button(shell, SWT.PUSH);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>button.setLayoutData(<span
+style='color:navy'>new</span> RowData(50, 40));</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h2 style='margin-left:17.0pt'><a name="_Toc509864526">Examples in this
+Document</a></h2>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Most of the snapshots in this
+document were taken by running variations on the following example code. We may
+change the type of layout, the options used, or the type or number of children.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span>
+org.eclipse.swt.*;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span>
+org.eclipse.swt.widgets.*;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span>
+org.eclipse.swt.layout.*;</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>public</span>
+<span style='color:navy'>class</span> LayoutExample {</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>public</span> <span style='color:navy'>static</span> <span
+style='color:navy'>void</span> main(String[] args) {</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Display
+display = <span style='color:navy'>new</span> Display();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Shell
+shell = <span style='color:navy'>new</span> Shell(display);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:maroon'>//
+Create the layout.</span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>RowLayout layout = </span><span
+style='color:navy'>new</span><span style='color:black'> RowLayout();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:maroon'>//
+Optionally set layout fields.</span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>layout.wrap = </span><span
+style='color:navy'>true</span><span style='color:black'>;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:maroon'>// Set
+the layout into the composite.</span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>shell.setLayout(layout);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:maroon'>//
+Create the children of the composite.</span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span><span
+style='mso-tab-count:1'>   </span><span style='color:navy'>new</span>
+Button(shell, SWT.PUSH).setText(<span style='color:teal'>&quot;B1&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>new</span> Button(shell, SWT.PUSH).setText(<span
+style='color:teal'>&quot;Wide Button 2&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>new</span> Button(shell, SWT.PUSH).setText(<span
+style='color:teal'>&quot;Button 3&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>shell.pack();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>shell.open();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>while</span> (!shell.isDisposed()) {</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:3'>          </span><span
+style='color:navy'>if</span> (!display.readAndDispatch()) display.sleep();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>}</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>}</p>
+
+<p class=Code style='margin-left:17.0pt'>}</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Running the above code results in
+the following:</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1063" type="#_x0000_t75" style='width:130.5pt;height:39.75pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image003.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=174 height=53
+src="./Understanding%20Layouts_files/image004.jpg" v:shapes="_x0000_i1063"><![endif]></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>If the user resizes the shell so
+that there is no longer room for <span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>Button 3</span> on the right, the <i style='mso-bidi-font-style:
+normal'>RowLayout</i> wraps <span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>Button 3</span> to the next row, as follows:</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1064" type="#_x0000_t75" style='width:105.75pt;height:56.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image005.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=141 height=75
+src="./Understanding%20Layouts_files/image006.jpg" v:shapes="_x0000_i1064"><![endif]></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Using layouts is closely tied with
+resize, as we shall see. Consequently, most of the examples in this document
+show what would happen if the <i style='mso-bidi-font-style:normal'>Composite</i>
+becomes smaller or larger, in order to illustrate how the <i style='mso-bidi-font-style:
+normal'>Layout</i> works.</p>
+
+<span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h2 style='margin-left:17.0pt'><a name="_Toc509864527"><span style='layout-grid-mode:
+line'>FillLayout</span></a><span style='layout-grid-mode:line'><o:p></o:p></span></h2>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><i
+style='mso-bidi-font-style:normal'>FillLayout</i> is the simplest layout class.
+It lays out widgets in a single row or column, forcing them to be the same
+size. Initially, the widgets will all be as tall as the tallest widget, and as
+wide as the widest. <i style='mso-bidi-font-style:normal'>FillLayout</i> does
+not wrap, and you cannot specify margins or spacing. You might use it to lay
+out buttons in a task bar or tool bar, or to stack checkboxes in a <i
+style='mso-bidi-font-style:normal'>Group</i>. <i style='mso-bidi-font-style:
+normal'>FillLayout</i> can also be used when a <i style='mso-bidi-font-style:
+normal'>Composite</i> only has one child. For example, if a <i
+style='mso-bidi-font-style:normal'>Shell</i> has a single <i style='mso-bidi-font-style:
+normal'>Group</i> child, <i style='mso-bidi-font-style:normal'>FillLayout</i>
+will cause the <i style='mso-bidi-font-style:normal'>Group</i> to completely
+fill the <i style='mso-bidi-font-style:normal'>Shell</i>.</p>
+
+<p class=MsoHeader style='margin-left:17.0pt;mso-list:skip;tab-stops:.5in center 3.0in right 6.0in'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>Here is the
+relevant portion of the example code. First we create a <i style='mso-bidi-font-style:
+normal'>FillLayout</i>, then (if we want vertical) we set its <b
+style='mso-bidi-font-weight:normal'>type</b> field, and then we set it into the
+<i style='mso-bidi-font-style:normal'>Composite</i> (a <i style='mso-bidi-font-style:
+normal'>Shell</i>). The <i style='mso-bidi-font-style:normal'>Shell</i> has
+three pushbutton children, <span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>B1</span>, <span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>B2</span>, and <span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>Button 3</span>. Note that in a <i style='mso-bidi-font-style:
+normal'>FillLayout</i>, children are always the same size, and they fill all
+available space.</p>
+
+<p class=MsoHeader style='margin-left:17.0pt;mso-list:skip;tab-stops:.5in center 3.0in right 6.0in'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>FillLayout
+fillLayout = <span style='color:navy'>new</span> FillLayout();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>fillLayout.type
+= SWT.VERTICAL;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>shell.setLayout(fillLayout);</p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>The following table
+shows the differences between a horizontal and vertical <i style='mso-bidi-font-style:
+normal'>FillLayout</i>, initially and after the parent has grown.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<table border=0 cellspacing=0 cellpadding=0 style='margin-left:17.0pt;
+ border-collapse:collapse;mso-padding-alt:0in 5.4pt 0in 5.4pt'>
+ <tr>
+ <td width=145 valign=top style='width:108.9pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><b
+ style='mso-bidi-font-weight:normal'><o:p></o:p></b></p>
+ </td>
+ <td width=222 valign=top style='width:166.5pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <h5>Initial</h5>
+ </td>
+ <td width=223 valign=top style='width:167.4pt;border:none;border-bottom:solid black .75pt;
+ mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <h5>After resize</h5>
+ </td>
+ </tr>
+ <tr>
+ <td width=145 valign=top style='width:108.9pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'>fillLayout.type =
+ SWT.HORIZONTAL<o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'>(default)<o:p></o:p></b></p>
+ </td>
+ <td width=222 valign=top style='width:166.5pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1065" type="#_x0000_t75" style='width:118.5pt;height:35.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image007.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=158 height=47
+ src="./Understanding%20Layouts_files/image008.jpg" v:shapes="_x0000_i1065"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ <td width=223 valign=top style='width:167.4pt;border:none;border-bottom:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1066" type="#_x0000_t75" style='width:137.25pt;height:50.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image009.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=183 height=67
+ src="./Understanding%20Layouts_files/image010.jpg" v:shapes="_x0000_i1066"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=145 valign=top style='width:108.9pt;border:none;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'>fillLayout.type =
+ SWT.VERTICAL<o:p></o:p></b></p>
+ </td>
+ <td width=222 valign=top style='width:166.5pt;border:none;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1067" type="#_x0000_t75" style='width:67.5pt;height:66pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image011.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=90 height=88
+ src="./Understanding%20Layouts_files/image012.jpg" v:shapes="_x0000_i1067"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ <td width=223 valign=top style='width:167.4pt;border:none;mso-border-top-alt:
+ solid black .75pt;mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1068" type="#_x0000_t75" style='width:137.25pt;height:66.75pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image013.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=183 height=89
+ src="./Understanding%20Layouts_files/image014.jpg" v:shapes="_x0000_i1068"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+</table>
+
+<span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h2 style='margin-left:17.0pt'><a name="_Toc509864528">RowLayout</a></h2>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><i
+style='mso-bidi-font-style:normal'>RowLayout</i> is more commonly used than <i
+style='mso-bidi-font-style:normal'>FillLayout</i> because of its ability to
+wrap, and because it provides configurable margins and spacing. <i
+style='mso-bidi-font-style:normal'>RowLayout</i> has a number of configuration
+fields. In addition, the height and width of each widget in a <i
+style='mso-bidi-font-style:normal'>RowLayout</i> can be specified by setting a <i
+style='mso-bidi-font-style:normal'>RowData</i> object into the widget using <b
+style='mso-bidi-font-weight:normal'>setLayoutData</b>.</p>
+
+<h3 style='margin-left:17.0pt'><a name="_Toc509864529">RowLayout Configuration
+Fields</a></h3>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864530">Wrap</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The <b style='mso-bidi-font-weight:
+normal'>wrap</b> field controls whether or not the <i style='mso-bidi-font-style:
+normal'>RowLayout</i> will wrap widgets into the next row if there isn’t enough
+space in the current row. <i style='mso-bidi-font-style:normal'>RowLayouts</i>
+wrap by default.</p>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864531">Pack</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>If the <b style='mso-bidi-font-weight:
+normal'>pack</b> field is true, widgets in a <i style='mso-bidi-font-style:
+normal'>RowLayout</i> will take their natural size, and they will be aligned as
+far to the left as possible. If packing is false, widgets will fill the
+available space, similar to the widgets in a <i style='mso-bidi-font-style:
+normal'>FillLayout</i>. <i style='mso-bidi-font-style:normal'>RowLayouts</i>
+pack by default.</p>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864532">Justify</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>If the <b style='mso-bidi-font-weight:
+normal'>justify</b> field is true, widgets in a <i style='mso-bidi-font-style:
+normal'>RowLayout</i> are spread across the available space from left to right.
+If the parent <i style='mso-bidi-font-style:normal'>Composite</i> grows wider, the
+extra space is distributed evenly among the widgets. If both <b
+style='mso-bidi-font-weight:normal'>pack</b> and <b style='mso-bidi-font-weight:
+normal'>justify</b> are true, widgets take their natural size, and the extra
+space is placed between the widgets in order to keep them fully justified. By
+default, <i style='mso-bidi-font-style:normal'>RowLayouts</i> do not justify.</p>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864533">MarginLeft, MarginTop,
+MarginRight, MarginBottom and Spacing</a></h4>
+
+<p class=MsoHeader style='margin-left:17.0pt;tab-stops:.5in center 3.0in right 6.0in'>These
+fields control the number of pixels between widgets (<b style='mso-bidi-font-weight:
+normal'>spacing</b>) and the number of pixels between a widget and the side of
+the parent <i style='mso-bidi-font-style:normal'>Composite</i> (<b
+style='mso-bidi-font-weight:normal'>margin</b>). By default, <i
+style='mso-bidi-font-style:normal'>RowLayouts</i> leave 3 pixels for margin and
+spacing. The margin and spacing fields are shown in the following diagram.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1069" type="#_x0000_t75" style='width:247.5pt;height:79.5pt'
+ o:ole="" fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image015.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=330 height=106
+src="./Understanding%20Layouts_files/image016.jpg" v:shapes="_x0000_i1069"><![endif]><!--[if gte mso 9]><xml>
+ <o:OLEObject Type="Embed" ProgID="PBrush" ShapeID="_x0000_i1069"
+ DrawAspect="Content" ObjectID="_1053162910">
+ </o:OLEObject>
+</xml><![endif]--></p>
+
+<span style='font-size:14.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h3 style='margin-left:17.0pt'><a name="_Toc509864534">RowLayout Examples</a></h3>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>The following
+example code creates a <i style='mso-bidi-font-style:normal'>RowLayout</i>,
+sets all of its fields to non-default values, and then sets it into a <i
+style='mso-bidi-font-style:normal'>Shell</i>. </p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>RowLayout
+rowLayout = <span style='color:navy'>new</span> RowLayout();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>rowLayout.wrap
+= false;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>rowLayout.pack
+= false;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>rowLayout.justify
+= true;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>rowLayout.marginLeft
+= 5;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>rowLayout.marginTop
+= 5;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>rowLayout.marginRight
+= 5;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>rowLayout.marginBottom
+= 5;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>rowLayout.spacing
+= 0;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>shell.setLayout(rowLayout);</p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>If you are using
+the default field values, you only need one line of code:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>shell.setLayout(<span
+style='color:navy'>new</span> RowLayout());</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>In the table below,
+the result of setting specific fields is shown.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<table border=0 cellspacing=0 cellpadding=0 style='margin-left:17.0pt;
+ border-collapse:collapse;mso-padding-alt:0in 5.4pt 0in 5.4pt'>
+ <tr>
+ <td width=127 valign=top style='width:95.4pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><b
+ style='mso-bidi-font-weight:normal'><o:p></o:p></b></p>
+ </td>
+ <td width=240 valign=top style='width:2.5in;border-top:none;border-left:none;
+ border-bottom:solid black .75pt;border-right:solid black .75pt;mso-border-left-alt:
+ solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <h5>Initial</h5>
+ </td>
+ <td width=223 valign=top style='width:167.4pt;border:none;border-bottom:solid black .75pt;
+ mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <h5>After resize</h5>
+ </td>
+ </tr>
+ <tr>
+ <td width=127 valign=top style='width:95.4pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'>wrap = true<o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'>pack = true<o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'>justify = false<o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><span style='font-size:10.0pt;font-family:"Times New Roman"'>(defaults)<o:p></o:p></span></p>
+ </td>
+ <td width=240 valign=top style='width:2.5in;border-top:none;border-left:none;
+ border-bottom:solid black .75pt;border-right:solid black .75pt;mso-border-top-alt:
+ solid black .75pt;mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1070" type="#_x0000_t75" style='width:130.5pt;height:39.75pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image017.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=174 height=53
+ src="./Understanding%20Layouts_files/image018.jpg" v:shapes="_x0000_i1070"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ <td width=223 valign=top style='width:167.4pt;border:none;border-bottom:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1071" type="#_x0000_t75" style='width:106.5pt;height:56.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image019.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=142 height=75
+ src="./Understanding%20Layouts_files/image020.jpg" v:shapes="_x0000_i1071"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=127 valign=top style='width:95.4pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'>wrap = false<o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><span style='font-size:10.0pt;font-family:"Times New Roman"'>(clips
+ if not enough space)<o:p></o:p></span></p>
+ </td>
+ <td width=240 valign=top style='width:2.5in;border-top:none;border-left:none;
+ border-bottom:solid black .75pt;border-right:solid black .75pt;mso-border-top-alt:
+ solid black .75pt;mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1072" type="#_x0000_t75" style='width:130.5pt;height:39.75pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image017.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=174 height=53
+ src="./Understanding%20Layouts_files/image021.jpg" v:shapes="_x0000_i1072"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ <td width=223 valign=top style='width:167.4pt;border:none;border-bottom:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1073" type="#_x0000_t75" style='width:106.5pt;height:56.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image022.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=142 height=75
+ src="./Understanding%20Layouts_files/image023.jpg" v:shapes="_x0000_i1073"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=127 valign=top style='width:95.4pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'>pack = false<o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><span style='font-size:10.0pt;font-family:"Times New Roman"'>(all
+ widgets are the same size)<o:p></o:p></span></p>
+ </td>
+ <td width=240 valign=top style='width:2.5in;border-top:none;border-left:none;
+ border-bottom:solid black .75pt;border-right:solid black .75pt;mso-border-top-alt:
+ solid black .75pt;mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1074" type="#_x0000_t75" style='width:168.75pt;height:35.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image024.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=225 height=47
+ src="./Understanding%20Layouts_files/image025.jpg" v:shapes="_x0000_i1074"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ <td width=223 valign=top style='width:167.4pt;border:none;border-bottom:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1075" type="#_x0000_t75" style='width:148.5pt;height:56.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image026.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=198 height=75
+ src="./Understanding%20Layouts_files/image027.jpg" v:shapes="_x0000_i1075"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=127 valign=top style='width:95.4pt;border:none;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'>justify = true<o:p></o:p></b></p>
+ <p class=Code><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=Code><span style='font-size:10.0pt;font-family:"Times New Roman"'>(widgets
+ are spread across the available space)<o:p></o:p></span></p>
+ </td>
+ <td width=240 valign=top style='width:2.5in;border:none;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1076" type="#_x0000_t75" style='width:130.5pt;height:39.75pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image028.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=174 height=53
+ src="./Understanding%20Layouts_files/image029.jpg" v:shapes="_x0000_i1076"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ <td width=223 valign=top style='width:167.4pt;border:none;mso-border-top-alt:
+ solid black .75pt;mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1077" type="#_x0000_t75" style='width:156.75pt;height:38.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image030.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=209 height=51
+ src="./Understanding%20Layouts_files/image031.jpg" v:shapes="_x0000_i1077"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+</table>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<span style='font-size:14.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h3 style='margin-left:17.0pt'><a name="_Toc509864535">Using RowData Objects
+with RowLayout</a></h3>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Each widget controlled by a <i
+style='mso-bidi-font-style:normal'>RowLayout</i> can have its initial width and
+height specified by setting a <i style='mso-bidi-font-style:normal'>RowData</i>
+object into the widget. The following code uses <i style='mso-bidi-font-style:
+normal'>RowData</i> objects to change the initial size of the <i
+style='mso-bidi-font-style:normal'>Buttons</i> in a <i style='mso-bidi-font-style:
+normal'>Shell</i>.</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span>
+org.eclipse.swt.*;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span>
+org.eclipse.swt.widgets.*;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span>
+org.eclipse.swt.layout.*;</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>public</span>
+<span style='color:navy'>class</span> RowDataExample {</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>public</span> <span style='color:navy'>static</span> <span
+style='color:navy'>void</span> main(String[] args) {</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Display
+display = <span style='color:navy'>new</span> Display();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Shell
+shell = <span style='color:navy'>new</span> Shell(display);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>shell.setLayout(<span
+style='color:navy'>new</span> RowLayout());</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Button
+button1 = <span style='color:navy'>new</span> Button(shell, SWT.PUSH);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button1.setText(<span
+style='color:teal'>&quot;Button 1&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button1.setLayoutData(<span
+style='color:navy'>new</span> RowData(50, 40));</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Button
+button2 = <span style='color:navy'>new</span> Button(shell, SWT.PUSH);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button2.setText(<span
+style='color:teal'>&quot;Button 2&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button2.setLayoutData(<span
+style='color:navy'>new</span> RowData(50, 30));</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Button
+button3 = <span style='color:navy'>new</span> Button(shell, SWT.PUSH);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button3.setText(<span
+style='color:teal'>&quot;Button 3&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button3.setLayoutData(<span
+style='color:navy'>new</span> RowData(50, 20));</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>shell.pack();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>shell.open();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>while</span> (!shell.isDisposed()) {</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:3'>          </span><span
+style='color:navy'>if</span> (!display.readAndDispatch()) display.sleep();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>}</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:1'>    </span>}</p>
+
+<p class=Code style='margin-left:17.0pt'>}</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Here is what you see when you run
+the above code.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1078" type="#_x0000_t75" style='width:129.75pt;height:54.75pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image032.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=173 height=73
+src="./Understanding%20Layouts_files/image033.jpg" v:shapes="_x0000_i1078"><![endif]></p>
+
+<span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h2 style='margin-left:17.0pt'><a name="_Toc509864536">GridLayout</a></h2>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><i
+style='mso-bidi-font-style:normal'>GridLayout</i> is the most useful and
+powerful of the standard layouts, but it is also the most complicated. With a <i
+style='mso-bidi-font-style:normal'>GridLayout</i>, the widget children of a <i
+style='mso-bidi-font-style:normal'>Composite</i> are laid out in a grid. <i
+style='mso-bidi-font-style:normal'>GridLayout</i> has a number of configuration
+fields, and, like <i style='mso-bidi-font-style:normal'>RowLayout</i>, the
+widgets it lays out can have an associated layout data object, called <i
+style='mso-bidi-font-style:normal'>GridData</i>. The power of <i
+style='mso-bidi-font-style:normal'>GridLayout</i> lies in the ability to
+configure <i style='mso-bidi-font-style:normal'>GridData</i> for each widget
+controlled by the <i style='mso-bidi-font-style:normal'>GridLayout</i>.</p>
+
+<h3 style='margin-left:17.0pt'><a name="_Toc509864537">GridLayout Configuration
+Fields</a></h3>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864538">NumColumns</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The <b style='mso-bidi-font-weight:
+normal'>numColumns</b> field is the most important field in a <i
+style='mso-bidi-font-style:normal'>GridLayout</i>, and it is usually the first
+field an application will set. Widgets are laid out in columns from left to
+right, and a new row is created when <b style='mso-bidi-font-weight:normal'>numColumns</b>
++ 1 widgets are added to the <i style='mso-bidi-font-style:normal'>Composite</i>.
+The default is to have only 1 column. The following code creates a <i
+style='mso-bidi-font-style:normal'>Shell</i> with five <i style='mso-bidi-font-style:
+normal'>Button</i> children of various widths, managed by a <i
+style='mso-bidi-font-style:normal'>GridLayout</i>. The table below shows the
+grid when <b style='mso-bidi-font-weight:normal'>numColumns</b> is set to 1, 2,
+or 3.</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Display
+display = <span style='color:navy'>new</span> Display();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Shell
+shell = <span style='color:navy'>new</span> Shell(display);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>GridLayout
+gridLayout = <span style='color:navy'>new</span> GridLayout();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>gridLayout.numColumns
+= 3;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>shell.setLayout(gridLayout);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>new</span> Button(shell, SWT.PUSH).setText(<span
+style='color:teal'>&quot;B1&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>new</span> Button(shell, SWT.PUSH).setText(<span
+style='color:teal'>&quot;Wide Button 2&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>new</span> Button(shell, SWT.PUSH).setText(<span
+style='color:teal'>&quot;Button 3&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>new</span> Button(shell, SWT.PUSH).setText(<span
+style='color:teal'>&quot;B4&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>new</span> Button(shell, SWT.PUSH).setText(<span
+style='color:teal'>&quot;Button 5&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>shell.pack();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>shell.open();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>while</span> (!shell.isDisposed()) {</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:3'>          </span><span
+style='color:navy'>if</span> (!display.readAndDispatch()) display.sleep();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>}</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<table border=0 cellspacing=0 cellpadding=0 style='margin-left:17.0pt;
+ border-collapse:collapse;mso-padding-alt:0in 5.4pt 0in 5.4pt'>
+ <tr>
+ <td width=197 valign=top style='width:2.05in;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><b
+ style='mso-bidi-font-weight:normal'>numColumns = 1<o:p></o:p></b></p>
+ </td>
+ <td width=197 valign=top style='width:2.05in;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><b
+ style='mso-bidi-font-weight:normal'>numColumns = 2<o:p></o:p></b></p>
+ </td>
+ <td width=197 valign=top style='width:2.05in;border:none;border-bottom:solid black .75pt;
+ mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><b
+ style='mso-bidi-font-weight:normal'>numColumns = 3<o:p></o:p></b></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=197 valign=top style='width:2.05in;border:none;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><b
+ style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=MsoNormal align=center style='text-align:center'><b
+ style='mso-bidi-font-weight:normal'><!--[if gte vml 1]><v:shape id="_x0000_i1079"
+ type="#_x0000_t75" style='width:84pt;height:117.75pt' fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image034.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=112 height=157
+ src="./Understanding%20Layouts_files/image035.jpg" v:shapes="_x0000_i1079"><![endif]><o:p></o:p></b></p>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><b
+ style='mso-bidi-font-weight:normal'><o:p></o:p></b></p>
+ </td>
+ <td width=197 valign=top style='width:2.05in;border:none;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1080" type="#_x0000_t75" style='width:113.25pt;height:80.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image036.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=151 height=107
+ src="./Understanding%20Layouts_files/image037.jpg" v:shapes="_x0000_i1080"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ <td width=197 valign=top style='width:2.05in;border:none;mso-border-top-alt:
+ solid black .75pt;mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1081" type="#_x0000_t75" style='width:134.25pt;height:61.5pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image038.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=179 height=82
+ src="./Understanding%20Layouts_files/image039.jpg" v:shapes="_x0000_i1081"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+</table>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<span style='font-size:12.0pt;mso-bidi-font-size:10.0pt;font-family:"Times New Roman";
+mso-fareast-font-family:"Times New Roman";mso-ansi-language:EN-US;mso-fareast-language:
+EN-US;mso-bidi-language:AR-SA'><br clear=all style='page-break-before:always'>
+</span>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864539">MakeColumnsEqualWidth</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The <b style='mso-bidi-font-weight:
+normal'>makeColumnsEqualWidth</b> field forces the columns to be the same width.
+The default is false. If we change the example above to have 3 columns of equal
+width, this is what we would get (note that in the absence of further
+instruction, widgets are left-justified in their columns):</p>
+
+<p class=MsoHeader style='margin-left:17.0pt;tab-stops:.5in center 3.0in right 6.0in'><!--[if gte vml 1]><o:wrapblock><v:shape
+ id="_x0000_s1053" type="#_x0000_t75" style='position:absolute;left:0;
+ text-align:left;margin-left:76.05pt;margin-top:0;width:249.8pt;height:104.25pt;
+ z-index:1' o:allowincell="f">
+ <v:imagedata src="./Understanding%20Layouts_files/image040.png" o:title=""/>
+ <w:wrap type="topAndBottom" anchorx="page"/>
+ </v:shape><![endif]--><![if !vml]><span style='mso-ignore:vglayout'>
+ <table cellpadding=0 cellspacing=0 align=left>
+ <tr>
+ <td width=101 height=0></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img width=333 height=139
+ src="./Understanding%20Layouts_files/image041.jpg" v:shapes="_x0000_s1053"></td>
+ </tr>
+ </table>
+ </span><![endif]><!--[if gte vml 1]></o:wrapblock><![endif]--><br
+style='mso-ignore:vglayout' clear=ALL>
+<![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<br style='mso-ignore:vglayout' clear=ALL>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864540">MarginWidth,
+MarginHeight, HorizontalSpacing, and VerticalSpacing</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The <b style='mso-bidi-font-weight:
+normal'>margin</b> and <b style='mso-bidi-font-weight:normal'>spacing</b>
+fields in a <i style='mso-bidi-font-style:normal'>GridLayout</i> are similar to
+those in a <i style='mso-bidi-font-style:normal'>RowLayout</i>. The difference
+is that the left and right margins are grouped into <b style='mso-bidi-font-weight:
+normal'>marginWidth</b>, and the top and bottom margins are grouped into <b
+style='mso-bidi-font-weight:normal'>marginHeight</b>. Also, in a <i
+style='mso-bidi-font-style:normal'>GridLayout</i> you can specify <b
+style='mso-bidi-font-weight:normal'>verticalSpacing</b>, whereas in a <i
+style='mso-bidi-font-style:normal'>RowLayout</i>, only <b style='mso-bidi-font-weight:
+normal'>horizontalSpacing</b> applied.</p>
+
+<h3 style='margin-left:17.0pt'><a name="_Toc509864541">GridData Object Fields</a></h3>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><i
+style='mso-bidi-font-style:normal'>GridData</i> is the layout data object
+associated with <i style='mso-bidi-font-style:normal'>GridLayout</i>. To set a <i
+style='mso-bidi-font-style:normal'>GridData</i> object into a widget, you use
+the <b style='mso-bidi-font-weight:normal'>setLayoutData</b> method. For
+example, to set the <i style='mso-bidi-font-style:normal'>GridData</i> for a <i
+style='mso-bidi-font-style:normal'>Button</i>, we could do the following:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Button
+button1 = <span style='color:navy'>new</span> Button(shell, SWT.PUSH);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button1.setText(<span
+style='color:teal'>&quot;B1&quot;</span>);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button1.setLayoutData(<span
+style='color:navy'>new</span> GridData());</p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><span
+style="mso-spacerun: yes"> </span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>Of course, this
+code just creates a <i style='mso-bidi-font-style:normal'>GridData</i> object
+with all of its fields set to their default values, which is the same as not
+setting the layout data at all. There are two ways to create a <i
+style='mso-bidi-font-style:normal'>GridData</i> object with certain fields set.
+The first is to set the fields directly, like this:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>GridData
+gridData = <span style='color:navy'>new</span> GridData();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>gridData.horizontalAlignment
+= GridData.FILL;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>gridData.grabExcessHorizontalSpace
+= true;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button1.setLayoutData(gridData);</p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>The second is to
+take advantage of convenience API – style bits defined by <i style='mso-bidi-font-style:
+normal'>GridData</i>:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button1.setLayoutData(<span
+style='color:navy'>new</span> GridData(GridData.HORIZONTAL_ALIGN_FILL |
+GridData.GRAB_HORIZONTAL));</p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>In fact, certain
+common style bit combinations are provided for further convenience:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button1.setLayoutData(new
+GridData(GridData.FILL_HORIZONTAL));</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Note that FILL_ convenience
+styles set both fill alignment <i style='mso-bidi-font-style:normal'>and</i>
+grab. <i style='mso-bidi-font-style:normal'>GridData</i> style bits can only be
+used for boolean and enumeration fields. Numeric fields must be set directly.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>One final note about <i>GridData</i>
+objects before we get into their fields: do not reuse <i>GridData</i> objects. Every
+widget in a <i>Composite</i> that is managed by a <i>GridLayout</i> must have a
+unique <i>GridData</i> object. If the layout data for a widget in a <i>GridLayout</i>
+is null at layout time, a unique <i>GridData</i> object is created for it.</p>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864542">HorizontalAlignment and
+VerticalAlignment</a> </h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The <b style='mso-bidi-font-weight:
+normal'>alignment</b> fields specify where to place a widget horizontally
+and/or vertically within its grid cell. Each alignment field can have any of
+the following values:</p>
+
+<p class=MsoNormal style='margin-left:71.0pt;text-indent:-.25in;mso-list:l3 level1 lfo4;
+tab-stops:list .75in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>BEGINNING</p>
+
+<p class=MsoNormal style='margin-left:71.0pt;text-indent:-.25in;mso-list:l3 level1 lfo4;
+tab-stops:list .75in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>CENTER</p>
+
+<p class=MsoNormal style='margin-left:71.0pt;text-indent:-.25in;mso-list:l3 level1 lfo4;
+tab-stops:list .75in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>END</p>
+
+<p class=MsoNormal style='margin-left:71.0pt;text-indent:-.25in;mso-list:l3 level1 lfo4;
+tab-stops:list .75in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>FILL</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The default horizontalAlignment
+is BEGINNING (or left-aligned). The default verticalAlignment is CENTER.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Let’s go back to our five-button
+example with three columns, and we will vary the <b style='mso-bidi-font-weight:
+normal'>horizontalAlignment</b> of <span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>Button 5</span>.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<table border=0 cellspacing=0 cellpadding=0 style='margin-left:17.0pt;
+ border-collapse:collapse;mso-padding-alt:0in 5.4pt 0in 5.4pt'>
+ <tr>
+ <td width=319 valign=top style='width:239.4pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=Code>horizontalAlignment = GridData.BEGINNING<b style='mso-bidi-font-weight:
+ normal'><o:p></o:p></b></p>
+ </td>
+ <td width=271 valign=top style='width:203.4pt;border:none;border-bottom:solid black .75pt;
+ mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><b
+ style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+ <p class=MsoNormal align=center style='text-align:center'><b
+ style='mso-bidi-font-weight:normal'><!--[if gte vml 1]><v:shape id="_x0000_i1082"
+ type="#_x0000_t75" style='width:134.25pt;height:61.5pt' fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image042.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=179 height=82
+ src="./Understanding%20Layouts_files/image043.jpg" v:shapes="_x0000_i1082"><![endif]><o:p></o:p></b></p>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><b
+ style='mso-bidi-font-weight:normal'><o:p></o:p></b></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=319 valign=top style='width:239.4pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=Code>horizontalAlignment = GridData.CENTER<b style='mso-bidi-font-weight:
+ normal'><o:p></o:p></b></p>
+ </td>
+ <td width=271 valign=top style='width:203.4pt;border:none;border-bottom:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1083" type="#_x0000_t75" style='width:134.25pt;height:61.5pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image044.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=179 height=82
+ src="./Understanding%20Layouts_files/image045.jpg" v:shapes="_x0000_i1083"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=319 valign=top style='width:239.4pt;border-top:none;border-left:
+ none;border-bottom:solid black .75pt;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=Code>horizontalAlignment = GridData.END<b style='mso-bidi-font-weight:
+ normal'><o:p></o:p></b></p>
+ </td>
+ <td width=271 valign=top style='width:203.4pt;border:none;border-bottom:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;mso-border-left-alt:solid black .75pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1084" type="#_x0000_t75" style='width:134.25pt;height:61.5pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image046.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=179 height=82
+ src="./Understanding%20Layouts_files/image047.jpg" v:shapes="_x0000_i1084"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=319 valign=top style='width:239.4pt;border:none;border-right:solid black .75pt;
+ mso-border-top-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=Code><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=Code>horizontalAlignment = GridData.FILL<b style='mso-bidi-font-weight:
+ normal'><o:p></o:p></b></p>
+ </td>
+ <td width=271 valign=top style='width:203.4pt;border:none;mso-border-top-alt:
+ solid black .75pt;mso-border-left-alt:solid black .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ <p class=MsoNormal align=center style='text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1085" type="#_x0000_t75" style='width:134.25pt;height:61.5pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image048.png" o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=179 height=82
+ src="./Understanding%20Layouts_files/image049.jpg" v:shapes="_x0000_i1085"><![endif]></p>
+ <p class=MsoNormal align=center style='text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+ </td>
+ </tr>
+</table>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864543">HorizontalIndent</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The <b style='mso-bidi-font-weight:
+normal'>horizontalIndent</b> field allows you to move a widget to the right by a
+specified number of pixels. This field is typically only useful when the <b
+style='mso-bidi-font-weight:normal'>horizontalAlignment</b> is BEGINNING. We
+cannot use a style bit to set the indent, so we will indent <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 5 </span>in
+our example by 4 pixels as follows:</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><!--[if gte vml 1]><o:wrapblock><v:shape
+ id="_x0000_s1061" type="#_x0000_t75" style='position:absolute;left:0;
+ text-align:left;margin-left:0;margin-top:0;width:134.25pt;height:61.5pt;
+ z-index:3;mso-wrap-edited:f;mso-position-horizontal:left;
+ mso-position-vertical:top' wrapcoords="-121 0 -121 21337 21600 21337 21600 0 -121 0">
+ <v:imagedata src="./Understanding%20Layouts_files/image050.png" o:title=""/>
+ <w:wrap type="topAndBottom" anchorx="page"/>
+ </v:shape><![endif]--><![if !vml]><img width=179 height=82
+ src="./Understanding%20Layouts_files/image051.jpg" v:shapes="_x0000_s1061"><![endif]><!--[if gte vml 1]></o:wrapblock><![endif]--><br
+style='mso-ignore:vglayout' clear=ALL>
+<![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<br style='mso-ignore:vglayout' clear=ALL>
+
+<p class=Code style='margin-left:17.0pt'>GridData gridData = <span
+style='color:navy'>new</span> GridData();</p>
+
+<p class=Code style='margin-left:17.0pt'>gridData.horizontalIndent = 4;</p>
+
+<p class=Code style='margin-left:17.0pt'>button5.setLayoutData(gridData);</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864544">HorizontalSpan and
+VerticalSpan</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The <b style='mso-bidi-font-weight:
+normal'>span</b> fields let widgets occupy more than one grid cell. They are
+often used in conjunction with FILL alignment. We can make <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 5</span> in
+our example span the last two cells as follows:</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><!--[if gte vml 1]><o:wrapblock><v:shape
+ id="_x0000_s1060" type="#_x0000_t75" style='position:absolute;left:0;
+ text-align:left;margin-left:0;margin-top:0;width:134.25pt;height:61.5pt;
+ z-index:2;mso-wrap-edited:f;mso-position-horizontal:left;
+ mso-position-vertical:top' wrapcoords="-121 0 -121 21337 21600 21337 21600 0 -121 0"
+ o:allowoverlap="f">
+ <v:imagedata src="./Understanding%20Layouts_files/image052.png" o:title=""/>
+ <w:wrap type="topAndBottom" anchorx="page"/>
+ </v:shape><![endif]--><![if !vml]><img width=179 height=82
+ src="./Understanding%20Layouts_files/image053.jpg" v:shapes="_x0000_s1060"><![endif]><!--[if gte vml 1]></o:wrapblock><![endif]--><br
+style='mso-ignore:vglayout' clear=ALL>
+<![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<br style='mso-ignore:vglayout' clear=ALL>
+
+<p class=Code style='margin-left:17.0pt'>GridData gridData = <span
+style='color:navy'>new</span> GridData();</p>
+
+<p class=Code style='margin-left:17.0pt'>gridData.horizontalAlignment =
+GridData.FILL;<span style='font-size:10.0pt'> </span></p>
+
+<p class=Code style='margin-left:17.0pt'>gridData.horizontalSpan = 2;</p>
+
+<p class=Code style='margin-left:17.0pt'>button5.setLayoutData(gridData);</p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>If we decide to make <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Wide Button 2</span>
+span two cells instead, we would end up with this:</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><!--[if gte vml 1]><o:wrapblock><v:shape
+ id="_x0000_s1062" type="#_x0000_t75" style='position:absolute;left:0;
+ text-align:left;margin-left:5.55pt;margin-top:0;width:113.25pt;height:61.5pt;
+ z-index:4;mso-position-horizontal:absolute;mso-position-vertical:top'>
+ <v:imagedata src="./Understanding%20Layouts_files/image054.png" o:title=""/>
+ <w:wrap type="topAndBottom" anchorx="page"/>
+ </v:shape><![endif]--><![if !vml]><span style='mso-ignore:vglayout'>
+ <table cellpadding=0 cellspacing=0 align=left>
+ <tr>
+ <td width=7 height=0></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img width=151 height=82
+ src="./Understanding%20Layouts_files/image055.jpg" v:shapes="_x0000_s1062"></td>
+ </tr>
+ </table>
+ </span><![endif]><!--[if gte vml 1]></o:wrapblock><![endif]--><br
+style='mso-ignore:vglayout' clear=ALL>
+<![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<br style='mso-ignore:vglayout' clear=ALL>
+
+<p class=Code style='margin-left:17.0pt'>GridData gridData = <span
+style='color:navy'>new</span> GridData();</p>
+
+<p class=Code style='margin-left:17.0pt'>gridData.horizontalAlignment =
+GridData.FILL;</p>
+
+<p class=Code style='margin-left:17.0pt'>gridData.horizontalSpan = 2;</p>
+
+<p class=Code style='margin-left:17.0pt'>button2.setLayoutData(gridData);</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Or we could make <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 3</span>
+span two cells vertically:</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><!--[if gte vml 1]><o:wrapblock><v:shape
+ id="_x0000_s1063" type="#_x0000_t75" style='position:absolute;left:0;
+ text-align:left;margin-left:0;margin-top:0;width:134.25pt;height:61.5pt;
+ z-index:5;mso-position-horizontal:left;mso-position-vertical:top'>
+ <v:imagedata src="./Understanding%20Layouts_files/image056.png" o:title=""/>
+ <w:wrap type="topAndBottom" anchorx="page"/>
+ </v:shape><![endif]--><![if !vml]><img width=179 height=82
+ src="./Understanding%20Layouts_files/image057.jpg" v:shapes="_x0000_s1063"><![endif]><!--[if gte vml 1]></o:wrapblock><![endif]--><br
+style='mso-ignore:vglayout' clear=ALL>
+<![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<br style='mso-ignore:vglayout' clear=ALL>
+
+<p class=Code style='margin-left:17.0pt'>GridData gridData = <span
+style='color:navy'>new</span> GridData();</p>
+
+<p class=Code style='margin-left:17.0pt'>gridData.verticalAlignment =
+GridData.FILL;</p>
+
+<p class=Code style='margin-left:17.0pt'>gridData.verticalSpan = 2;</p>
+
+<p class=Code style='margin-left:17.0pt'>button3.setLayoutData(gridData);</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864545">GrabExcessHorizontalSpace
+and GrabExcessVerticalSpace</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The <b style='mso-bidi-font-weight:
+normal'>grabExcessHorizontalSpace</b> and <b style='mso-bidi-font-weight:normal'>grabExcessVerticalSpace</b>
+fields are typically used for larger widgets such as <i style='mso-bidi-font-style:
+normal'>Texts</i> or <i style='mso-bidi-font-style:normal'>Lists</i> to allow
+them to grow if their containing <i style='mso-bidi-font-style:normal'>Composite</i>
+grows. If a <i style='mso-bidi-font-style:normal'>Text</i> is grabbing excess
+horizontal space and the user resizes the <i style='mso-bidi-font-style:normal'>Shell</i>
+wider, then the <i style='mso-bidi-font-style:normal'>Text</i> will get all of the
+new horizontal space and other widgets in the same row will stay their original
+width. Of course, the widget that is grabbing excess space is also the first
+one to shrink when the <i style='mso-bidi-font-style:normal'>Shell</i> gets
+smaller. It is easiest to always think of the <b style='mso-bidi-font-weight:
+normal'>grabExcessSpace</b> fields in the context of resizing. For a simple
+example, let’s reuse the previous example where <span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>Button 3</span> spanned two cells vertically. Here it is
+again:</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1086" type="#_x0000_t75" style='width:134.25pt;height:61.5pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image056.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=179 height=82
+src="./Understanding%20Layouts_files/image058.jpg" v:shapes="_x0000_i1086"><![endif]></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>If we resize this window, the
+only thing that happens is the window gets bigger:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1087" type="#_x0000_t75" style='width:151.5pt;height:84pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image059.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=202 height=112
+src="./Understanding%20Layouts_files/image060.jpg" v:shapes="_x0000_i1087"><![endif]></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Now we will tell <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 3 </span>to
+grab excess horizontal and vertical space, and <span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>B1</span> and <span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>B4</span> to fill vertically (without grabbing), and we
+resize the window again:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1088" type="#_x0000_t75" style='width:178.5pt;height:87pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image061.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=238 height=116
+src="./Understanding%20Layouts_files/image062.jpg" v:shapes="_x0000_i1088"><![endif]></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>This time, <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 3 </span>grew
+in both directions, and <span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";layout-grid-mode:
+line'>B4</span> grew vertically. The other buttons stayed their original sizes.
+Because <span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button
+3</span> was grabbing vertically and it spans two rows, the <i
+style='mso-bidi-font-style:normal'>last</i> row that it spans grew taller. Note
+that <span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>B1</span> did not
+grow – although it is filling vertically – because its row did not grow. Since <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 3</span>
+was grabbing horizontally, its column grew wider, and since it was filling
+horizontally, it grew wider to fill the column. Here is the code for all five
+buttons:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>Button button1 = </span><span
+style='color:navy'>new</span><span style='color:black'> Button(shell,
+SWT.PUSH);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>button1.setText(</span><span
+style='color:teal'>&quot;B1&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>GridData gridData = </span><span
+style='color:navy'>new</span><span style='color:black'> GridData();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.verticalAlignment =
+GridData.FILL;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>button1.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:navy'>new</span><span
+style='color:black'> Button(shell, SWT.PUSH).setText(</span><span
+style='color:teal'>&quot;Wide Button 2&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>Button button3 = </span><span
+style='color:navy'>new</span><span style='color:black'> Button(shell,
+SWT.PUSH);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>button3.setText(</span><span
+style='color:teal'>&quot;Button 3&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData = </span><span style='color:
+navy'>new</span><span style='color:black'> GridData();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.verticalAlignment =
+GridData.FILL;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.verticalSpan = 2;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.grabExcessVerticalSpace = </span><span
+style='color:navy'>true</span><span style='color:black'>;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.horizontalAlignment =
+GridData.FILL;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.grabExcessHorizontalSpace = </span><span
+style='color:navy'>true</span><span style='color:black'>;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>button3.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>Button button4 = </span><span
+style='color:navy'>new</span><span style='color:black'> Button(shell,
+SWT.PUSH);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>button4.setText(</span><span
+style='color:teal'>&quot;B4&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData = </span><span style='color:
+navy'>new</span><span style='color:black'> GridData();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.verticalAlignment =
+GridData.FILL;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>button4.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:navy'>new</span><span
+style='color:black'> Button(shell, SWT.PUSH).setText(</span><span
+style='color:teal'>&quot;Button 5&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>In a typical application window,
+you often want to have at least one widget that is grabbing. If more than one
+widget is trying to grab the same space, then the excess space is shared evenly
+among the grabbing widgets:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1089" type="#_x0000_t75" style='width:84pt;height:42.75pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image063.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=112 height=57
+src="./Understanding%20Layouts_files/image064.jpg" v:shapes="_x0000_i1089"><![endif]><span
+style='mso-tab-count:1'>  </span><!--[if gte vml 1]><v:shape id="_x0000_i1090"
+ type="#_x0000_t75" style='width:184.5pt;height:42.75pt' fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image065.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=246 height=57
+src="./Understanding%20Layouts_files/image066.jpg" v:shapes="_x0000_i1090"><![endif]></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>One final point to note about
+grabbing. If a widget is grabbing excess horizontal space and its parent <i
+style='mso-bidi-font-style:normal'>Composite</i> grows wider, then the entire <i
+style='mso-bidi-font-style:normal'>column</i> containing that widget grows
+wider. If a widget is grabbing excess vertical space and its parent <i
+style='mso-bidi-font-style:normal'>Composite</i> grows taller, then the entire <i
+style='mso-bidi-font-style:normal'>row</i> containing that widget grows taller.
+The implication of this is that if any other widget in the affected column or
+row has <i style='mso-bidi-font-style:normal'>fill</i> alignment, then it will
+stretch also. Widgets that have beginning, center, or end alignment will not
+stretch – they will stay at the beginning, center or end of the wider column or
+taller row.</p>
+
+<h4 style='margin-left:17.0pt'><a name="_Toc509864546">WidthHint and HeightHint</a></h4>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The <b style='mso-bidi-font-weight:
+normal'>widthHint</b> and <b style='mso-bidi-font-weight:normal'>heightHint</b>
+fields indicate the number of pixels wide or tall that you would like a widget
+to be, if it does not conflict with other requirements in the <i
+style='mso-bidi-font-style:normal'>GridLayout</i>’s constraint system. Looking
+back at the five-button, three-column example, say we want <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 5</span>
+to be 70 pixels wide and 40 pixels tall. We code it as follows:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>GridData
+gridData = <span style='color:navy'>new</span> GridData();</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>gridData.widthHint
+= 70;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>gridData.heightHint
+= 40;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>button5.setLayoutData(gridData);</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>The natural size of <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 5</span>
+is shown in the window on the left, below, and the 70-pixel wide, 40-pixel tall
+<span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 5</span>
+is on the right.</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1091" type="#_x0000_t75" style='width:134.25pt;height:61.5pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image038.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=179 height=82
+src="./Understanding%20Layouts_files/image067.jpg" v:shapes="_x0000_i1091"><![endif]><span
+style='mso-tab-count:2'>                      </span><!--[if gte vml 1]><v:shape
+ id="_x0000_i1092" type="#_x0000_t75" style='width:134.25pt;height:76.5pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image068.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=179 height=102
+src="./Understanding%20Layouts_files/image069.jpg" v:shapes="_x0000_i1092"><![endif]></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>Note, however, that
+if the <b style='mso-bidi-font-weight:normal'>horizontalAlignment</b> of <span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Button 5</span>
+was FILL, then the <i style='mso-bidi-font-style:normal'>GridLayout</i> would
+not have been able to honor the request for a width of 70 pixels.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'>One final comment
+about using width and height hints. Something that looks good on one platform
+may not look good on another. The variation between font sizes and natural widget
+sizes across platforms means that hard-coding pixel values is not usually the
+best way to lay out windows. So, keep the use of size hints to a minimum, if
+you use them at all.</p>
+
+<span style='font-size:14.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h3 style='margin-left:17.0pt'><a name="_Toc509864547">A Complex GridLayout
+Example</a></h3>
+
+<p class=MsoNormal style='margin-left:17.0pt'>So far, the <i style='mso-bidi-font-style:
+normal'>GridLayout</i> examples have been fairly simple, in order to show how
+each field works. Now, we will put them all together to create a more
+complicated example. We start by hand-drawing a rough sketch of the window we
+want to create, to determine things like how many columns the grid should contain,
+and whether or not any widgets need to span.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style="mso-spacerun:
+yes">   </span><!--[if gte vml 1]><v:shape id="_x0000_i1093" type="#_x0000_t75"
+ style='width:386.25pt;height:271.5pt' o:ole="" fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image070.gif" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=515 height=362
+src="./Understanding%20Layouts_files/image070.gif" v:shapes="_x0000_i1093"><![endif]><!--[if gte mso 9]><xml>
+ <o:OLEObject Type="Embed" ProgID="PBrush" ShapeID="_x0000_i1093"
+ DrawAspect="Content" ObjectID="_1053162911">
+ </o:OLEObject>
+</xml><![endif]--></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Then we start coding the example
+from the diagram. The code is below. Note that we have added a bit of logic to
+make the code more interesting, for example, <span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>Browse…</span> opens a <i style='mso-bidi-font-style:
+normal'>FileDialog</i> to read an <i style='mso-bidi-font-style:normal'>Image</i>
+file which the <i style='mso-bidi-font-style:normal'>Canvas</i> displays in a
+paint listener, <span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";layout-grid-mode:
+line'>Delete</span> deletes the <i style='mso-bidi-font-style:normal'>Image</i>,
+and <span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>Enter</span>
+prints the current dog and owner info. The example has been coded in a single <b
+style='mso-bidi-font-weight:normal'>main</b> method to keep it as simple as
+possible.</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span><span
+style='color:black'> org.eclipse.swt.*;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span><span
+style='color:black'> org.eclipse.swt.widgets.*;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span><span
+style='color:black'> org.eclipse.swt.layout.*;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span><span
+style='color:black'> org.eclipse.swt.events.*;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>import</span><span
+style='color:black'> org.eclipse.swt.graphics.*;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:navy'>public</span><span
+style='color:black'> </span><span style='color:navy'>class</span><span
+style='color:black'> ComplexGridLayoutExample {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>static</span><span
+style='color:black'> Display display;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>static</span><span
+style='color:black'> Shell shell;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>static</span><span
+style='color:black'> Text dogName;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>static</span><span
+style='color:black'> Combo dogBreed;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>static</span><span
+style='color:black'> Canvas dogPhoto;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>static</span><span
+style='color:black'> Image dogImage;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>static</span><span
+style='color:black'> List categories;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>static</span><span
+style='color:black'> Text ownerName;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>static</span><span
+style='color:black'> Text ownerPhone;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span></span><span style='color:navy'>public</span><span
+style='color:black'> </span><span style='color:navy'>static</span><span
+style='color:black'> </span><span style='color:navy'>void</span><span
+style='color:black'> main(String[] args) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>display = </span><span style='color:navy'>new</span><span
+style='color:black'> Display();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>shell = </span><span style='color:navy'>new</span><span
+style='color:black'> Shell(display);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>shell.setText(</span><span
+style='color:teal'>&quot;Dog Show Entry&quot;</span><span style='color:black'>);</span><span
+style='color:teal'><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>GridLayout gridLayout = </span><span
+style='color:navy'>new</span><span style='color:black'> GridLayout();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridLayout.numColumns = 3;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>shell.setLayout(gridLayout);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:navy'>new</span><span
+style='color:black'> Label(shell, SWT.NULL).setText(</span><span
+style='color:teal'>&quot;Dog's Name:&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>dogName = </span><span style='color:navy'>new</span><span
+style='color:black'> Text(shell, SWT.SINGLE | SWT.BORDER);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>GridData gridData = </span><span
+style='color:navy'>new</span><span style='color:black'>
+GridData(GridData.HORIZONTAL_ALIGN_FILL);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.horizontalSpan = 2;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>dogName.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:navy'>new</span><span
+style='color:black'> Label(shell, SWT.NULL).setText(</span><span
+style='color:teal'>&quot;Breed:&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>dogBreed = </span><span style='color:
+navy'>new</span><span style='color:black'> Combo(shell, SWT.NULL);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>dogBreed.setItems(</span><span
+style='color:navy'>new</span><span style='color:black'> String [] {</span><span
+style='color:teal'>&quot;Collie&quot;</span><span style='color:black'>, </span><span
+style='color:teal'>&quot;Pitbull&quot;</span><span style='color:black'>, </span><span
+style='color:teal'>&quot;Poodle&quot;</span><span style='color:black'>, </span><span
+style='color:teal'>&quot;Scottie&quot;</span><span style='color:black'>});<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>dogBreed.setLayoutData(</span><span
+style='color:navy'>new</span><span style='color:black'>
+GridData(GridData.HORIZONTAL_ALIGN_FILL));<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>Label label = </span><span
+style='color:navy'>new</span><span style='color:black'> Label(shell, SWT.NULL);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>label.setText(</span><span
+style='color:teal'>&quot;Categories&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>label.setLayoutData(</span><span
+style='color:navy'>new</span><span style='color:black'>
+GridData(GridData.HORIZONTAL_ALIGN_CENTER));<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:navy'>new</span><span
+style='color:black'> Label(shell, SWT.NULL).setText(</span><span
+style='color:teal'>&quot;Photo:&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>dogPhoto = </span><span style='color:
+navy'>new</span><span style='color:black'> Canvas(shell, SWT.BORDER);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData = </span><span style='color:
+navy'>new</span><span style='color:black'> GridData(GridData.FILL_BOTH);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.widthHint = 80;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.heightHint = 80;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.verticalSpan = 3;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>dogPhoto.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>dogPhoto.addPaintListener(</span><span
+style='color:navy'>new</span><span style='color:black'> PaintListener() {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:navy'>public</span><span
+style='color:black'> </span><span style='color:navy'>void</span><span
+style='color:black'> paintControl(</span><span style='color:navy'>final</span><span
+style='color:black'> PaintEvent event) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span></span><span style='color:navy'>if</span><span
+style='color:black'> (dogImage != </span><span style='color:navy'>null</span><span
+style='color:black'>) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:5'>                 </span>event.gc.drawImage(dogImage, 0,
+0);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>});<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>categories = </span><span
+style='color:navy'>new</span><span style='color:black'> List(shell, SWT.MULTI |
+SWT.BORDER | SWT.V_SCROLL);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>categories.setItems(</span><span
+style='color:navy'>new</span><span style='color:black'> String [] {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:teal'>&quot;Best
+of Breed&quot;</span><span style='color:black'>, </span><span style='color:
+teal'>&quot;Prettiest Female&quot;</span><span style='color:black'>, </span><span
+style='color:teal'>&quot;Handsomest Male&quot;</span><span style='color:black'>,<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:teal'>&quot;Best
+Dressed&quot;</span><span style='color:black'>, </span><span style='color:teal'>&quot;Fluffiest
+Ears&quot;</span><span style='color:black'>, </span><span style='color:teal'>&quot;Most
+Colors&quot;</span><span style='color:black'>,<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:teal'>&quot;Best
+Performer&quot;</span><span style='color:black'>, </span><span
+style='color:teal'>&quot;Loudest Bark&quot;</span><span style='color:black'>, </span><span
+style='color:teal'>&quot;Best Behaved&quot;</span><span style='color:black'>,<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:teal'>&quot;Prettiest
+Eyes&quot;</span><span style='color:black'>, </span><span style='color:teal'>&quot;Most
+Hair&quot;</span><span style='color:black'>, </span><span style='color:teal'>&quot;Longest
+Tail&quot;</span><span style='color:black'>,<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:teal'>&quot;Cutest
+Trick&quot;</span><span style='color:black'>});<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData = </span><span style='color:
+navy'>new</span><span style='color:black'>
+GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.verticalSpan = 4;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>int</span> listHeight = categories.getItemHeight() * 12;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>Rectangle
+trim = categories.computeTrim(0, 0, 0, listHeight);</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-tab-count:2'>       </span>gridData.heightHint
+= trim.height;</p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>categories.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>Button browse = </span><span
+style='color:navy'>new</span><span style='color:black'> Button(shell,
+SWT.PUSH);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>browse.setText(</span><span
+style='color:teal'>&quot;Browse...&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData = </span><span style='color:
+navy'>new</span><span style='color:black'> GridData(GridData.HORIZONTAL_ALIGN_FILL);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.horizontalIndent = 5;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>browse.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>browse.addSelectionListener(</span><span
+style='color:navy'>new</span><span style='color:black'> SelectionAdapter() {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:navy'>public</span><span
+style='color:black'> </span><span style='color:navy'>void</span><span
+style='color:black'> widgetSelected(SelectionEvent event) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>String fileName = </span><span
+style='color:navy'>new</span><span style='color:black'>
+FileDialog(shell).open();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span></span><span style='color:navy'>if</span><span
+style='color:black'> (fileName != </span><span style='color:navy'>null</span><span
+style='color:black'>) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:5'>                 </span>dogImage = </span><span
+style='color:navy'>new</span><span style='color:black'> Image(display,
+fileName);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>});<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>Button delete = </span><span
+style='color:navy'>new</span><span style='color:black'> Button(shell,
+SWT.PUSH);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>delete.setText(</span><span
+style='color:teal'>&quot;Delete&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData = </span><span style='color:
+navy'>new</span><span style='color:black'>
+GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.horizontalIndent = 5;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>delete.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>delete.addSelectionListener(</span><span
+style='color:navy'>new</span><span style='color:black'> SelectionAdapter() {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:navy'>public</span><span
+style='color:black'> </span><span style='color:navy'>void</span><span
+style='color:black'> widgetSelected(SelectionEvent event) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span></span><span style='color:navy'>if</span><span
+style='color:black'> (dogImage != </span><span style='color:navy'>null</span><span
+style='color:black'>) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:5'>                 </span>dogImage.dispose();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:5'>                 </span>dogImage = </span><span
+style='color:navy'>null</span><span style='color:black'>;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:5'>                 </span>dogPhoto.redraw();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>});<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>Group ownerInfo = </span><span
+style='color:navy'>new</span><span style='color:black'> Group(shell, SWT.NULL);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>ownerInfo.setText(</span><span
+style='color:teal'>&quot;Owner Info&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridLayout = </span><span
+style='color:navy'>new</span><span style='color:black'> GridLayout();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridLayout.numColumns = 2;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>ownerInfo.setLayout(gridLayout);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData = </span><span style='color:
+navy'>new</span><span style='color:black'> GridData(GridData.HORIZONTAL_ALIGN_FILL);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.horizontalSpan = 2;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>ownerInfo.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:navy'>new</span><span
+style='color:black'> Label(ownerInfo, SWT.NULL).setText(</span><span
+style='color:teal'>&quot;Name:&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>ownerName = </span><span
+style='color:navy'>new</span><span style='color:black'> Text(ownerInfo,
+SWT.SINGLE | SWT.BORDER);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>ownerName.setLayoutData(</span><span
+style='color:navy'>new</span><span style='color:black'> GridData(GridData.FILL_HORIZONTAL));<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:navy'>new</span><span
+style='color:black'> Label(ownerInfo, SWT.NULL).setText(</span><span
+style='color:teal'>&quot;Phone:&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>ownerPhone = </span><span
+style='color:navy'>new</span><span style='color:black'> Text(ownerInfo,
+SWT.SINGLE | SWT.BORDER);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>ownerPhone.setLayoutData(</span><span
+style='color:navy'>new</span><span style='color:black'>
+GridData(GridData.FILL_HORIZONTAL));<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>Button enter = </span><span
+style='color:navy'>new</span><span style='color:black'> Button(shell,
+SWT.PUSH);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>enter.setText(</span><span
+style='color:teal'>&quot;Enter&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData = </span><span style='color:
+navy'>new</span><span style='color:black'>
+GridData(GridData.HORIZONTAL_ALIGN_END);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>gridData.horizontalSpan = 3;<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>enter.setLayoutData(gridData);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>enter.addSelectionListener(</span><span
+style='color:navy'>new</span><span style='color:black'> SelectionAdapter() {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:navy'>public</span><span
+style='color:black'> </span><span style='color:navy'>void</span><span
+style='color:black'> widgetSelected(SelectionEvent event) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>System.out.println(</span><span
+style='color:teal'>&quot;\nDog Name: &quot;</span><span style='color:black'> +
+dogName.getText());<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>System.out.println(</span><span
+style='color:teal'>&quot;Dog Breed: &quot;</span><span style='color:black'> +
+dogBreed.getText());<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>System.out.println(</span><span
+style='color:teal'>&quot;Owner Name: &quot;</span><span style='color:black'> +
+ownerName.getText());<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>System.out.println(</span><span
+style='color:teal'>&quot;Owner Phone: &quot;</span><span style='color:black'> +
+ownerPhone.getText());<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>System.out.println(</span><span
+style='color:teal'>&quot;Categories:&quot;</span><span style='color:black'>);<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>String cats[] =
+categories.getSelection();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span></span><span style='color:navy'>for</span><span
+style='color:black'> (</span><span style='color:navy'>int</span><span
+style='color:black'> i = 0; i &lt; cats.length; i++) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:5'>                 </span>System.out.println(</span><span
+style='color:teal'>&quot;\t&quot;</span><span style='color:black'> + cats[i]);</span><span
+style='color:teal'><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:4'>              </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>});<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>shell.pack();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>shell.open();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:navy'>while</span><span
+style='color:black'> (!shell.isDisposed()) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span></span><span style='color:navy'>if</span><span
+style='color:black'> (!display.readAndDispatch()) display.sleep();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span></span><span style='color:navy'>if</span><span
+style='color:black'> (dogImage != </span><span style='color:navy'>null</span><span
+style='color:black'>) {<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:3'>          </span>dogImage.dispose();<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'><span
+style='mso-tab-count:1'>    </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='color:black'>}<o:p></o:p></span></p>
+
+<span style='font-size:12.0pt;mso-bidi-font-size:10.0pt;font-family:"Times New Roman";
+mso-fareast-font-family:"Times New Roman";mso-ansi-language:EN-US;mso-fareast-language:
+EN-US;mso-bidi-language:AR-SA'><br clear=all style='page-break-before:always'>
+</span>
+
+<p class=MsoNormal style='margin-left:17.0pt'>Here is what the window looks
+like after Mary Smith enters Fifi in the dog show:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoHeader align=center style='margin-left:17.0pt;text-align:center;
+tab-stops:.5in center 3.0in right 6.0in'><!--[if gte vml 1]><v:shape id="_x0000_i1094"
+ type="#_x0000_t75" style='width:210.75pt;height:204.75pt' fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image071.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=281 height=273
+src="./Understanding%20Layouts_files/image072.jpg" v:shapes="_x0000_i1094"><![endif]></p>
+
+<p class=MsoHeader style='margin-left:17.0pt;tab-stops:.5in center 3.0in right 6.0in'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoHeader style='margin-left:17.0pt;tab-stops:.5in center 3.0in right 6.0in'>If
+this window is resized larger, the layout adjusts as follows:</p>
+
+<p class=Code style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoHeader align=center style='margin-left:17.0pt;text-align:center;
+tab-stops:.5in center 3.0in right 6.0in'><!--[if gte vml 1]><v:shape id="_x0000_i1095"
+ type="#_x0000_t75" style='width:247.5pt;height:235.5pt' fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image073.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=330 height=314
+src="./Understanding%20Layouts_files/image074.jpg" v:shapes="_x0000_i1095"><![endif]></p>
+
+<p class=MsoHeader style='margin-left:17.0pt;tab-stops:.5in center 3.0in right 6.0in'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoHeader style='margin-left:17.0pt;tab-stops:.5in center 3.0in right 6.0in'>Notice
+the following:</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>There are 3 columns and 7 rows.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>dogPhoto</b>
+<i style='mso-bidi-font-style:normal'>Canvas</i> grew wider and taller because
+it is filling and grabbing horizontally and vertically (we did not resize the <i
+style='mso-bidi-font-style:normal'>Image</i>, but we could have).</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>dogBreed</b>
+<i style='mso-bidi-font-style:normal'>Combo</i> grew wider because it is
+filling horizontally, and it is in the same column as the <i style='mso-bidi-font-style:
+normal'>Canvas</i>.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>dogName</b> <i
+style='mso-bidi-font-style:normal'>Text</i> grew wider because it is filling
+horizontally, and one of the columns it spans is the column containing the <i
+style='mso-bidi-font-style:normal'>Canvas</i>.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>categories</b>
+<i style='mso-bidi-font-style:normal'>List</i> grew taller because it is
+filling vertically, and it spans the same rows that the <i style='mso-bidi-font-style:
+normal'>Canvas</i> does.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Because the <b style='mso-bidi-font-weight:normal'>categories</b>
+<i style='mso-bidi-font-style:normal'>List</i> grew taller, its vertical
+scrollbar disappeared (it did not grow wider).</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>ownerInfo</b>
+<i style='mso-bidi-font-style:normal'>Group</i> grew wider because it is
+filling horizontally, and one of the columns it spans is the column containing
+the <i style='mso-bidi-font-style:normal'>Canvas</i>.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>ownerInfo</b>
+<i style='mso-bidi-font-style:normal'>Group</i>, as a subclass of <i
+style='mso-bidi-font-style:normal'>Composite</i>, has its own <i
+style='mso-bidi-font-style:normal'>GridLayout</i> with 2 columns and 2 rows.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>ownerName</b>
+and <b style='mso-bidi-font-weight:normal'>ownerPhone</b> <i style='mso-bidi-font-style:
+normal'>Texts</i> grew wider because the <i style='mso-bidi-font-style:normal'>Group</i>
+grew wider, and they are filling and grabbing horizontally in the <i
+style='mso-bidi-font-style:normal'>Group</i>’s <i style='mso-bidi-font-style:
+normal'>GridLayout</i>.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>browse</b>
+and <b style='mso-bidi-font-weight:normal'>delete</b> <i style='mso-bidi-font-style:
+normal'>Buttons</i> are indented slightly, and because they both fill
+horizontally, they are the same width.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>delete</b> <i
+style='mso-bidi-font-style:normal'>Button</i> is vertically aligned at the top
+of its row.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The “Categories” <i style='mso-bidi-font-style:normal'>Label</i>
+is centered over the <b style='mso-bidi-font-weight:normal'>categories</b> <i
+style='mso-bidi-font-style:normal'>List</i>.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>enter</b> <i
+style='mso-bidi-font-style:normal'>Button</i> is horizontally aligned to the
+right of the 3 columns it spans.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>dogPhoto</b>
+<i style='mso-bidi-font-style:normal'>Canvas</i> was created with width and
+height hints because we want the <i style='mso-bidi-font-style:normal'>Image</i>
+to be 80 pixels x 80 pixels, if possible.</p>
+
+<p class=MsoHeader style='margin-left:53.0pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .5in center 3.0in right 6.0in'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>The <b style='mso-bidi-font-weight:normal'>categories</b>
+<i style='mso-bidi-font-style:normal'>List</i> was created with a height hint
+that was based on the <i style='mso-bidi-font-style:normal'>List</i>’s font
+times 12, because we want try to get the <i style='mso-bidi-font-style:normal'>List</i>
+to show 12 items initially.</p>
+
+<span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h2 style='margin-left:17.0pt'><a name="_Toc509864548">Writing Your Own Layout
+Class</a></h2>
+
+<p class=MsoNormal style='margin-left:17.0pt'><a name="_Toc496069428"></a><a
+name="_Toc496069785"><span style='mso-bookmark:_Toc496069428'>Occasionally, you
+may want to write your own <i style='mso-bidi-font-style:normal'>Layout</i>
+class. Perhaps your layout needs are very complex. Maybe you have the same look
+in many places, and you want to take advantage of code reuse. Or you want to
+leverage domain knowledge to create a very efficient layout class. Whatever the
+reason, there are things to consider before writing a new class:</span></a></p>
+
+<p class=MsoNormal style='margin-left:71.0pt;text-indent:-.25in;mso-list:l2 level1 lfo8;
+tab-stops:list .75in'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportLists]><span style='font-family:
+Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Can the layout be done using a <i style='mso-bidi-font-style:
+normal'>GridLayout</i>, with maybe a few nested layouts?</span></span></p>
+
+<p class=MsoNormal style='margin-left:71.0pt;text-indent:-.25in;mso-list:l2 level1 lfo8;
+tab-stops:list .75in'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportLists]><span style='font-family:
+Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Can the desired effect be more easily achieved with a
+resize listener?</span></span></p>
+
+<p class=MsoNormal style='margin-left:71.0pt;text-indent:-.25in;mso-list:l2 level1 lfo8;
+tab-stops:list .75in'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportLists]><span style='font-family:
+Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Are you defining a general layout algorithm or just
+positioning widgets?</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Unless you are writing a very generic <i
+style='mso-bidi-font-style:normal'>Layout</i> type that will be used by several
+<i>Composite</i> widgets, it is often better and easier to simply calculate
+sizes and position children in a resize listener. Many of the SWT custom
+widgets were written this way. Although a new widget can be implemented as a <i
+style='mso-bidi-font-style:normal'>Composite</i>/<i style='mso-bidi-font-style:
+normal'>Layout</i> pair, implementing it as a <i style='mso-bidi-font-style:
+normal'>Composite</i> that does its layout in a resize listener and computes
+its preferred size in <b style='mso-bidi-font-weight:normal'>computeSize</b> is
+clearer, and does not involve writing an extra class.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>First, we will look at how layouts work, and
+then we will create a new <i style='mso-bidi-font-style:normal'>Layout</i>
+class. Another example of writing your own <i style='mso-bidi-font-style:normal'>Layout</i>
+can be found in the <i style='mso-bidi-font-style:normal'>Compound Widget
+Example</i> section of <i style='mso-bidi-font-style:normal'>“Creating Your Own
+Widgets Using SWT”</i>, which shows how to achieve the same look using either a
+resize listener or a new <i style='mso-bidi-font-style:normal'>Layout</i>
+class.</span></span></p>
+
+<h3 style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><a name="_Toc509864549">How Layouts Work</a></span></span></h3>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><i style='mso-bidi-font-style:normal'>Layout</i>
+is the abstract superclass of all layouts. It only has two methods: <b
+style='mso-bidi-font-weight:normal'>computeSize</b> and <b style='mso-bidi-font-weight:
+normal'>layout</b>. The class is defined as follows:</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>public abstract
+class</span><span style='color:black'> Layout {<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>protected abstract</span><span style='color:black'> Point
+computeSize(<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:2'>       </span>Composite composite, </span><span
+style='color:navy'>int</span><span style='color:black'> widthHint, </span><span
+style='color:navy'>int </span><span style='color:black'>heightHint, </span><span
+style='color:navy'>boolean</span><span style='color:black'> flushCache);<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>protected abstract void</span><span style='color:black'>
+layout(Composite composite, </span><span style='color:navy'>boolean</span><span
+style='color:black'> flushCache);<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'>}<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The <b>computeSize</b> method calculates the
+width and height of a rectangle that encloses all of the <i>Composite</i>’s
+children once they have been sized and placed according to the layout algorithm
+encoded in the <i>Layout</i> class. The hint parameters allow the width and/or
+height to be constrained. For example, a layout may choose to grow in one
+dimension if constrained in another. A hint of </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'>SWT.DEFAULT</span>
+means to use the preferred size.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The <b>layout</b> method positions and sizes
+the <i>Composite</i>’s children. A <i>Layout</i> can choose to cache layout-related
+information, such as the preferred extent of each of the children. The <b>flushCache</b>
+parameter tells the <i>Layout</i> to flush cached data.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Since a <i style='mso-bidi-font-style:normal'>Layout</i>
+controls the size and placement of widgets in a <i style='mso-bidi-font-style:
+normal'>Composite</i>, there are several methods in <i style='mso-bidi-font-style:
+normal'>Composite</i> that are used with <i style='mso-bidi-font-style:normal'>Layout</i>s.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The first two methods allow setting and
+getting a <i>Layout</i> object in a <i>Composite</i>.</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><span
+style='mso-tab-count:1'>    </span>public</span> <span style='color:navy'>void</span>
+setLayout(Layout layout);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><span
+style='mso-tab-count:1'>    </span>public</span> Layout getLayout();</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>An application can force a <i>Layout</i> to recalculate
+the sizes of and reposition children by sending <b>layout()</b> to the parent <i>Composite</i>.</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><span
+style='mso-tab-count:1'>    </span>public</span> <span style='color:navy'>void</span>
+layout(<span style='color:navy'>boolean</span> changed);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><span
+style='mso-tab-count:1'>    </span>public</span> <span style='color:navy'>void</span>
+layout();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span><span
+style='color:maroon'>// calls layout(true);<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>You would do this after changing anything
+about the children that might affect their size or position, such as changing
+the font of a child, changing the text or image of a child, adding a new child,
+adding children to a child, etc. (If the child can accommodate the change, then
+layout may not be necessary – for example, changing the font or text of a
+scrollable multi-line <i>Text</i>). Since these changes are done
+programmatically, they do not cause events to happen. Consequently, the parent
+doesn’t know about the changes, and has to be told through the <b>layout</b>
+method. This strategy reduces flash because the application can make several
+changes and then tell the parent to layout, and the children are only redrawn
+once instead of once per change. If <b>layout()</b> is not called and changes
+are made after the shell is opened, then the children may not be correctly laid
+out until the shell is somehow resized. Note that <b>shell.open()</b> causes a
+layout to occur.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The <b>computeSize</b> methods of a <i>Composite</i>
+calculate the Composite’s preferred size, which is the size of its client area
+as determined by the <i>Layout</i>, plus its trim.</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+ <p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><span
+style='mso-tab-count:1'>    </span>public</span> </span><span style='mso-bookmark:_Toc496069785'>Point</span><span style="color: navy">
+ </span><span
+style='mso-bookmark:_Toc496069428'>computeSize(<span style='color:navy'>int</span>
+ widthHint, <span
+style='color:navy'>int</span> heightHint, <span style='color:navy'>boolean</span>
+ changed);</span></span></p>
+
+ <p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><span
+style='mso-tab-count:1'>    </span>public</span> </span><span style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069785'>Point</span><span style="color: navy">
+ </span><span
+style='mso-bookmark:_Toc496069428'></span></span><span
+style='mso-bookmark:_Toc496069428'>computeSize(<span style='color:navy'>int</span>
+ widthHint, <span
+style='color:navy'>int</span> heightHint);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span><span
+style='color:maroon'>// calls computeSize(widthHint, heightHint, true);<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The <b>clientArea</b> of a <i>Composite</i>
+is the rectangle that will contain all of the children. A <i>Layout</i>
+positions the children inside the client area.</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bidi-font-family:"Courier New"'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:10.0pt;mso-bidi-font-family:
+"Courier New";color:#000084'><span style='mso-tab-count:1'>   </span>public</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:10.0pt;mso-bidi-font-family:"Courier New";color:black'>
+Rectangle getClientArea ();<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The <b>trim</b> of a <i>Composite</i> is the
+area outside the client area. For some composites, the size of the trim is zero.
+The trim can be computed by passing the dimensions of the client area into the
+method <b>computeTrim</b>.</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:10.0pt;mso-bidi-font-family:
+"Courier New";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:10.0pt;mso-bidi-font-family:
+"Courier New";color:#000084'><span style='mso-tab-count:1'>   </span>public</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:10.0pt;mso-bidi-font-family:"Courier New";color:black'>
+Rectangle computeTrim (</span></span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:10.0pt;mso-bidi-font-family:
+"Courier New";color:#000084'>int</span></span></span><span style='mso-bookmark:
+_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span style='font-size:
+10.0pt;mso-bidi-font-family:"Courier New";color:black'> x, </span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:10.0pt;mso-bidi-font-family:"Courier New";color:#000084'>int</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:10.0pt;mso-bidi-font-family:"Courier New";color:black'> y, </span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:10.0pt;mso-bidi-font-family:"Courier New";color:#000084'>int</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:10.0pt;mso-bidi-font-family:"Courier New";color:black'> width,
+</span></span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:10.0pt;mso-bidi-font-family:
+"Courier New";color:#000084'>int</span></span></span><span style='mso-bookmark:
+_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span style='font-size:
+10.0pt;mso-bidi-font-family:"Courier New";color:black'> height);<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Sending <b>pack</b> to a <i>Composite</i>
+resizes it to its preferred size.</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bidi-font-family:"Courier New"'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><span
+style='mso-tab-count:1'>    </span>public</span> <span style='color:navy'>void</span>
+pack(<span style='color:navy'>boolean</span> changed);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span><span
+style='color:maroon'>// calls setSize(computeSize(SWT.DEFAULT, SWT.DEFAULT,
+changed));</span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><span
+style='mso-tab-count:1'>    </span>public</span> <span style='color:navy'>void</span>
+pack();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span><span
+style='color:maroon'>// calls pack(true);</span></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>The
+boolean parameter to the <b style='mso-bidi-font-weight:normal'>layout</b>, <b
+style='mso-bidi-font-weight:normal'>computeSize</b>, and <b style='mso-bidi-font-weight:
+normal'>pack</b> methods is the <b style='mso-bidi-font-weight:normal'>changed</b>
+flag. If <b style='mso-bidi-font-weight:normal'>true</b>, it indicates that the
+<i>Composite</i>’s contents have changed in some way that affects its preferred
+size, therefore any caches that the <i style='mso-bidi-font-style:normal'>Layout</i>
+may have been keeping need to be flushed. When a <i style='mso-bidi-font-style:
+normal'>Composite</i> is resized, it asks its <i style='mso-bidi-font-style:
+normal'>Layout</i> to lay out its children by calling layout(<span
+style='color:navy'>false</span>); therefore widget content caches are <i
+style='mso-bidi-font-style:normal'>not</i> flushed. This lets the <i
+style='mso-bidi-font-style:normal'>Layout</i> perform any expensive
+calculations only when necessary.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt;mso-list:skip'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>Caching
+can increase performance, but it can also be tricky. You can choose not to
+cache at all – in fact, it is best not to try caching until your code is
+stable. When considering what to cache, be certain not to store any widget
+state, such as the text of a label, or the number of items in a list. </span></span></p>
+
+<span style='font-size:14.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'><br
+clear=all style='page-break-before:always'>
+</span>
+
+<h3 style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><a name="_Toc509864550">Custom Layout
+Example</a></span></span></h3>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>If you have several vertically oriented <i
+style='mso-bidi-font-style:normal'>Composite</i> widgets in your application,
+you might choose to write <i style='mso-bidi-font-style:normal'>ColumnLayout</i>.
+We will show a simple version of a <i style='mso-bidi-font-style:normal'>Layout</i>
+class that lays out <i style='mso-bidi-font-style:normal'>Composite</i>
+children into a single column. The class has fixed margins and spacing.
+Children are given the same width, but they take their natural height.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The code for the <i style='mso-bidi-font-style:
+normal'>ColumnLayout</i> class is below. Note that we cache the width of the
+widest child, and the sum of the child heights (plus spacing), and these values
+are used to compute the size and lie out the children. They are recalculated if
+<b style='mso-bidi-font-weight:normal'>flushCache</b> is <b style='mso-bidi-font-weight:
+normal'>true</b>.</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>import</span>
+org.eclipse.swt.*;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>import</span>
+org.eclipse.swt.graphics.*;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>import</span>
+org.eclipse.swt.widgets.*;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>import</span>
+org.eclipse.swt.layout.*;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>public</span> <span
+style='color:navy'>class</span> ColumnLayout <span style='color:navy'>extends</span>
+Layout {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:maroon'>// fixed margin and spacing<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>public</span> <span style='color:navy'>static</span> <span
+style='color:navy'>final</span> <span style='color:navy'>int</span> MARGIN = 4;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>public</span> <span style='color:navy'>static</span> <span
+style='color:navy'>final</span> <span style='color:navy'>int</span> SPACING =
+2;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:maroon'>// cache<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>Point
+[] sizes;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>int</span> maxWidth, totalHeight;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>protected</span>
+Point computeSize(Composite composite, <span style='color:navy'>int</span>
+wHint, <span style='color:navy'>int</span> hHint, <span style='color:navy'>boolean</span>
+flushCache) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>Control
+children[] = composite.getChildren();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>if</span> (flushCache || sizes == <span style='color:navy'>null</span>
+|| sizes.length != children.length) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>initialize(children);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>int</span> width = wHint, height = hHint;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>if</span> (wHint == SWT.DEFAULT) width = maxWidth;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>if</span> (hHint == SWT.DEFAULT) height = totalHeight;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>return</span> <span style='color:navy'>new</span> Point(width
++ 2 * MARGIN, height + 2 * MARGIN);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>protected</span> <span
+style='color:navy'>void</span> layout(Composite composite, <span
+style='color:navy'>boolean</span> flushCache) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>Control
+children[] = composite.getChildren();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>if</span> (flushCache || sizes == <span style='color:navy'>null</span>
+|| sizes.length != children.length) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>initialize(children);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>Rectangle
+rect = composite.getClientArea();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>int</span> x = MARGIN, y = MARGIN;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>int</span> width = Math.max(rect.width - 2 * MARGIN,
+maxWidth);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>for</span> (<span style='color:navy'>int</span> i = 0; i
+&lt; children.length; i++) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>int</span> height = sizes[i].y;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>children[i].setBounds(x,
+y, width, height);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='mso-tab-count:1'>   </span>y += height + SPACING;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>void</span>
+initialize(Control children[]) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>maxWidth
+= 0;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>totalHeight
+= 0;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>sizes
+= <span style='color:navy'>new</span> Point [children.length];</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>for</span> (<span style='color:navy'>int</span> i = 0; i
+&lt; children.length; i++) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>sizes[i]
+= children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, <span style='color:navy'>true</span>);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>maxWidth
+= Math.max(maxWidth, sizes[i].x);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>totalHeight
++= sizes[i].y;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>totalHeight
++= (children.length - 1) * SPACING;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Here is some simple test code to test the <i
+style='mso-bidi-font-style:normal'>ColumnLayout</i>. The <b style='mso-bidi-font-weight:
+normal'>grow</b> and <b style='mso-bidi-font-weight:normal'>shrink</b> <i
+style='mso-bidi-font-style:normal'>Buttons</i> show a call to the <i
+style='mso-bidi-font-style:normal'>Shell</i>’s <b style='mso-bidi-font-weight:
+normal'>layout()</b> method to force a re-layout after changing the width of
+one of the children. Calling <b style='mso-bidi-font-weight:normal'>layout()</b>
+is the same as calling <b style='mso-bidi-font-weight:normal'>layout(true</b>)
+which tells the <i style='mso-bidi-font-style:normal'>ColumnLayout</i> to flush
+its caches before setting the bounds of the children. The <i style='mso-bidi-font-style:
+normal'>Shell</i> is also told to <b style='mso-bidi-font-weight:normal'>pack()</b>
+after laying out the children. This forces the <i style='mso-bidi-font-style:
+normal'>Shell</i> to take the new size.</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>import</span>
+org.eclipse.swt.*;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>import</span>
+org.eclipse.swt.widgets.*;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>import</span>
+org.eclipse.swt.layout.*;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>import</span>
+org.eclipse.swt.events.*;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'>public</span> <span
+style='color:navy'>class</span> ColumnLayoutTest {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>static</span> Shell shell;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>static</span> Button button3;</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span><span
+style='color:navy'>public</span> <span style='color:navy'>static</span> <span
+style='color:navy'>void</span> main(String[] args) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>Display
+display = <span style='color:navy'>new</span> Display();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>shell
+= <span style='color:navy'>new</span> Shell(display);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>shell.setLayout(<span
+style='color:navy'>new</span> ColumnLayout());</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>new</span> Button(shell, SWT.PUSH).setText(<span
+style='color:teal'>&quot;B1&quot;</span>);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>new</span> Button(shell, SWT.PUSH).setText(<span
+style='color:teal'>&quot;Very Wide Button 2&quot;</span>);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>(button3
+= <span style='color:navy'>new</span> Button(shell, SWT.PUSH)).setText(<span
+style='color:teal'>&quot;Button 3&quot;</span>);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>Button
+grow = <span style='color:navy'>new</span> Button(shell, SWT.PUSH);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>grow.setText(<span
+style='color:teal'>&quot;Grow Button 3&quot;</span>);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>grow.addSelectionListener(<span
+style='color:navy'>new</span> SelectionAdapter() {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>          </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span> widgetSelected(SelectionEvent
+e) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>              </span>button3.setText(<span
+style='color:teal'>&quot;Extreemely Wide Button 3&quot;</span>);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>              </span>shell.layout();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>              </span>shell.pack();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>          </span>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>});</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>Button
+shrink = <span style='color:navy'>new</span> Button(shell, SWT.PUSH);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>shrink.setText(<span
+style='color:teal'>&quot;Shrink Button 3&quot;</span>);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>shrink.addSelectionListener(<span
+style='color:navy'>new</span> SelectionAdapter() {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>          </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+widgetSelected(SelectionEvent e) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>              </span>button3.setText(<span
+style='color:teal'>&quot;Button 3&quot;</span>);</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>              </span>shell.layout();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>              </span>shell.pack();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>          </span>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>});</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>shell.pack();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>shell.open();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span><span
+style='color:navy'>while</span> (!shell.isDisposed()) {</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>          </span><span
+style='color:navy'>if</span> (!display.readAndDispatch()) display.sleep();</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>       </span>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>    </span>}</span></span></p>
+
+<p class=Code style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>If we run the test code, the window on the
+left appears. Pressing the </span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'>Grow Button 3</span> button results in the window on the
+right. Resizing the window with the mouse will also make the buttons wider (or
+narrower) but they do not grow taller.</span></span></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><!--[if gte vml 1]><v:shape
+ id="_x0000_i1096" type="#_x0000_t75" style='width:88.5pt;height:107.25pt'
+ fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image075.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=118 height=143
+src="./Understanding%20Layouts_files/image076.jpg" v:shapes="_x0000_i1096"><![endif]><span
+style='mso-tab-count:1'> </span><!--[if gte vml 1]><v:shape id="_x0000_i1097"
+ type="#_x0000_t75" style='width:111pt;height:107.25pt' fillcolor="window">
+ <v:imagedata src="./Understanding%20Layouts_files/image077.png" o:title=""/>
+</v:shape><![endif]--><![if !vml]><img width=148 height=143
+src="./Understanding%20Layouts_files/image078.jpg" v:shapes="_x0000_i1097"><![endif]></span></span></p>
+
+<p class=MsoNormal align=center style='margin-left:17.0pt;text-align:center'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<h3 style='margin-left:17.15pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Overriding Composite</span></span></h3>
+
+<p class=MsoNormal style='margin-left:17.15pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><a name="_Toc509864551">If you are writing
+your own widget, as outlined in <i style='mso-bidi-font-style:normal'>“Creating
+Your Own Widgets Using SWT”</i>, and you subclass <i>Composite</i>, then here
+are a few points to consider for your implementation:</a></span></span></p>
+
+<p class=MsoNormal style='margin-left:35.15pt;text-indent:-.25in;mso-list:l5 level1 lfo10;
+tab-stops:list 26.65pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bookmark:_Toc509864551'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;
+</span></span><![endif]>If you are providing trimmings in your new <i>Composite</i>,
+make sure to override both <b>computeTrim</b> and <b>getClientArea</b>.</span></span></span></p>
+
+<p class=MsoNormal style='margin-left:35.15pt;text-indent:-.25in;mso-list:l5 level1 lfo10;
+tab-stops:list 26.65pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bookmark:_Toc509864551'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;
+</span></span><![endif]>Never override <b>layout()</b>, but you may override <b>layout(boolean)</b>.</span></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.15pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bookmark:_Toc509864551'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.15pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bookmark:_Toc509864551'>Sometimes
+you want your new <i>Composite</i> to have a specific look, and you don’t want
+the application to be able to specify a layout. Your new <i>Composite</i> would
+either do its layout in a resize handler or using a private custom layout. In
+either case, you will probably want to do the following:</span></span></span></p>
+
+<p class=MsoNormal style='margin-left:35.15pt;text-indent:-.25in;mso-list:l4 level1 lfo12;
+tab-stops:list 26.65pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bookmark:_Toc509864551'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;
+</span></span><![endif]>Override <b>setLayout</b> to do nothing.</span></span></span></p>
+
+<p class=MsoNormal style='margin-left:35.15pt;text-indent:-.25in;mso-list:l4 level1 lfo12;
+tab-stops:list 26.65pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bookmark:_Toc509864551'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;
+</span></span><![endif]>Override <b>layout(boolean)</b> to call your layout
+code.</span></span></span></p>
+
+<p class=MsoNormal style='margin-left:35.15pt;text-indent:-.25in;mso-list:l4 level1 lfo12;
+tab-stops:list 26.65pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bookmark:_Toc509864551'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;
+</span></span><![endif]>Override <b>computeSize</b> to correctly compute the
+size of your <i>Composite</i>.</span></span></span></p>
+
+<p class=MsoNormal style='margin-left:17.15pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bookmark:_Toc509864551'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<h2 style='margin-left:17.0pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-bookmark:_Toc509864551'>Summary</span></span></span></h2>
+
+<p class=MsoNormal style='margin-left:17.0pt'>SWT provides several different
+ways to lay out widgets. The simplest method, and the one you will typically
+use, is to use one of the standard <i style='mso-bidi-font-style:normal'>Layout</i>
+classes: <i style='mso-bidi-font-style:normal'>FillLayout</i>, <i
+style='mso-bidi-font-style:normal'>RowLayout</i>, or <i style='mso-bidi-font-style:
+normal'>GridLayout</i>.</p>
+
+<p class=MsoNormal style='margin-left:17.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:17.0pt'>In certain cases you may want to
+write your own <i style='mso-bidi-font-style:normal'>Layout</i> class to
+provide a very specific look or to reuse very similar layout code, but often a
+resize listener on the parent widget will suffice.</p>
+
+<p class=MsoHeader style='margin-left:17.0pt;tab-stops:.5in center 3.0in right 6.0in'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/default_style.css b/Article-Understanding Layouts/Understanding Layouts_files/default_style.css
new file mode 100644
index 0000000..85e4e07
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/default_style.css
@@ -0,0 +1,11 @@
+p { font-family: arial, helvetica, geneva; font-size: 10pt}
+td { font-family: arial,helvetica,geneva; font-size: -1}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 11px}
+th { font-family: arial,helvetica,geneva; font-size: 11px; font-weight: bold}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/filelist.xml b/Article-Understanding Layouts/Understanding Layouts_files/filelist.xml
new file mode 100644
index 0000000..15ea6a7
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/filelist.xml
@@ -0,0 +1,84 @@
+<xml xmlns:o="urn:schemas-microsoft-com:office:office">
+ <o:MainFile HRef="../Understanding%20Layouts.htm"/>
+ <o:File HRef="image001.png"/>
+ <o:File HRef="oledata.mso"/>
+ <o:File HRef="image002.jpg"/>
+ <o:File HRef="image003.png"/>
+ <o:File HRef="image004.jpg"/>
+ <o:File HRef="image005.png"/>
+ <o:File HRef="image006.jpg"/>
+ <o:File HRef="image007.png"/>
+ <o:File HRef="image008.jpg"/>
+ <o:File HRef="image009.png"/>
+ <o:File HRef="image010.jpg"/>
+ <o:File HRef="image011.png"/>
+ <o:File HRef="image012.jpg"/>
+ <o:File HRef="image013.png"/>
+ <o:File HRef="image014.jpg"/>
+ <o:File HRef="image015.png"/>
+ <o:File HRef="image016.jpg"/>
+ <o:File HRef="image017.png"/>
+ <o:File HRef="image018.jpg"/>
+ <o:File HRef="image019.png"/>
+ <o:File HRef="image020.jpg"/>
+ <o:File HRef="image021.jpg"/>
+ <o:File HRef="image022.png"/>
+ <o:File HRef="image023.jpg"/>
+ <o:File HRef="image024.png"/>
+ <o:File HRef="image025.jpg"/>
+ <o:File HRef="image026.png"/>
+ <o:File HRef="image027.jpg"/>
+ <o:File HRef="image028.png"/>
+ <o:File HRef="image029.jpg"/>
+ <o:File HRef="image030.png"/>
+ <o:File HRef="image031.jpg"/>
+ <o:File HRef="image032.png"/>
+ <o:File HRef="image033.jpg"/>
+ <o:File HRef="image034.png"/>
+ <o:File HRef="image035.jpg"/>
+ <o:File HRef="image036.png"/>
+ <o:File HRef="image037.jpg"/>
+ <o:File HRef="image038.png"/>
+ <o:File HRef="image039.jpg"/>
+ <o:File HRef="image040.png"/>
+ <o:File HRef="image041.jpg"/>
+ <o:File HRef="image042.png"/>
+ <o:File HRef="image043.jpg"/>
+ <o:File HRef="image044.png"/>
+ <o:File HRef="image045.jpg"/>
+ <o:File HRef="image046.png"/>
+ <o:File HRef="image047.jpg"/>
+ <o:File HRef="image048.png"/>
+ <o:File HRef="image049.jpg"/>
+ <o:File HRef="image050.png"/>
+ <o:File HRef="image051.jpg"/>
+ <o:File HRef="image052.png"/>
+ <o:File HRef="image053.jpg"/>
+ <o:File HRef="image054.png"/>
+ <o:File HRef="image055.jpg"/>
+ <o:File HRef="image056.png"/>
+ <o:File HRef="image057.jpg"/>
+ <o:File HRef="image058.jpg"/>
+ <o:File HRef="image059.png"/>
+ <o:File HRef="image060.jpg"/>
+ <o:File HRef="image061.png"/>
+ <o:File HRef="image062.jpg"/>
+ <o:File HRef="image063.png"/>
+ <o:File HRef="image064.jpg"/>
+ <o:File HRef="image065.png"/>
+ <o:File HRef="image066.jpg"/>
+ <o:File HRef="image067.jpg"/>
+ <o:File HRef="image068.png"/>
+ <o:File HRef="image069.jpg"/>
+ <o:File HRef="image070.gif"/>
+ <o:File HRef="image071.png"/>
+ <o:File HRef="image072.jpg"/>
+ <o:File HRef="image073.png"/>
+ <o:File HRef="image074.jpg"/>
+ <o:File HRef="image075.png"/>
+ <o:File HRef="image076.jpg"/>
+ <o:File HRef="image077.png"/>
+ <o:File HRef="image078.jpg"/>
+ <o:File HRef="header.htm"/>
+ <o:File HRef="filelist.xml"/>
+</xml> \ No newline at end of file
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/header.htm b/Article-Understanding Layouts/Understanding Layouts_files/header.htm
new file mode 100644
index 0000000..30438ff
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/header.htm
@@ -0,0 +1,69 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml"
+xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link id=Main-File rel=Main-File href="../Understanding%20Layouts.htm">
+</head>
+
+<body lang=EN-US link=blue vlink=purple>
+
+<div style='mso-element:footer' id=ef1>
+
+<div style='mso-element:frame;mso-element-wrap:around;mso-element-anchor-vertical:
+paragraph;mso-element-anchor-horizontal:margin;mso-element-left:right;
+mso-element-top:.05pt;mso-height-rule:exactly'>
+
+<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
+ <tr>
+ <td valign=top align=left style='padding-top:0in;padding-right:0in;
+ padding-bottom:0in;padding-left:0in'>
+ <p class=MsoFooter style='margin-top:14.2pt;margin-right:0in;margin-bottom:
+ 0in;margin-left:17.0pt;margin-bottom:.0001pt;mso-element:frame;mso-element-wrap:
+ around;mso-element-anchor-vertical:paragraph;mso-element-anchor-horizontal:
+ margin;mso-element-left:right;mso-element-top:.05pt;mso-height-rule:exactly'><span
+ class=MsoPageNumber><span style='mso-field-code:PAGE'>1</span><o:p></o:p></span></p>
+ </td>
+ </tr>
+</table>
+
+</div>
+
+<p class=MsoFooter style='margin-top:0in;margin-right:.25in;margin-bottom:0in;
+margin-left:17.0pt;margin-bottom:.0001pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+<div style='mso-element:footer' id=f1>
+
+<div style='mso-element:frame;mso-element-wrap:around;mso-element-anchor-vertical:
+paragraph;mso-element-anchor-horizontal:margin;mso-element-left:right;
+mso-element-top:.05pt;mso-height-rule:exactly'>
+
+<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
+ <tr>
+ <td valign=top align=left style='padding-top:0in;padding-right:0in;
+ padding-bottom:0in;padding-left:0in'>
+ <p class=MsoFooter style='margin-left:17.0pt;mso-element:frame;mso-element-wrap:
+ around;mso-element-anchor-vertical:paragraph;mso-element-anchor-horizontal:
+ margin;mso-element-left:right;mso-element-top:.05pt;mso-height-rule:exactly'><span
+ class=MsoPageNumber><span style='mso-field-code:PAGE'>23</span><o:p></o:p></span></p>
+ </td>
+ </tr>
+</table>
+
+</div>
+
+<p class=MsoFooter style='margin-top:0in;margin-right:.25in;margin-bottom:0in;
+margin-left:17.0pt;margin-bottom:.0001pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/idea.jpg b/Article-Understanding Layouts/Understanding Layouts_files/idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/idea.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image001.png b/Article-Understanding Layouts/Understanding Layouts_files/image001.png
new file mode 100644
index 0000000..4fc0452
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image001.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image002.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image002.jpg
new file mode 100644
index 0000000..e641291
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image002.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image003.png b/Article-Understanding Layouts/Understanding Layouts_files/image003.png
new file mode 100644
index 0000000..3c4afef
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image003.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image004.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image004.jpg
new file mode 100644
index 0000000..64e2681
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image004.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image005.png b/Article-Understanding Layouts/Understanding Layouts_files/image005.png
new file mode 100644
index 0000000..df09f83
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image005.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image006.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image006.jpg
new file mode 100644
index 0000000..c53235a
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image006.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image007.png b/Article-Understanding Layouts/Understanding Layouts_files/image007.png
new file mode 100644
index 0000000..6e4cea0
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image007.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image008.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image008.jpg
new file mode 100644
index 0000000..330928b
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image008.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image009.png b/Article-Understanding Layouts/Understanding Layouts_files/image009.png
new file mode 100644
index 0000000..1ea4d44
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image009.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image010.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image010.jpg
new file mode 100644
index 0000000..56b1f97
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image010.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image011.png b/Article-Understanding Layouts/Understanding Layouts_files/image011.png
new file mode 100644
index 0000000..8855720
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image011.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image012.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image012.jpg
new file mode 100644
index 0000000..802baa4
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image012.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image013.png b/Article-Understanding Layouts/Understanding Layouts_files/image013.png
new file mode 100644
index 0000000..781c312
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image013.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image014.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image014.jpg
new file mode 100644
index 0000000..6bbd759
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image014.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image015.png b/Article-Understanding Layouts/Understanding Layouts_files/image015.png
new file mode 100644
index 0000000..844a952
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image015.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image016.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image016.jpg
new file mode 100644
index 0000000..29cbd5b
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image016.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image017.png b/Article-Understanding Layouts/Understanding Layouts_files/image017.png
new file mode 100644
index 0000000..d40416f
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image017.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image018.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image018.jpg
new file mode 100644
index 0000000..64e2681
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image018.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image019.png b/Article-Understanding Layouts/Understanding Layouts_files/image019.png
new file mode 100644
index 0000000..3d93708
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image019.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image020.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image020.jpg
new file mode 100644
index 0000000..e456783
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image020.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image021.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image021.jpg
new file mode 100644
index 0000000..64e2681
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image021.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image022.png b/Article-Understanding Layouts/Understanding Layouts_files/image022.png
new file mode 100644
index 0000000..c0687d7
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image022.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image023.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image023.jpg
new file mode 100644
index 0000000..715d053
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image023.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image024.png b/Article-Understanding Layouts/Understanding Layouts_files/image024.png
new file mode 100644
index 0000000..a309244
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image024.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image025.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image025.jpg
new file mode 100644
index 0000000..afd0d48
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image025.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image026.png b/Article-Understanding Layouts/Understanding Layouts_files/image026.png
new file mode 100644
index 0000000..02249ec
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image026.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image027.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image027.jpg
new file mode 100644
index 0000000..211a997
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image027.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image028.png b/Article-Understanding Layouts/Understanding Layouts_files/image028.png
new file mode 100644
index 0000000..01c39e7
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image028.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image029.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image029.jpg
new file mode 100644
index 0000000..12ab626
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image029.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image030.png b/Article-Understanding Layouts/Understanding Layouts_files/image030.png
new file mode 100644
index 0000000..cae0404
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image030.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image031.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image031.jpg
new file mode 100644
index 0000000..228364f
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image031.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image032.png b/Article-Understanding Layouts/Understanding Layouts_files/image032.png
new file mode 100644
index 0000000..37fa9a5
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image032.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image033.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image033.jpg
new file mode 100644
index 0000000..202382a
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image033.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image034.png b/Article-Understanding Layouts/Understanding Layouts_files/image034.png
new file mode 100644
index 0000000..d062e46
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image034.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image035.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image035.jpg
new file mode 100644
index 0000000..8d607ad
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image035.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image036.png b/Article-Understanding Layouts/Understanding Layouts_files/image036.png
new file mode 100644
index 0000000..33f3785
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image036.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image037.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image037.jpg
new file mode 100644
index 0000000..930cb9a
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image037.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image038.png b/Article-Understanding Layouts/Understanding Layouts_files/image038.png
new file mode 100644
index 0000000..c7b2b86
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image038.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image039.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image039.jpg
new file mode 100644
index 0000000..e8e62e8
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image039.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image040.png b/Article-Understanding Layouts/Understanding Layouts_files/image040.png
new file mode 100644
index 0000000..92406bb
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image040.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image041.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image041.jpg
new file mode 100644
index 0000000..72ee7c4
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image041.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image042.png b/Article-Understanding Layouts/Understanding Layouts_files/image042.png
new file mode 100644
index 0000000..0951295
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image042.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image043.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image043.jpg
new file mode 100644
index 0000000..d956fbf
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image043.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image044.png b/Article-Understanding Layouts/Understanding Layouts_files/image044.png
new file mode 100644
index 0000000..0657be5
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image044.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image045.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image045.jpg
new file mode 100644
index 0000000..9148e16
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image045.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image046.png b/Article-Understanding Layouts/Understanding Layouts_files/image046.png
new file mode 100644
index 0000000..5b5f02a
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image046.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image047.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image047.jpg
new file mode 100644
index 0000000..682e9c6
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image047.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image048.png b/Article-Understanding Layouts/Understanding Layouts_files/image048.png
new file mode 100644
index 0000000..b7fbf5d
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image048.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image049.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image049.jpg
new file mode 100644
index 0000000..b326f6f
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image049.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image050.png b/Article-Understanding Layouts/Understanding Layouts_files/image050.png
new file mode 100644
index 0000000..066f04e
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image050.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image051.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image051.jpg
new file mode 100644
index 0000000..0635d03
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image051.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image052.png b/Article-Understanding Layouts/Understanding Layouts_files/image052.png
new file mode 100644
index 0000000..f304563
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image052.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image053.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image053.jpg
new file mode 100644
index 0000000..00b0262
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image053.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image054.png b/Article-Understanding Layouts/Understanding Layouts_files/image054.png
new file mode 100644
index 0000000..5c02774
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image054.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image055.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image055.jpg
new file mode 100644
index 0000000..3d6c492
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image055.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image056.png b/Article-Understanding Layouts/Understanding Layouts_files/image056.png
new file mode 100644
index 0000000..87eaf44
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image056.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image057.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image057.jpg
new file mode 100644
index 0000000..291fafd
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image057.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image058.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image058.jpg
new file mode 100644
index 0000000..291fafd
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image058.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image059.png b/Article-Understanding Layouts/Understanding Layouts_files/image059.png
new file mode 100644
index 0000000..d62a930
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image059.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image060.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image060.jpg
new file mode 100644
index 0000000..0244cbc
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image060.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image061.png b/Article-Understanding Layouts/Understanding Layouts_files/image061.png
new file mode 100644
index 0000000..9f22f9e
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image061.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image062.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image062.jpg
new file mode 100644
index 0000000..c2b6131
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image062.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image063.png b/Article-Understanding Layouts/Understanding Layouts_files/image063.png
new file mode 100644
index 0000000..c83b26a
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image063.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image064.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image064.jpg
new file mode 100644
index 0000000..7d8e04e
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image064.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image065.png b/Article-Understanding Layouts/Understanding Layouts_files/image065.png
new file mode 100644
index 0000000..b96fc2d
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image065.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image066.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image066.jpg
new file mode 100644
index 0000000..0f6df90
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image066.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image067.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image067.jpg
new file mode 100644
index 0000000..e8e62e8
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image067.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image068.png b/Article-Understanding Layouts/Understanding Layouts_files/image068.png
new file mode 100644
index 0000000..51b9920
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image068.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image069.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image069.jpg
new file mode 100644
index 0000000..5a9d8ff
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image069.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image070.gif b/Article-Understanding Layouts/Understanding Layouts_files/image070.gif
new file mode 100644
index 0000000..d403281
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image070.gif
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image071.png b/Article-Understanding Layouts/Understanding Layouts_files/image071.png
new file mode 100644
index 0000000..2204e7a
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image071.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image072.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image072.jpg
new file mode 100644
index 0000000..de9e18b
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image072.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image073.png b/Article-Understanding Layouts/Understanding Layouts_files/image073.png
new file mode 100644
index 0000000..3bbac4f
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image073.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image074.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image074.jpg
new file mode 100644
index 0000000..0303da7
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image074.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image075.png b/Article-Understanding Layouts/Understanding Layouts_files/image075.png
new file mode 100644
index 0000000..ac25d73
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image075.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image076.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image076.jpg
new file mode 100644
index 0000000..961ee19
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image076.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image077.png b/Article-Understanding Layouts/Understanding Layouts_files/image077.png
new file mode 100644
index 0000000..5389ffc
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image077.png
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/image078.jpg b/Article-Understanding Layouts/Understanding Layouts_files/image078.jpg
new file mode 100644
index 0000000..07ef1af
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/image078.jpg
Binary files differ
diff --git a/Article-Understanding Layouts/Understanding Layouts_files/oledata.mso b/Article-Understanding Layouts/Understanding Layouts_files/oledata.mso
new file mode 100644
index 0000000..5a2e53b
--- /dev/null
+++ b/Article-Understanding Layouts/Understanding Layouts_files/oledata.mso
Binary files differ
diff --git a/Article-Update/images/Idea.jpg b/Article-Update/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Update/images/Idea.jpg
Binary files differ
diff --git a/Article-Update/images/category-def.jpg b/Article-Update/images/category-def.jpg
new file mode 100644
index 0000000..7f8f3dc
--- /dev/null
+++ b/Article-Update/images/category-def.jpg
Binary files differ
diff --git a/Article-Update/images/copyright.jpg b/Article-Update/images/copyright.jpg
new file mode 100644
index 0000000..d416550
--- /dev/null
+++ b/Article-Update/images/copyright.jpg
Binary files differ
diff --git a/Article-Update/images/explorer.jpg b/Article-Update/images/explorer.jpg
new file mode 100644
index 0000000..840224b
--- /dev/null
+++ b/Article-Update/images/explorer.jpg
Binary files differ
diff --git a/Article-Update/images/feature-desc.jpg b/Article-Update/images/feature-desc.jpg
new file mode 100644
index 0000000..94e2a5b
--- /dev/null
+++ b/Article-Update/images/feature-desc.jpg
Binary files differ
diff --git a/Article-Update/images/feature-preview.jpg b/Article-Update/images/feature-preview.jpg
new file mode 100644
index 0000000..eb3ae0c
--- /dev/null
+++ b/Article-Update/images/feature-preview.jpg
Binary files differ
diff --git a/Article-Update/images/feature-refs.jpg b/Article-Update/images/feature-refs.jpg
new file mode 100644
index 0000000..9ba9879
--- /dev/null
+++ b/Article-Update/images/feature-refs.jpg
Binary files differ
diff --git a/Article-Update/images/history.jpg b/Article-Update/images/history.jpg
new file mode 100644
index 0000000..9aa5f35
--- /dev/null
+++ b/Article-Update/images/history.jpg
Binary files differ
diff --git a/Article-Update/images/license.jpg b/Article-Update/images/license.jpg
new file mode 100644
index 0000000..26362a3
--- /dev/null
+++ b/Article-Update/images/license.jpg
Binary files differ
diff --git a/Article-Update/images/one-click2.jpg b/Article-Update/images/one-click2.jpg
new file mode 100644
index 0000000..d897fd9
--- /dev/null
+++ b/Article-Update/images/one-click2.jpg
Binary files differ
diff --git a/Article-Update/images/propsheet.jpg b/Article-Update/images/propsheet.jpg
new file mode 100644
index 0000000..431c4a6
--- /dev/null
+++ b/Article-Update/images/propsheet.jpg
Binary files differ
diff --git a/Article-Update/images/site_obj.gif b/Article-Update/images/site_obj.gif
new file mode 100644
index 0000000..701608b
--- /dev/null
+++ b/Article-Update/images/site_obj.gif
Binary files differ
diff --git a/Article-Update/images/tag_1.gif b/Article-Update/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Update/images/tag_1.gif
Binary files differ
diff --git a/Article-Update/images/tag_2.gif b/Article-Update/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Update/images/tag_2.gif
Binary files differ
diff --git a/Article-Update/images/tag_3.gif b/Article-Update/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Update/images/tag_3.gif
Binary files differ
diff --git a/Article-Update/images/tip.gif b/Article-Update/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Update/images/tip.gif
Binary files differ
diff --git a/Article-Update/images/tryit.gif b/Article-Update/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Update/images/tryit.gif
Binary files differ
diff --git a/Article-Update/images/url.jpg b/Article-Update/images/url.jpg
new file mode 100644
index 0000000..afd2760
--- /dev/null
+++ b/Article-Update/images/url.jpg
Binary files differ
diff --git a/Article-Update/keeping-up-to-date.html b/Article-Update/keeping-up-to-date.html
new file mode 100644
index 0000000..8e3bd0f
--- /dev/null
+++ b/Article-Update/keeping-up-to-date.html
@@ -0,0 +1,707 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML><HEAD><TITLE>How To Keep Up to Date</TITLE>
+<META http-equiv=Content-Type content="text/html; charset=iso-8859-1"><LINK
+href="../default_style.css" rel=stylesheet>
+<META content="Microsoft FrontPage 5.0" name=GENERATOR></HEAD>
+<BODY vLink=#800080 link=#0000ff>
+<DIV align=right><FONT face="Times New Roman, Times, serif" size=2>Copyright ©
+2003 International Business Machines Corp.</FONT>
+<TABLE cellSpacing=0 cellPadding=2 width="100%" border=0>
+ <TBODY>
+ <TR>
+ <TD vAlign=top align=left bgColor=#0080c0 colSpan=2><B><FONT
+ face=Arial,Helvetica><FONT color=#ffffff>&nbsp;Eclipse Corner
+ Article</FONT></FONT></B></TD></TR></TBODY></TABLE></DIV>
+<DIV align=left>
+<H1><IMG height=86 src="images/Idea.jpg" width=120
+align=middle></H1></DIV>
+<P>&nbsp;</P>
+<H1 align=center>How To Keep Up To Date</H1>
+<BLOCKQUOTE><B>Summary</B><BR>This article shows you how to create and publish
+ bundles of plug-ins (called features) to an update site so that customers can
+ download and install them directly into Eclipse using the Eclipse update
+ manager. This has many advantages over the low tech way of delivering new or
+ updated plug-ins in a zip file that someone manually unzips into the directory
+ where Eclipse is installed.
+ <P><B>By Dejan Glozic, IBM and Dorian Birsan, IBM</B><BR>
+ August 27<FONT
+ size=-1>, 2003 (Appendix added January 13, 2004)</FONT></P>
+</BLOCKQUOTE>
+<HR width="100%">
+
+<H2>Staying up to date</H2>
+<P>More often than not, software products are out of date as soon as they appear
+on the market: new features and bug fixes are already available before the CD's
+hit the shelves and web sites provide links for downloading. Eclipse based
+products are no different. Over the course of a project, remember how many times
+you exchanged plug-ins using email attachments with the suggestion 'just unzip
+into the Eclipse directory'. Of course, it works. But would you sell a product
+with 500 plug-ins for $2999, then send updates to customers by email with
+similar instructions? Or post hundreds of zip files on a web site, along with
+installation instructions ?</P>
+<P>In the real world where commercial products are built on top of Eclipse
+technology, new plug-ins and updates to existing ones must be delivered in a
+more convenient way. Another consequence of charging people for software is that
+there are legal ramifications to reckon with. For this reason, Eclipse platform
+has a component that deals with installing and updating plug-ins that is both
+convenient and keeps your company's lawyers happy. </P>
+<H3>Plug-ins are too small (even the large ones)</H3>
+<P>We already know that the basic building block of Eclipse functionality is a
+plug-in. Its manifest contains all the information required by Eclipse to
+successfully load it, contribute into the application and run. However, it is
+not particularly well suited for distribution. One reason is that a plug-in is
+functionally too fine-grained. We always start small, but real production
+quality plug-ins rarely come alone. A more realistic situation is to have
+several plug-ins working together to perform a useful function. Example: Java
+Tools consists of 9 plug-ins, PDE has 5 etc. These plug-ins require each other
+and go together - their usefulness is limited in isolation.</P>
+<P>To represent a unit of useful functionality Eclipse has a notion of
+<B>features</B>. Instead of saying 'take these 9 plug-ins that go together', you
+should be able to say 'take Java Tools'. </P>
+<P>The role of features is to allow providers to make collections of plug-ins
+that logically go together. These collections are made in such a way as to
+provide for easy transport over the network, have necessary legal and security
+mechanisms, and are modular to allow hierarchical product building.</P>
+<P>Features are designed to help in performing the three major tasks:</P>
+<OL>
+ <LI><B><A name=task1></A>Install new functionality into Eclipse products</B>.
+ This task allows you to add things you didn't have before and make your
+ product do more.
+ <LI><B>Update the plug-ins you already have to the newer versions</B>. This
+ task allows you to receive fixes and upgrades to the functionality you already
+ have. Official fix packs and emergency fixes for the pesky bugs that make your
+ life miserable all fall into this category.
+ <LI><B>Control which plug-ins should run when Eclipse starts</B>. This task
+ allows you to disable an entire group of plug-ins, thus making them invisible
+ to Eclipse run-time (note that they are still physically present in the
+ product). This comes in handy in large products where you have the whole slew
+ of features you don't care about at the moment and want to get rid of the user
+ interface artifacts you never use. </LI></OL>
+<P>Although features group plug-ins together, they are not containers. All the
+plug-ins are installed in the 'plugins' directory in the Eclipse product
+location. Features simply reference plug-ins (and fragments) that belong to
+them. This important property plays a major role in optimizing performance when
+downloading over the network. It allows Eclipse to download only the plug-ins
+that have actually changed between the two feature versions. It is easy to
+imagine why downloading 20 new plug-ins out of 500 makes a huge difference in
+this scenario.</P>
+<H3>What's in the manifest?</H3>
+<P>As plug-ins have <B>plug-in manifests</B>, features have <B>feature
+manifests</B>. The file name is feature.xml and it can contain the following
+things (the full DTD can be found in the reference section of the <A
+href="http://dev.eclipse.org/help21/topic/org.eclipse.platform.doc.isv/reference/misc/feature_archive.html">Eclipse
+platform documentation</A>):</P>
+<UL>
+ <LI>Feature id, version, provider name, image to use in Eclipse
+ <LI>Short description, URL to long description, license agreement, copyright
+ statement
+ <LI>References to other features (for building complex feature trees by
+ inclusion)
+ <LI>Dependencies (features can require presence of other plug-ins or features
+ as a prerequisite for installation)
+ <LI>List of plug-ins and fragments that belong to the feature
+ <LI>List of data archives that belong to the feature (normally go together
+ with the custom install handler) </LI></UL>
+<P>This list is not complete but is fairly representative. A manifest file can
+contain translatable content but it is better to place it in
+feature_&lt;NL&gt;.properties files that will be picked as Java resource bundles
+based on the current locale. This is analogous to the way NL content is handled
+for plug-ins.</P>
+<H3>Where features live</H3>
+<P>Features exist in two major places and incarnations: <B>installed</B> (in the
+Eclipse product) and <B>packaged</B> (on the server as part of the update
+site).</P>
+<P>Imagine for a second that Eclipse is completely empty i.e. has no plug-ins
+and features. To get any functionality into it, you would need to download
+features from the server (see <A
+href="http://eclipse.org/articles/Article-Update/keeping-up-to-date.html#task1">task
+#1</A> above). For this to happen, features must be published on a HTTP server
+in the following way:</P>
+<UL>
+ <LI>All features must be packaged into the JAR archives (one per feature) and
+ placed into the directory called 'features'
+ <LI>All plug-ins must be packaged into the JAR archives (one per plug-in) and
+ placed into the directory called 'plugins'
+ <LI>An update site map (an XML file with the name 'site.xml') should be placed
+ in the root of the update site (the folder that contains 'features' and
+ 'plugins') </LI></UL>
+<P>Features and plug-ins are packaged into archives for easy transportation over
+the network. In addition, archives can be digitally signed. If you are charging
+for your software and want to protect your customers as they download updates
+from your site, it is a good idea to sign your archives using valid
+certificates. If not, Eclipse Update will warn your users that they are about to
+install an unsigned feature (a scary message indeed).</P>
+<P><IMG src="images/tip.gif" width="62" height="13"> Security issues with
+features should not be underestimated. Eclipse allows users to download new
+functionality from remote servers. A rogue plug-in can act as a perfect Trojan
+horse. It can look innocent enough and provide useful function while spawning
+threads in the background with full access to the local file system and the
+Internet (if connected). Beware of installing features from update sites you do
+not trust.</P>
+<P>By using Update Manager, we can connect to the update site and examine its
+content (we will talk more about this later in the article). Once we find
+features we want to install, we can bring up the install wizard and let it
+complete the installation.</P>
+<P>After we restart Eclipse, features and their corresponding plug-ins will be
+physically present in our product location. Features and plug-ins will not be
+archives any more: they will now be <B>installed</B>. All the features will be
+in the 'features' directory, and all the plug-ins in the 'plugins'
+directory.</P>
+<P>Of course, Eclipse is never empty to begin with. Every Eclipse product starts
+its life with a number of plug-ins and features. They were not installed using
+Update Manager - they were placed there as a baseline content. Initial update
+operations will be performed using this baseline as a reference.</P>
+<H3>Checking for updates</H3>
+<P>The easiest way to use Eclipse Update starting from a fresh Eclipse
+installation is to see if there are new versions of currently installed features
+available. Features typically have a URL to the site where updates can be found.
+When <B>Help&gt;Software Updates&gt;New Updates</B> is selected, Eclipse will
+connect to these update sites and try to find new versions of the already
+installed features. If found, they will be presented in the installation wizard.
+After accepting the license agreements, pressing <B>Finish</B> and completing
+the installation, your Eclipse product will have the latest updates.</P>
+<P>It is important to note that this operation is performed by Eclipse product
+customers - people that bought the product and want to have the latest service
+update of it. If you are the product provider, it is your responsibility to
+build the features and place them on the update site for your customers to find.
+In the following sections, we will learn how.</P>
+<H2>Time to get our hands dirty</H2>
+<P>Now that we understand the basics of the Eclipse Update mechanism, it is time
+to see it in action. We will use the 'Hello, World' plug-in, create a feature
+for it, publish it on an update site and then install it into another Eclipse.
+Since plug-in development is not the focus of this article, we will take
+advantage of PDE to do it fast.</P>
+<P><IMG src="images/tip.gif" width="62" height="13"> The goal of our example is
+to use one Eclipse product as a development environment, and publish a feature
+that can be installed into another Eclipse product. In order to keep things
+clean, we suggest you install two copies of Eclipse in your file system - one to
+use for development, and another to act as a product. Download the 2.1.1 version
+of Eclipse SDK from <A href="http://www.eclipse.org/downloads/">Eclipse.org</A>
+and unzip it into the two different locations.</P>
+<H3>Creating a feature</H3>
+<P>We will start by making the plug-in project by selecting
+<B>New&gt;Project&gt;Plug-in Development&gt;Plug-in Project</B>. We will choose
+'com.example.xyz' for the project name (this will become our plug-in ID as
+well). We will accept the defaults and select 'Hello, World' template from the
+<B>Plug-in Code Generators</B> page.</P>
+<P>After pressing <B>Finish</B>, we should have the plug-in project created and
+visible in the Package Explorer. Newly created manifest file will be opened for
+editing in the PDE manifest editor. We should take this opportunity to test our
+new plug-in by following the 'Run...' hyperlink from the <B>Welcome</B> editor
+page. The test Eclipse instance that will appear should contain a tool bar
+button that will greet us with a 'Hello, World' message box when pressed. Our
+goal is to get our plug-in packaged, published and installed into another
+Eclipse so that we can see the same message box there.</P>
+<P>Before we move on to creating a feature, we must perform one important step:
+make sure all the files we need will end up in the packaged plug-in. An
+important file controls how plug-ins and features are built: build.properties.
+It has been created by PDE wizard automatically, but it may not contain all the
+things we need. In our particular case, 'Hello, World' wizard created
+<B>'</B>icons<B>'</B> directory that we need to include in the <FONT size=2>
+<IMG
+src="images/tag_1.gif" align=middle width="24" height="13"> </FONT>bin.includes
+variable as follows:</P><FONT size=2>
+<BLOCKQUOTE><PRE>bin.includes = plugin.xml,\<BR> xyz.jar,\<BR> <IMG src="images/tag_1.gif" align=middle width="24" height="13"> icons/<BR>source.xyz.jar = src/</PRE></BLOCKQUOTE></FONT>
+<P>Once we have the plug-in, know that it is working and ready to build, we will
+create a feature. To do so, select <B>New&gt;Project&gt;Plug-in
+Development&gt;Feature Project</B>. We will use the same ID as for the plug-in
+but change the project name to avoid name collision in the workspace. We will
+choose 'com.example.xyz-feature'. After pressing <B>Next</B>, we will be able to
+change the ID into 'com.example.xyz', name into 'XYZ Feature' and provider into
+'XYZ Inc'. Pressing <B>Next</B> again will take us to the page where we can pick
+plug-ins and fragments that should belong to the feature. We will select the
+only plug-in available (com.example.xyz). At this point we can press
+<B>Finish</B> to get our project created.</P>
+<P>The wizard operation is analogous to the one for plug-in projects in that it
+creates the project and the necessary files, and opens the feature manifest for
+editing. The manifest editor is the usual PDE variety which means that you don't
+need to know the exact XML DTD to be productive - you can use form pages
+exclusively.</P>
+<P>Feature manifests can get complex in some cases, but we don't need to use all
+their capabilities for our little exercise. Our goal is to define the
+following:</P>
+<UL>
+ <LI>Feature id, version, name and provider (<B>Overview</B> page - already set
+ by the wizard)
+ <LI>Short description, license agreement, copyright notice (<B>Information</B>
+ page)
+ <LI>Plug-ins and fragments that belong to the feature (<B>Content</B> page -
+ already set by the wizard) </LI></UL>
+<P><IMG src="images/tryit.gif" width="61" height="13"> Switch to the Information
+page and<BR></P>
+<DIV style="MARGIN-LEFT: 40px">
+<UL>
+ <LI>select the <SPAN style="FONT-WEIGHT: bold">Feature Description</SPAN>
+ section and enter the following text: </LI></UL>
+<DIV style="MARGIN-LEFT: 40px"><SPAN style="FONT-STYLE: italic">This feature is
+designed to allow us to make XYZ plug-in available for installation using
+Eclipse Update Manager.</SPAN> </DIV>
+<DIV style="MARGIN-LEFT: 40px"><BR>
+ <IMG title="" alt="Feature Description"
+src="images/feature-desc.jpg" width="547" height="327"><BR><BR><B>Figure 1:</B>
+Setting the Feature Description </DIV></DIV>
+<DIV style="MARGIN-LEFT: 40px">
+<UL>
+ <LI>select the <SPAN style="FONT-WEIGHT: bold">Copyright Notice</SPAN> section
+ and enter the following text: </LI></UL>
+<DIV style="MARGIN-LEFT: 40px"><SPAN style="FONT-STYLE: italic">2003 XYZ Inc.
+All rights reserved.</SPAN></DIV>
+<DIV style="MARGIN-LEFT: 40px"><BR>
+ <IMG title="" alt="Feature Description"
+src="images/copyright.jpg" width="544" height="325"><BR><BR><B>Figure 2:</B>
+Setting the Copyright Notice </DIV></DIV>
+<DIV style="MARGIN-LEFT: 40px">
+<UL>
+ <LI>select the <SPAN style="FONT-WEIGHT: bold">License Agreement</SPAN>
+ section and enter the following text: </LI></UL>
+<DIV style="MARGIN-LEFT: 40px; FONT-STYLE: italic">License Agreement<BR><BR>You
+must accept this license agreement in order to install this<BR>feature into your
+product.</DIV>
+<DIV style="MARGIN-LEFT: 40px"><BR>
+ <IMG title="" alt="Feature Description"
+src="images/license.jpg" width="546" height="327"><BR><BR><B>Figure 3:</B> Setting
+the Licence Agreement</DIV></DIV>
+<P>Now save the file, switch to the <B>Overview</B> page and select
+<B>Preview</B> from the pop-up menu. This handy function taps into Eclipse
+Update API to test if the feature we are creating will be liked by Update
+Manager when packaged and deployed. If everything is fine, you should see the
+<B>Preview</B> (part of the Update Manager) open, showing you the feature
+properties. You should be able to see the description, follow the 'License' and
+'Copyright' hyperlinks and see the correct name, provider and version (and above
+all, this demonstrates that the manifest file is loaded without errors by the
+Update XML parser):</P>
+<P align=center>
+<IMG src="images/feature-preview.jpg"
+border=0 width="511" height="470"></P>
+<P align=center><B>Figure 4:</B> Preview of the feature as it is being designed
+in the workspace.</P>Note that the actual size and location of the view will
+depend on the perspective in which it was opened. We made the view in Figure 4
+taller to allow you to see it without the scroll bars. In most perspectives it
+opens stacked with the other views in the lower-right corner.<BR>
+<H3>Creating an update site</H3>
+<P>Having created a plug-in and a feature, we need to build them and make them
+available on an Eclipse <B>update site</B>. The update site concept is very
+powerful and flexible, but requires some advanced programming in order to tap
+into that power. For this reason, Eclipse provides a default implementation of
+the required interfaces that makes feature publishing easier and
+programming-free.</P>
+<P>We said earlier that in order to build a site, we need a <B>site map</B>
+(site.xml). In addition, we need to package features and plug-ins into JARs and
+place them alongside the map in the 'features' and 'plugins' directories,
+respectively. By placing these files and folders on an HTTP server connected to
+the Internet, you are making the site visible to Eclipse users around the
+world.</P>
+<P>There are many ways to build an update site. Large products with automated
+builds can package features and plug-ins, upload them onto the server and update
+site.xml automatically. For smaller projects and for experimentation, PDE
+provides tooling for update site creation. It will come in handy for our example
+as well.</P>
+<P><A name=siteLocation></A>We will start by creating an update site project by
+selecting <B>New&gt;Project&gt;Plug-in Development&gt;Update Site Project</B>.
+We will pick 'update-site' for a project name, but choose a non-default location
+for the project for the following reasons:</P>
+<OL>
+ <LI>If your local machine is also a server or you have file system access to
+ the server (e.g. shared drives), you can create the site project directly in
+ the server root. Changes made to the server project resources will be
+ instantly visible to everybody.
+ <LI>Even if it isn't, by locating the update site outside of a workspace, you
+ can share the site between several workspaces. This is important if you want
+ to build <B>multiple versions</B> of features and plug-ins and place them in
+ the same site (which is often the case). You must do it this way because when
+ you are self-hosting in Eclipse, you can only work on one version of each
+ plug-in at a time per workspace. </LI></OL>
+<P>Very predictably, the wizard creates a new site project, site map and opens
+the file for editing in the usual PDE multi-page editor. </P>
+<P align=left>The first step is to connect the features in the workspace and our
+site. The update site manifest editor is actually a combination of an editor and
+a builder in that it keeps track of features in the workspace, builds them and
+packages them in a format required by the Update Manager. The packaged files are
+then placed directly into the site project in the required folders. To connect
+features and the site, we need to switch to the <B>Build</B> page and press
+<B>Add...</B> in <B>Features To Build</B> section. The wizard should contain
+'com.example.xyz' feature (version 1.0.0) that is in our workspace. When we
+choose it and press <B>Finish</B>, this feature project is now added to the
+build map of this site.</P>
+<P align=left>Adding a feature project to the build map will not make it visible
+to people that connect to our site. It is possible to have features in the
+update site that are not visible. For example, if you build a complex feature
+that includes several smaller ones, you only need to make the root visible in
+the site. When users select your complex feature for installation, all the
+children will be recursively downloaded as part of the process.</P>
+<P align=left>To make our XYZ feature visible, we need to select the checkbox in
+the above mentioned section. You will notice that an entry appeared in the
+<B>Outline</B> under <B>Features</B>. Indeed, if you switch to <B>Features</B>
+page, you will see this entry in the list. What this means is that the feature
+will be visible to users who connect to our site and browse it. Note how the
+feature archive name is a combination of the feature ID and version. This way
+you can place many different versions of the same feature side by side:</P>
+<P align=center>
+<IMG title="" alt="Features on update site"
+src="images/feature-refs.jpg" width="581" height="399"></P>
+<P align=center><B>Figure 5</B>: Defining the features that will be visible when
+connecting to the site.</P>
+<P align=left>Our site description is now ready to be built. To do so, we will
+switch to the <B>Build</B> page and press the <B>Build</B> button. After the
+build operation has finished, you should have a JAR in both the 'features' and
+'plugins' directory. Check that you have the following content in your Navigator
+or Package Explorer after the build operation. Note that Navigator shows all the
+resources, so you will also see a folder where build information is kept
+(.sitebuild). This folder is used by the site builder only and is hidden for a
+reason. It is used at development time only and plays no role in a published
+site.</P>
+<P align=center>
+<IMG src="images/explorer.jpg"
+border=0 width="235" height="192"></P>
+<P align=center><B>Figure 6</B>: Package Explorer view after building the update
+site.</P>
+<P align=center>
+<IMG src="images/tip.gif" align=left width="62" height="13"></P>
+<P align=left>You have probably noticed that there are two buttons in the
+<B>Build</B> page: <B>Build</B> and <B>Rebuild All</B>. Why two? The later is
+easy to understand: it unconditionally builds all the plug-ins and features in
+the build map. In contrast, the former builds only features and plug-ins that
+changed since the last build. Building features may take time if they reference
+many plug-ins, so it definitely makes life easier. However, it is not as
+fine-grain as incremental builders that run on resource changes, since the
+expectation is that you will not need them as often.</P>
+<H3 align=left>Testing the site</H3>
+<P align=left>We can test our site without leaving the workspace. Update Manager
+treats local and remote sites equally (the only exception being that remote
+sites have an extra download step before you can access its files). We can use
+this property to go to our site and verify that we can browse it correctly. If
+we can, so will our users once we publish it on the server.</P>
+<P align=left>All you need to do is open Update Manager (<B>Help&gt;Software
+Updates&gt;Update Manager</B>), locate icon <B>My Computer</B> in Feature
+Updates and drill down into the location on the file system where our
+'update-site' project folder is. You will notice that it is actually not
+represented as a folder in the view. Instead, it shows a pink diamond icon (<IMG
+title="" alt=site src="images/site_obj.gif" width="16" height="16">) used for
+update sites. This is a good sign - it means that the view recognized that this
+folder is in fact an update site and immediately switched into site browsing
+mode. You can browse the site right there, but a better way is to bookmark it
+(select it and choose <B>Bookmark Location...</B> from the pop-up menu). This
+will bookmark the site so that you don't have to drill down in the future.</P>
+<P align=left>If everything is OK, you should see <SPAN
+style="FONT-WEIGHT: bold">Other</SPAN> (the default category) with one feature
+in it: XYZ Feature 1.0.0. When you select it, the feature properties should show
+up in the <B>Preview</B>.</P>
+<P align=left>
+<IMG src="images/tip.gif" width="62" height="13"> When creating
+more complex sites, you would first create a <B>category definition</B> to help
+people accessing your site see features classified into logical groups. That
+way, categorized features will not appear under the Other folder, but under
+their category folder.</P>
+<P align=left>
+<IMG src="images/tip.gif" width="62" height="13"> As you are
+testing your site over and over, remember to select <B>Refresh</B> from the
+pop-up menu before making conclusions. Update Manager tries to be as efficient
+as possible so it will not react to changes in the file system unless you force
+it to drop the cached data and connect to the site anew.</P>
+<H3 align=left>Implanting the update URL</H3>
+<P align=left>There is one extra task we need to perform before publishing the
+site. It represents our investment in the future. Although our users can use
+Update Manager to navigate to the update site, find the new version and install
+it, it requires more knowledge and work than is really necessary. By implanting
+a URL that points at the update site, Eclipse can search for new updates
+automatically, with minimal user intervention.</P>
+<P align=left>Embedding a URL that points to the site with updates is easy, but
+you need to select the URL wisely. Once you ship the feature, the server must be
+located where you said it will be. You can change this URL in the subsequent
+versions of your feature, but do spend some time thinking about it - if you do,
+you will not need to change it often. For example, Eclipse.org update site is <A
+href="http://update.eclipse.org/updates/">http://update.eclipse.org/updates/</A>
+and is unchanged since release 2.0.</P>
+<P align=left>Since in our example the site is local on the file system, we will
+use file protocol for the update URL. All we need is to add the update URL to
+our feature.xml:</P>
+<DIV align=left>
+<P align=left>
+<IMG title="" alt="" src="images/tryit.gif" width="61" height="13">
+<BR>On the <B>Overview</B> page of the feature manifest editor locate the
+<B>Feature URLs</B> section. Choose <B>New&gt;Update URL</B> from the pop-up
+menu and edit the object properties in the property sheet when created. /p&gt;
+<P align=left>
+<IMG title="" alt="site url"
+src="images/url.jpg" width="716" height="422"><BR><B>Figure 7</B>: Setting the
+Update URL for a feature</P>
+<P>The URL path should match the directory where you defined your update site,
+so make sure you change the following URL if you copy/paste it:</P><PRE><FONT color=#008000 size=2>file:D:/eclipse-sdk2.1/eclipse/update-area/update-site/</FONT></PRE>
+<P>
+<IMG title="" alt=propsheet
+src="images/propsheet.jpg" width="379" height="165"></P><B>Figure 8</B>: Setting
+the Update URL in the property sheet
+<P></P></DIV>
+<H3 align=left>Publishing the site to a server</H3>
+<P align=left>
+<IMG src="images/tip.gif" width="62" height="13"> This step is not
+needed if you are directly updating a site on the local file system or on a
+local server, as it was discussed when <A
+href="#siteLocation">creating
+the update site project</A>.</P>
+<P align=left>You can publish the site in many ways. If you do not have access
+to a server, the simplest way to publish it is to export the site project into a
+local directory, outside the Eclipse workspace. </P>
+<P align=left>A more powerful way to publish the site to a remote server is by
+using the optional <B>Eclipse FTP and WebDAV Support</B> feature available as a
+separate download from Eclipse.org. You can create a target for your update site
+project on the server, and upload deltas using FTP or WebDAV protocols whenever
+you rebuild the site. If your server is not enabled for FTP or WebDAV, then
+you'll have to manually deploy the site to the server. In this example we assume
+that your server is FTP-ready.</P>
+<P align=left>First, let's use the Update Manager to download the FTP and WebDAV
+Support: switch to the Update Manager, add a bookmark to <A
+href="http://update.eclipse.org/updates/">http://update.eclipse.org/updates/</A>,
+expand it, expand <B>Eclipse SDK 2.1.0</B> category and find <B>Eclipse FTP and
+WebDAV Support</B>. Select the feature and press <B>Install Now</B> button in
+the <B>Preview</B>. It will download, install and configure this feature
+automatically. Restart when asked and that's it.</P>
+<P align=left>Now that our Eclipse workbench can act as an FTP client, we can
+prepare the site for publishing:</P>
+<OL>
+ <LI>Select the update site project and bring up the pop-up menu.
+ <LI>Choose '<SPAN style="FONT-WEIGHT: bold">Team-&gt;Target Site</SPAN>'. The
+ wizard will open.
+ <LI>Select '<SPAN style="FONT-WEIGHT: bold">FTP</SPAN>' protocol and press
+ 'Next'.
+ <LI>Select the FTP URL that includes the remote server and the path from the
+ FTP root to the physical root of the site as defined by the HTTP server.
+ <LI>Specify user name and password for the FTP account. Press Next.
+ <LI>Specify the directory that will be the project root on the server (use the
+ provided default that is the same as the project name).
+ <LI>Press 'Finish'. </LI></OL>
+<P>You have now established the target site. Changes you make in the workspace
+will be compared to the target and delta will be computed when upload is
+needed.</P>
+<P>To upload, select the project and use 'Team-&gt;Synchronize with target'
+option. This will bring the familiar 'Synchronize' view used with CVS
+repositories. Select the desired branch or the root and 'Upload' the content to
+the server.</P>
+<H3 align=left>The geek test</H3>
+<P align=left>Let's now pretend that our feature is published and that we were
+told that there is this cool XYZ feature that is a 'must have'. To pretend
+successfully, we need to install another copy of Eclipse 2.1.1 SDK in a
+different location (to act as a product) and launch it. When it comes up,
+immediately switch to the Update Manager and create a bookmark in Feature
+Updates. If the site was published locally, drill down to the site location
+using <B>My Computer</B> and create a bookmark for it. If the site was published
+on a remote server, then create a Site bookmark to the appropriate site URL.</P>
+<P align=left>You should be able to expand this bookmark and see the same things
+as before when we tested the site. This time, we will go all the way and press
+the <B>Install Now</B> button. You should accept our fake license, accept the
+default location and press <B>Finish</B>. After restarting Eclipse, our XYZ
+Feature (and XYZ Plug-in) will be installed.</P>
+<P align=left>How to tell that everything went well? Check any of the
+following:</P>
+<OL>
+ <LI>Switch to the <B>Resource</B> perspective and select <B>Window&gt;Reset
+ Perspective</B> (this is required because perspective was created and
+ persisted before we installed our plug-in, so we must reset it to see our
+ contribution). A new tool bar button should show up, as well as <B>Sample
+ Menu</B> with a <B>Sample Action</B> in the menu bar. Both the button and the
+ action should open the 'Hello, World' message box, indicating that our plug-in
+ is alive and well.
+ <LI>Select <B>Help&gt;About&gt;Feature Details</B>. Our feature should be on
+ the list.
+ <LI>Switch to Update Manager and expand <B>Eclipse Platform</B> node in
+ <B>Install Configuration</B>. Expand the install location object. It should
+ show 'XYZ Feature 1.0.0'. </LI></OL>
+<H2>Providing feature updates</H2>
+<P>As it usually happens, after you successfully deploy the 1.0.0 version, it is
+likely you will need to provide bug fixes to your customers.</P>
+<P>One very important thing to remember is that once you publish your plug-ins
+and features, any changes to their code must cause version increments. After you
+change one line of your code, it starts to differ from what people have
+installed on their machines, which means it is not the same version. In Eclipse,
+this is handled by creating a maintenance branch in the repository. This branch
+is used for fixes of the shipped code base while further development goes on
+unimpeded in the main development stream.</P>
+<H3>Creating an update</H3>
+<P>Since we found a bug, we will create a <B>bug fix release</B>. We started
+with version 1.0.0, so we will make 1.0.1 this time (increment only service
+portion of the version). We need to make a number of changes to the existing
+plug-in and feature, so make sure the 1.0.0 versions are saved somewhere.</P>We
+will start by editing plugin.xml of our plug-in project and incrementing its
+version to 1.0.1. In addition, we will modify
+com.example.xyz.actions.SampleAction.java file to show a different text in the
+message box:
+<BLOCKQUOTE><PRE> <FONT color=#7f0055 size=2><B>public</B></FONT><FONT size=2> </FONT><FONT color=#7f0055 size=2><B>void</B></FONT><FONT size=2> run(IAction action) {<BR> MessageDialog.openInformation(<BR> window.getShell(),<BR> </FONT><FONT color=#2a00ff size=2>"Xyz Plug-in"</FONT><FONT size=2>,<BR> </FONT><FONT color=#2a00ff size=2>"Hello, UPDATED Eclipse world"</FONT><FONT size=2>);<BR> }</FONT></PRE></BLOCKQUOTE>
+<P>This will take care of the plug-in. Next, we will handle the feature. First,
+open feature.xml again. Since we changed plug-in version, we must repair the
+broken reference in the feature: on the <SPAN style="FONT-WEIGHT: bold">Content
+</SPAN>page remove the com.example.xyz plug-in and add it back (PDE will
+automatically handle this in a future Eclipse release). In addition, we must
+increment the feature version on the <SPAN style="FONT-WEIGHT: bold">Overview
+</SPAN>page to 1.0.1, because Update compares feature versions when scanning for
+new updates. Finally, we will change the description of the feature to say
+something about the fix; add this text to the Feature Description section: <SPAN
+style="FONT-STYLE: italic">This version contains a fix to a critical bug found
+during writing of this article</SPAN>.</P>
+<H3>Building and publishing the update</H3>
+<P>Now that we updated the feature, we must rebuild everything and
+republish.</P>
+<P>We will start by opening site.xml using the site map editor. When you switch
+to the <B>Build</B> page, note how the icon for the 'XYZ Feature 1.0.0' is gray
+and hollowed out. This indicates that we contain a reference to this feature but
+cannot find it in the workspace. This is OK - since this is shared project,
+there will always be features that we cannot find (because they are in other
+workspaces). We need to add our modified XYZ Feature 1.0.1 to this list and
+check the checkbox. This will add another feature entry to the site
+manifest.</P>
+<P>When we switch to the <B>Features</B> page, we can indeed see this entry.
+Repeating what we did before, we will select this entry and add it to our
+category. After saving the file, we can select <B>Build</B> from the pop-up menu
+(no need to switch back to the <B>Build</B> page). If everything went well, you
+should now have TWO plug-ins in the 'plugins' folder and TWO features in the
+'features' folder.</P>
+<P>As before, we can preview the site using Update Manager (this is where
+bookmarking the site is paying off). You should now see two features (XYZ
+Feature 1.0.0 and 1.0.1) and switching between them should show differences in
+the description.</P>
+<H3>The geek test, updated</H3>
+<P>Finally, the fix is ready. This is where our decision to implant a URL that
+points at our update site is paying off. All the users need to do is select
+<B>Help&gt;Software Updates&gt;New Updates</B> and wait for the results.</P>
+<P><IMG src="images/tryit.gif" width="61" height="13"> So far, our 'pretend'
+Eclipse product has 'XYZ Feature 1.0.0' installed. When we select this command,
+a progress monitor will show up, searching for new updates. It is shortly
+replaced with a wizard showing the results of the search:</P>
+<P align=center>
+<IMG src="images/one-click2.jpg"
+border=0 width="600" height="500"></P>
+<P align=center><B>Figure 9:</B> Result of the update search.</P>
+<P>What happened? Eclipse checked currently installed features, connected to the
+update sites using URLs in feature manifests, and searched for features with the
+same ID but higher version. Since our site had a feature that matched this
+description, it showed up in the wizard. We can now proceed with the
+installation and the result will be the same as if we installed it from the
+Update Manager, only with fewer mouse clicks.</P>
+<P>When you publish your features, you definitely want your users to follow this
+path because it is the most straightforward way of bringing the updates in.</P>
+<P>
+<IMG title="" alt="" src="images/tip.gif" width="62" height="13"> After
+installing a new feature or updating an existing feature it is possible to go
+back to a previous configuration state. Do this from the Configuration History
+node in the Install Configuration view.</P>
+<H2>Conclusion</H2>
+<P>We hope this article makes you think twice about sending more 'just unzip
+...' notes with attachments. Instead, your next note should read:</P>
+<BLOCKQUOTE style="FONT-STYLE: italic">
+ <P>A new tool named XYZ Feature is now available for download from update
+ site<BR>http://xyz.example.com/updates/</P></BLOCKQUOTE>
+<P>Each subsequent note should simply be:</P>
+<P><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </B><SPAN
+style="FONT-STYLE: italic">Version 1.0.1 of XYZ Feature is now available for
+download from update site</SPAN><BR style="FONT-STYLE: italic"><SPAN
+style="FONT-STYLE: italic">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
+http://xyz.example.com/updates/ </SPAN><BR style="FONT-STYLE: italic"><SPAN
+style="FONT-STYLE: italic">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; You can
+install it directly by selecting the New Updates
+action.</SPAN><B><BR></B>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>More can be
+done with Eclipse update. You can make a more complex feature by <SPAN
+style="FONT-WEIGHT: bold">including </SPAN>several smaller ones, with some of
+them <SPAN style="FONT-WEIGHT: bold">optional</SPAN>. By providing <SPAN
+style="FONT-WEIGHT: bold">patches</SPAN>, you can update branches of the complex
+feature hierarchy, not just the root feature. You can also create a
+<B>branding</B> plug-in and associate it with a feature to make your feature
+stand out in a number of places in the workbench. If your feature is <SPAN
+style="FONT-WEIGHT: bold">primary</SPAN>, that plug-in can also contain a splash
+screen that replaces the default Eclipse splash. Finally, you can package a set
+of features and plug-ins that represent a significant function and add it to
+other Eclipse products during installation using <B>linked extensions</B>.</P>
+<P>Our example only scratched the surface of update capabilities. As your code
+grows in complexity, so will your software update needs.</P>
+<h2>&nbsp;</h2>
+<h2>Appendix: Update Manager Developer Tips</h2>
+<p><b>By Alexandre Junqueira, INMETRICS</b> <br>
+ <font size="-1">January 13, 2004</font> </p>
+<P>This appendix presents some real-world tips to avoid common mistakes during
+ the creation and maintenance of Eclipse update sites. Creating an update-site
+ is easy, but you need to adhere to some unwritten rules to get a well-functioning
+ artifact.</P>
+<h3>Tip #1: Always remember trailing slash &quot;/&quot;</h3>
+<p style="margin-top: 0; margin-bottom: 0">One major pitfall when build Update
+sites is that everything goes well until the final test. But then, even the most
+simplistic site <b>doesn't work</b> in Update Manager (or Install/Update dialog
+-- for those using Eclipse 3.0). </p>
+<p style="margin-top: 0; margin-bottom: 0">Then comes the &quot;bit-brushing&quot; work of
+trying to get everything work by hand, since the &quot;update site&quot; is no more than a
+bunch of XML and JAR files you've created with assistance of Eclipse wizards ...
+</p>
+<ol>
+ <li>
+ <p style="margin-top: 0; margin-bottom: 0">first, you try to check the HTTP
+ access to the update site, and it works; </li>
+ <li>
+ <p style="margin-top: 0; margin-bottom: 0">then, you check file permissions to
+ certifies that anyone can read them; they're also ok; </li>
+ <li>
+ <p style="margin-top: 0; margin-bottom: 0">come back to the Eclipse workbench
+ and, surprisingly, it <b>doesn't work at all</b>; </li>
+</ol>
+<p style="margin-top: 0; margin-bottom: 0">You check, double-check, and even
+triple-check the above steps, and then you give up on creating an update site
+and deliver your brand new plug-in as a downloadable .zip file to the community,
+so at least it could be <b>manually</b> installed. </p>
+<p style="margin-top: 0; margin-bottom: 0">This situation is common place for
+you? If so, then you've probably ran in one of the most tricky behaviors of the
+update manager. </p>
+<p style="margin-top: 0; margin-bottom: 0">The problem is: <b>you must put a
+trailing slash (&quot;/&quot;) in the update site URL defined in &quot;feature.xml&quot; XML file.</b>
+</p>
+<p style="margin-top: 0; margin-bottom: 0">Go back to the Feature Editor (if
+you're using Eclipse 3.x), or open &quot;feature.xml&quot; file you've created. Look for
+the <b>&lt;url&gt;</b> tag. </p>
+<p style="margin-top: 0; margin-bottom: 0">This tag contains the reference to
+the site where Update Manager will look for your plug-ins installation files.
+BUT THIS URL MUST BE TERMINATED BY A SLASH CHARACTER. </p>
+<p style="margin-top: 0; margin-bottom: 0">Why such behavior? Because Eclipse's
+Update Manager appends plug-in distribution file name to the URL you've set up
+there, <b>without</b> pre-pending with &quot;/&quot; ... so, instead of getting something
+like </p>
+<pre>&quot;http://your.site/update/plugin_1.0.0.jar&quot;</pre>
+<p>it gets </p>
+<pre>&quot;http://your.site/updateplugin_1.0.0.jar&quot;</pre>
+<p>which explains why, after all, Eclipse doesn't find your master piece. It's
+looking for an inexistent URL!</p>
+<h3>Tip #2: Fill the blanks</h3>
+<p style="margin-top: 0; margin-bottom: 0">Another common pitfall when build
+features to publish in update sites is to avoid writing copyright and license
+notices. </p>
+<p style="margin-top: 0; margin-bottom: 0">It's specially true when building
+your update site for the first time (you don't want to write a major legal act
+-- you're just trying to make your work available, no?). </p>
+<p style="margin-top: 0; margin-bottom: 0">But Eclipse's Update Manager will
+look for such disclaimers and doesn't allow you to install features that don't
+provide such notices. </p>
+<p style="margin-top: 0; margin-bottom: 0">So, to avoid such pain in the
+uttermost stage of deploying, write down at least a simple word in both fields.
+</p>
+<p style="margin-top: 0; margin-bottom: 0">The recommended way is to use a
+template-based text for both fields, such as: </p>
+<dl>
+ <dt><b>copyright</b> </dt>
+ <dd>Copyright (c) 2004 by John Doe. All rights reserved </dd>
+ <dt><b>legal</b> </dt>
+ <dd>This work follows CPL/GPL/LGPL/BSD licensing schema. See
+ &lt;license-site&gt; for more details
+ about usage and distribution. </dd>
+</dl>
+<h3>Tip #3: Be careful when using <i>build.xml</i></h3>
+<p style="word-spacing: 1; margin-top: 0; margin-bottom: 0">If you're the
+developer of the plug-in been published, then you've almost certainly created
+the <b>build.xml</b> using the &quot;Create build file&quot; (or &quot;Create ant build file&quot;)
+pop-up menu option on plugin.xml. </p>
+<p style="word-spacing: 1; margin-top: 0; margin-bottom: 0">If you did so, and
+specially, you've customized the file, then BE CAREFUL. </p>
+<p style="word-spacing: 1; margin-top: 0; margin-bottom: 0">Before creating and
+building an update site project, create a backup of your <b>build.xml</b> file.
+The update-site project build option will <b>erase</b> every <i>build.xml</i> it
+finds in the features and plugins required by the site -- which leads to lost
+work. </p>
+<p style="word-spacing: 1; margin-top: 0; margin-bottom: 0">To avoid this
+problem, create another ant build-file to hold your customization and use it
+instead of default the &quot;build.xml&quot;.</p>
+<P><SMALL>Java and all Java-based trademarks and logos are trademarks or
+registered trademarks of Sun Microsystems, Inc. in the United States, other
+countries, or both.</SMALL></P></BODY></HTML> \ No newline at end of file
diff --git a/Article-Using EMF/Test.familytree b/Article-Using EMF/Test.familytree
new file mode 100644
index 0000000..8cb53c4
--- /dev/null
+++ b/Article-Using EMF/Test.familytree
@@ -0,0 +1,19 @@
+<com.ibm.example.familytree:FamilyTree xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:com.ibm.example.familytree="http:///com/ibm/example/familytree.ecore">
+ <families mother="//@individuals.0" father="//@families.2/@children.0">
+ <children xsi:type="com.ibm.example.familytree:Female" name="Queen Mary"/>
+ </families>
+ <families mother="//@individuals.1" father="//@families.2/@children.0">
+ <children xsi:type="com.ibm.example.familytree:Female" name="Queen Elizabeth"/>
+ </families>
+ <families mother="//@individuals.2" father="//@families.3/@children.0">
+ <children xsi:type="com.ibm.example.familytree:Male" name="King Henry VIII"/>
+ </families>
+ <families mother="//@individuals.3" father="//@individuals.4">
+ <children xsi:type="com.ibm.example.familytree:Male" name="King Henry VII"/>
+ </families>
+ <individuals xsi:type="com.ibm.example.familytree:Female" name="Catherine of Aragon"/>
+ <individuals xsi:type="com.ibm.example.familytree:Female" name="Anne Boleyn"/>
+ <individuals xsi:type="com.ibm.example.familytree:Female" name="Elizabeth of York"/>
+ <individuals xsi:type="com.ibm.example.familytree:Female" name="Margaret Beaufort"/>
+ <individuals xsi:type="com.ibm.example.familytree:Male" name="Edmund Tudor"/>
+</com.ibm.example.familytree:FamilyTree>
diff --git a/Article-Using EMF/family.mdl b/Article-Using EMF/family.mdl
new file mode 100644
index 0000000..def7d6f
--- /dev/null
+++ b/Article-Using EMF/family.mdl
@@ -0,0 +1,583 @@
+
+(object Petal
+ version 42
+ _written "Rose 4.5.8163.3"
+ charSet 0)
+
+(object Design "Logical View"
+ is_unit TRUE
+ is_loaded TRUE
+ defaults (object defaults
+ rightMargin 0.250000
+ leftMargin 0.250000
+ topMargin 0.250000
+ bottomMargin 0.500000
+ pageOverlap 0.250000
+ clipIconLabels TRUE
+ autoResize TRUE
+ snapToGrid TRUE
+ gridX 16
+ gridY 16
+ defaultFont (object Font
+ size 10
+ face "Arial"
+ bold FALSE
+ italics FALSE
+ underline FALSE
+ strike FALSE
+ color 0
+ default_color TRUE)
+ showMessageNum 1
+ showClassOfObject TRUE
+ notation "Unified")
+ root_usecase_package (object Class_Category "Use Case View"
+ quid "3DDFA8FE0135"
+ exportControl "Public"
+ global TRUE
+ logical_models (list unit_reference_list)
+ logical_presentations (list unit_reference_list
+ (object UseCaseDiagram "Main"
+ quid "3DDFA8FF00F9"
+ title "Main"
+ zoom 100
+ max_height 28350
+ max_width 21600
+ origin_x 0
+ origin_y 0
+ items (list diagram_item_list))))
+ root_category (object Class_Category "Logical View"
+ quid "3DDFA8FE0134"
+ exportControl "Public"
+ global TRUE
+ subsystem "Component View"
+ quidu "3DDFA8FE0136"
+ logical_models (list unit_reference_list
+ (object Class "Male"
+ quid "3DDFA9050364"
+ superclasses (list inheritance_relationship_list
+ (object Inheritance_Relationship
+ quid "3DDFA91B0167"
+ supplier "Logical View::Individual"
+ quidu "3DDFA91202D6")))
+ (object Class "Female"
+ quid "3DDFA90C01FB"
+ superclasses (list inheritance_relationship_list
+ (object Inheritance_Relationship
+ quid "3DDFA91E0229"
+ supplier "Logical View::Individual"
+ quidu "3DDFA91202D6")))
+ (object Class "Individual"
+ quid "3DDFA91202D6"
+ class_attributes (list class_attribute_list
+ (object ClassAttribute "name"
+ quid "3DEE34A90368"
+ type "String"
+ exportControl "Public"))
+ abstract TRUE)
+ (object Class "FamilyTree"
+ quid "3DDFA921035A")
+ (object Class "Family"
+ quid "3DDFA92900E5")
+ (object Association "$UNNAMED$0"
+ quid "3DDFA9320084"
+ roles (list role_list
+ (object Role "$UNNAMED$1"
+ quid "3DDFA9330248"
+ supplier "Logical View::FamilyTree"
+ quidu "3DDFA921035A"
+ is_aggregate TRUE)
+ (object Role "individuals"
+ quid "3DDFA9330249"
+ label "individuals"
+ supplier "Logical View::Individual"
+ quidu "3DDFA91202D6"
+ client_cardinality (value cardinality "0..n")
+ Containment "By Value"
+ is_navigable TRUE)))
+ (object Association "$UNNAMED$2"
+ quid "3DDFA95100E2"
+ roles (list role_list
+ (object Role "$UNNAMED$3"
+ quid "3DDFA9520256"
+ supplier "Logical View::FamilyTree"
+ quidu "3DDFA921035A"
+ is_aggregate TRUE)
+ (object Role "families"
+ quid "3DDFA9520257"
+ label "families"
+ supplier "Logical View::Family"
+ quidu "3DDFA92900E5"
+ client_cardinality (value cardinality "0..n")
+ Containment "By Value"
+ is_navigable TRUE)))
+ (object Association "$UNNAMED$4"
+ quid "3DDFA96D03D2"
+ roles (list role_list
+ (object Role "$UNNAMED$5"
+ quid "3DDFA96E029D"
+ supplier "Logical View::Family"
+ quidu "3DDFA92900E5"
+ is_aggregate TRUE)
+ (object Role "children"
+ quid "3DDFA96E029E"
+ label "children"
+ supplier "Logical View::Individual"
+ quidu "3DDFA91202D6"
+ client_cardinality (value cardinality "0..n")
+ Containment "By Value"
+ is_navigable TRUE)))
+ (object Association "$UNNAMED$6"
+ quid "3DDFA98A024D"
+ roles (list role_list
+ (object Role "father"
+ quid "3DDFA98B03AD"
+ label "father"
+ supplier "Logical View::Male"
+ quidu "3DDFA9050364"
+ client_cardinality (value cardinality "0..1")
+ is_navigable TRUE)
+ (object Role "$UNNAMED$7"
+ quid "3DDFA98B03AE"
+ supplier "Logical View::Family"
+ quidu "3DDFA92900E5")))
+ (object Association "$UNNAMED$8"
+ quid "3DDFA9A70230"
+ roles (list role_list
+ (object Role "mother"
+ quid "3DDFA9A90002"
+ label "mother"
+ supplier "Logical View::Female"
+ quidu "3DDFA90C01FB"
+ client_cardinality (value cardinality "0..1")
+ is_navigable TRUE)
+ (object Role "$UNNAMED$9"
+ quid "3DDFA9A90003"
+ supplier "Logical View::Family"
+ quidu "3DDFA92900E5"))))
+ logical_presentations (list unit_reference_list
+ (object ClassDiagram "Main"
+ quid "3DDFA8FF012A"
+ title "Main"
+ zoom 100
+ max_height 28350
+ max_width 21600
+ origin_x 0
+ origin_y 0
+ items (list diagram_item_list
+ (object ClassView "Class" "Logical View::FamilyTree" @1
+ ShowCompartmentStereotypes TRUE
+ IncludeAttribute TRUE
+ IncludeOperation TRUE
+ location (256, 192)
+ label (object ItemLabel
+ Parent_View @1
+ location (139, 141)
+ fill_color 13434879
+ nlines 1
+ max_width 234
+ justify 0
+ label "FamilyTree")
+ icon_style "Icon"
+ line_color 3342489
+ fill_color 13434879
+ quidu "3DDFA921035A"
+ width 252
+ height 126
+ annotation 8
+ autoResize TRUE)
+ (object ClassView "Class" "Logical View::Individual" @2
+ ShowCompartmentStereotypes TRUE
+ IncludeAttribute TRUE
+ IncludeOperation TRUE
+ location (992, 192)
+ font (object Font
+ italics TRUE)
+ label (object ItemLabel
+ Parent_View @2
+ location (843, 111)
+ fill_color 13434879
+ nlines 1
+ max_width 298
+ justify 0
+ label "Individual")
+ icon_style "Icon"
+ line_color 3342489
+ fill_color 13434879
+ quidu "3DDFA91202D6"
+ compartment (object Compartment
+ Parent_View @2
+ location (843, 171)
+ icon_style "Icon"
+ fill_color 16777215
+ anchor 2
+ nlines 2
+ max_width 294)
+ width 316
+ height 186
+ annotation 8
+ autoResize TRUE)
+ (object AssociationViewNew "$UNNAMED$0" @3
+ location (607, 192)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA9320084"
+ roleview_list (list RoleViews
+ (object RoleView "$UNNAMED$1" @4
+ Parent_View @3
+ location (-241, -304)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA9330248"
+ client @3
+ supplier @1
+ line_style 0)
+ (object RoleView "individuals" @5
+ Parent_View @3
+ location (-241, -304)
+ label (object SegLabel @6
+ Parent_View @5
+ location (700, 151)
+ anchor 1
+ anchor_loc 1
+ nlines 1
+ max_width 216
+ justify 0
+ label "+individuals"
+ pctDist 0.416382
+ height 42
+ orientation 0)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA9330249"
+ client @3
+ supplier @2
+ line_style 0
+ label (object SegLabel @7
+ Parent_View @5
+ location (761, 231)
+ anchor 2
+ anchor_loc 1
+ nlines 1
+ max_width 15
+ justify 0
+ label "0..*"
+ pctDist 0.681416
+ height 39
+ orientation 1))))
+ (object ClassView "Class" "Logical View::Male" @8
+ ShowCompartmentStereotypes TRUE
+ IncludeAttribute TRUE
+ IncludeOperation TRUE
+ location (1152, 464)
+ label (object ItemLabel
+ Parent_View @8
+ location (1071, 413)
+ fill_color 13434879
+ nlines 1
+ max_width 162
+ justify 0
+ label "Male")
+ icon_style "Icon"
+ line_color 3342489
+ fill_color 13434879
+ quidu "3DDFA9050364"
+ height 126
+ annotation 8
+ autoResize TRUE)
+ (object InheritView "" @9
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA91B0167"
+ client @8
+ supplier @2
+ line_style 0)
+ (object ClassView "Class" "Logical View::Female" @10
+ ShowCompartmentStereotypes TRUE
+ IncludeAttribute TRUE
+ IncludeOperation TRUE
+ location (1440, 464)
+ label (object ItemLabel
+ Parent_View @10
+ location (1359, 413)
+ fill_color 13434879
+ nlines 1
+ max_width 162
+ justify 0
+ label "Female")
+ icon_style "Icon"
+ line_color 3342489
+ fill_color 13434879
+ quidu "3DDFA90C01FB"
+ height 126
+ annotation 8
+ autoResize TRUE)
+ (object InheritView "" @11
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA91E0229"
+ client @10
+ supplier @2
+ line_style 0)
+ (object ClassView "Class" "Logical View::Family" @12
+ ShowCompartmentStereotypes TRUE
+ IncludeAttribute TRUE
+ IncludeOperation TRUE
+ location (576, 864)
+ label (object ItemLabel
+ Parent_View @12
+ location (495, 813)
+ fill_color 13434879
+ nlines 1
+ max_width 162
+ justify 0
+ label "Family")
+ icon_style "Icon"
+ line_color 3342489
+ fill_color 13434879
+ quidu "3DDFA92900E5"
+ height 126
+ annotation 8
+ autoResize TRUE)
+ (object AssociationViewNew "$UNNAMED$2" @13
+ location (256, 675)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA95100E2"
+ roleview_list (list RoleViews
+ (object RoleView "$UNNAMED$3" @14
+ Parent_View @13
+ location (-624, -141)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA9520256"
+ client @13
+ supplier @1
+ line_style 3
+ origin_attachment (256, 675)
+ terminal_attachment (256, 255))
+ (object RoleView "families" @15
+ Parent_View @13
+ location (-624, -141)
+ label (object SegLabel @16
+ Parent_View @15
+ location (389, 900)
+ anchor 1
+ anchor_loc 1
+ nlines 1
+ max_width 168
+ justify 0
+ label "+families"
+ pctDist 0.768496
+ height 36
+ orientation 1)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA9520257"
+ client @13
+ supplier @12
+ vertices (list Points
+ (256, 675)
+ (256, 864)
+ (486, 864))
+ line_style 3
+ origin_attachment (256, 675)
+ terminal_attachment (486, 864)
+ label (object SegLabel @17
+ Parent_View @15
+ location (409, 829)
+ anchor 2
+ anchor_loc 1
+ nlines 1
+ max_width 15
+ justify 0
+ label "0..*"
+ pctDist 0.816229
+ height 36
+ orientation 0))))
+ (object AssociationViewNew "$UNNAMED$4" @18
+ location (774, 542)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA96D03D2"
+ roleview_list (list RoleViews
+ (object RoleView "$UNNAMED$5" @19
+ Parent_View @18
+ location (-74, 46)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA96E029D"
+ client @18
+ supplier @12
+ line_style 0)
+ (object RoleView "children" @20
+ Parent_View @18
+ location (-74, 46)
+ label (object SegLabel @21
+ Parent_View @20
+ location (793, 362)
+ anchor 1
+ anchor_loc 1
+ nlines 1
+ max_width 168
+ justify 0
+ label "+children"
+ pctDist 0.543527
+ height 80
+ orientation 0)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA96E029E"
+ client @18
+ supplier @2
+ line_style 0
+ label (object SegLabel @22
+ Parent_View @20
+ location (963, 340)
+ anchor 2
+ anchor_loc 1
+ nlines 1
+ max_width 15
+ justify 0
+ label "0..*"
+ pctDist 0.900000
+ height 54
+ orientation 1))))
+ (object AssociationViewNew "$UNNAMED$6" @23
+ location (1050, 828)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA98A024D"
+ roleview_list (list RoleViews
+ (object RoleView "father" @24
+ Parent_View @23
+ location (426, -180)
+ label (object SegLabel @25
+ Parent_View @24
+ location (1046, 559)
+ anchor 1
+ anchor_loc 1
+ nlines 1
+ max_width 132
+ justify 0
+ label "+father"
+ pctDist 0.916883
+ height 89
+ orientation 0)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA98B03AD"
+ client @23
+ supplier @8
+ vertices (list Points
+ (1050, 828)
+ (1134, 828)
+ (1134, 527))
+ line_style 3
+ origin_attachment (1050, 828)
+ terminal_attachment (1134, 527)
+ label (object SegLabel @26
+ Parent_View @24
+ location (1208, 566)
+ anchor 2
+ anchor_loc 1
+ nlines 1
+ max_width 15
+ justify 0
+ label "0..1"
+ pctDist 0.898701
+ height 74
+ orientation 1))
+ (object RoleView "$UNNAMED$7" @27
+ Parent_View @23
+ location (426, -180)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA98B03AE"
+ client @23
+ supplier @12
+ line_style 3
+ origin_attachment (1050, 828)
+ terminal_attachment (666, 828))))
+ (object AssociationViewNew "$UNNAMED$8" @28
+ location (1218, 878)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA9A70230"
+ roleview_list (list RoleViews
+ (object RoleView "mother" @29
+ Parent_View @28
+ location (594, -130)
+ label (object SegLabel @30
+ Parent_View @29
+ location (1517, 650)
+ anchor 1
+ anchor_loc 1
+ nlines 1
+ max_width 156
+ justify 0
+ label "+mother"
+ pctDist 0.777174
+ height 98
+ orientation 1)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA9A90002"
+ client @28
+ supplier @10
+ vertices (list Points
+ (1218, 878)
+ (1419, 878)
+ (1419, 527))
+ line_style 3
+ origin_attachment (1218, 878)
+ terminal_attachment (1419, 527)
+ label (object SegLabel @31
+ Parent_View @29
+ location (1473, 582)
+ anchor 2
+ anchor_loc 1
+ nlines 1
+ max_width 15
+ justify 0
+ label "0..1"
+ pctDist 0.900000
+ height 54
+ orientation 1))
+ (object RoleView "$UNNAMED$9" @32
+ Parent_View @28
+ location (594, -130)
+ stereotype TRUE
+ line_color 3342489
+ quidu "3DDFA9A90003"
+ client @28
+ supplier @12
+ line_style 3
+ origin_attachment (1218, 878)
+ terminal_attachment (666, 878))))))))
+ root_subsystem (object SubSystem "Component View"
+ quid "3DDFA8FE0136"
+ physical_models (list unit_reference_list)
+ physical_presentations (list unit_reference_list
+ (object Module_Diagram "Main"
+ quid "3DDFA8FF00F8"
+ title "Main"
+ zoom 100
+ max_height 28350
+ max_width 21600
+ origin_x 0
+ origin_y 0
+ items (list diagram_item_list))))
+ process_structure (object Processes
+ quid "3DDFA8FE0137"
+ ProcsNDevs (list
+ (object Process_Diagram "Deployment View"
+ quid "3DDFA8FE013D"
+ title "Deployment View"
+ zoom 100
+ max_height 28350
+ max_width 21600
+ origin_x 0
+ origin_y 0
+ items (list diagram_item_list))))
+ properties (object Properties
+ quid "3DDFA8FE0138"))
diff --git a/Article-Using EMF/family1.zip b/Article-Using EMF/family1.zip
new file mode 100644
index 0000000..d2b5209
--- /dev/null
+++ b/Article-Using EMF/family1.zip
Binary files differ
diff --git a/Article-Using EMF/family2.zip b/Article-Using EMF/family2.zip
new file mode 100644
index 0000000..6463dec
--- /dev/null
+++ b/Article-Using EMF/family2.zip
Binary files differ
diff --git a/Article-Using EMF/images/Idea.jpg b/Article-Using EMF/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Using EMF/images/Idea.jpg
Binary files differ
diff --git a/Article-Using EMF/images/customized.JPG b/Article-Using EMF/images/customized.JPG
new file mode 100644
index 0000000..cdfe8f1
--- /dev/null
+++ b/Article-Using EMF/images/customized.JPG
Binary files differ
diff --git a/Article-Using EMF/images/customized.bmp b/Article-Using EMF/images/customized.bmp
new file mode 100644
index 0000000..15f5302
--- /dev/null
+++ b/Article-Using EMF/images/customized.bmp
Binary files differ
diff --git a/Article-Using EMF/images/familytree.JPG b/Article-Using EMF/images/familytree.JPG
new file mode 100644
index 0000000..e9e29a9
--- /dev/null
+++ b/Article-Using EMF/images/familytree.JPG
Binary files differ
diff --git a/Article-Using EMF/images/labels.JPG b/Article-Using EMF/images/labels.JPG
new file mode 100644
index 0000000..e77abbc
--- /dev/null
+++ b/Article-Using EMF/images/labels.JPG
Binary files differ
diff --git a/Article-Using EMF/images/labels.bmp b/Article-Using EMF/images/labels.bmp
new file mode 100644
index 0000000..722212d
--- /dev/null
+++ b/Article-Using EMF/images/labels.bmp
Binary files differ
diff --git a/Article-Using EMF/images/linux_only.gif b/Article-Using EMF/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-Using EMF/images/linux_only.gif
Binary files differ
diff --git a/Article-Using EMF/images/model.bmp b/Article-Using EMF/images/model.bmp
new file mode 100644
index 0000000..7b735f3
--- /dev/null
+++ b/Article-Using EMF/images/model.bmp
Binary files differ
diff --git a/Article-Using EMF/images/sample.JPG b/Article-Using EMF/images/sample.JPG
new file mode 100644
index 0000000..87fcb2e
--- /dev/null
+++ b/Article-Using EMF/images/sample.JPG
Binary files differ
diff --git a/Article-Using EMF/images/sample.bmp b/Article-Using EMF/images/sample.bmp
new file mode 100644
index 0000000..7be17d5
--- /dev/null
+++ b/Article-Using EMF/images/sample.bmp
Binary files differ
diff --git a/Article-Using EMF/images/tag_1.gif b/Article-Using EMF/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-Using EMF/images/tag_1.gif
Binary files differ
diff --git a/Article-Using EMF/images/tag_2.gif b/Article-Using EMF/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-Using EMF/images/tag_2.gif
Binary files differ
diff --git a/Article-Using EMF/images/tag_3.gif b/Article-Using EMF/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-Using EMF/images/tag_3.gif
Binary files differ
diff --git a/Article-Using EMF/images/tag_4.gif b/Article-Using EMF/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-Using EMF/images/tag_4.gif
Binary files differ
diff --git a/Article-Using EMF/images/tag_5.gif b/Article-Using EMF/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-Using EMF/images/tag_5.gif
Binary files differ
diff --git a/Article-Using EMF/images/tag_6.gif b/Article-Using EMF/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-Using EMF/images/tag_6.gif
Binary files differ
diff --git a/Article-Using EMF/images/tag_7.gif b/Article-Using EMF/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-Using EMF/images/tag_7.gif
Binary files differ
diff --git a/Article-Using EMF/images/testdata.JPG b/Article-Using EMF/images/testdata.JPG
new file mode 100644
index 0000000..a3a333a
--- /dev/null
+++ b/Article-Using EMF/images/testdata.JPG
Binary files differ
diff --git a/Article-Using EMF/images/testdata.bmp b/Article-Using EMF/images/testdata.bmp
new file mode 100644
index 0000000..b39e821
--- /dev/null
+++ b/Article-Using EMF/images/testdata.bmp
Binary files differ
diff --git a/Article-Using EMF/images/tip.gif b/Article-Using EMF/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Using EMF/images/tip.gif
Binary files differ
diff --git a/Article-Using EMF/images/tryit.gif b/Article-Using EMF/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Using EMF/images/tryit.gif
Binary files differ
diff --git a/Article-Using EMF/images/win_only.gif b/Article-Using EMF/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-Using EMF/images/win_only.gif
Binary files differ
diff --git a/Article-Using EMF/using-emf.html b/Article-Using EMF/using-emf.html
new file mode 100644
index 0000000..e645823
--- /dev/null
+++ b/Article-Using EMF/using-emf.html
@@ -0,0 +1,504 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.6 [en] (WinNT; I) [Netscape]">
+ <title>Using EMF</title>
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+<body link="#0000FF" vlink="#800080">
+
+<div align=right>&nbsp; <font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2002 International Business Machines Corp.</font></font></div>
+&nbsp;
+<div ALIGN=right><table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table></div>
+
+<h1>
+<img SRC="images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+Using EMF</h1></center>
+
+<blockquote><b>Summary</b>
+<br>
+ This article introduces EMF, the Eclipse Modelling Framework, and will help
+ you get started using EMF in your own Eclipse plug-ins.
+ <p><b>By Catherine Griffin, IBM</b><br>
+ <font size=-1>December 9, 2002 (revised May 2003 for EMF 1.1.0)</font></blockquote>
+
+<hr width="100%">
+<h1>
+What is EMF, and why would I want to use it ?</h1>
+EMF, the Eclipse Modelling Framework, is used to define and implement structured
+data models. A data model is simply a set of related classes used to handle
+the data which you want to deal with in your application.
+<h2>
+Some good reasons to use EMF</h2>
+
+<ol>
+<li>
+<b>Code generation.</b> All the code needed for a working data model is generated for you,
+based on a definition of the model. EMF generates nice readable code, from template files
+that can be customized. You can customize the generated code, and your
+changes won't be lost when the classes are regenerated. The input to code
+generation can be a Rational Rose model file, annotated Java interfaces,
+or an XML schema definition (under development).</li>
+
+<li>
+<b>Meta-data.</b> You can programatically query the structure of a model, and
+get more information than the standard Java BeanInfo or reflection would
+allow. EMF also supports accessing and updating models reflectively.</li>
+
+<li>
+<b>Default serialization.</b> EMF can load and save instances of your model as
+XMI (an XML format). If you need to save your data in a different format,
+you can do so. XML schema as a file format is under development.</li>
+
+<li>
+<b>Links between files.</b> You can save and edit data across multiple files.</li>
+
+<li>
+<b>Editors.</b> EMF will also generate an editor for your model,
+complete with content outline and property sheet. There is also a reflective editor,
+which can view and edit any EMF model file, using only the model meta-data.
+It provides similar function to the default generated editor, but it can't be easily
+customized.
+</li>
+</ol>
+For more information see the <a href="http://www.eclipse.org/emf" target="_blank">EMF
+project page</a>.
+<p>If you want to try the example from this article, you will need EMF
+and a suitable version of Eclipse (I am using 2.1). EMF version 1.1.0
+Build 20030501_0612VL was used to generate the example code.
+<h1>
+Developing an Eclipse plug-in using EMF</h1>
+
+<h2>
+The Example</h2>
+The example used in this article is an editor for family trees.
+
+<h2>
+Step 1: Designing the model</h2>
+The first step is to design the data model for the application - that is, the
+structure of the data we want to be able to view and edit, and the relationships
+between data items. You may find a UML tool useful, or a piece of paper. For this
+application, the main information needed is who had which children. In UML, the
+data structure looks like this:
+<p align="center"><img src="images/familytree.JPG"></p>
+A FamilyTree contains families and individuals. Individuals are either Male or
+Female - Individual itself is an abstract class. A Family contains children and
+is linked to a mother and father.
+<p>In addition to these types of relations, EMF will handle multi-valued
+references, two-way relationships (navigable both ways), enumerations and
+data types (Java objects which aren't EMF based, serialized as strings).
+<h2>
+Step 2: Defining the model</h2>
+The next step is to define the model to EMF so that code can be generated.
+If you have Rational Rose, EMF can generate the implementation of your
+model directly from the Rose mdl file. See the EMF tutorial for details.
+<p>It is also possible to generate the model code from annotated Java interfaces.
+and that is what is described below. If you don't want to do any typing,
+just create a new Java project in Eclipse, import <a href="family1.zip">family1.zip,</a>
+and skip to Step 3. Otherwise proceed as follows:
+<ol>
+<li>
+In Eclipse, create a new Java project and a package for the interfaces.
+I am calling my project <b>com.ibm.example.familytree</b> and my package
+<b>com.ibm.example.familytree</b>.</li>
+
+<li>
+Create new Java interfaces called FamilyTree and Family in this package.
+In the Javadoc comment for each interface, add a line with the tag <b>@model</b>.
+This tells EMF that this interface is part of your model.</li>
+
+<li>
+A Java interface is also needed for Individual, but this needs an extra
+piece of information in the Javadoc comment because Individual needs to
+be treated as an abstract class. Add the tag <b>@model abstract="true"</b>.</li>
+
+<li>
+Next create the interfaces Male and Female, each extending Individual.&nbsp;
+Again add the <b>@model</b> tag.</li>
+</ol>
+
+<h3>
+Defining Attributes</h3>
+Individuals have names, so we need to add the attribute 'name' to the Individual
+interface. Just add a method as follows:
+<pre>&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Return the individuals name.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return the name
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @model
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **/
+&nbsp;&nbsp;&nbsp;&nbsp; String getName();</pre>
+Again, the <b>@model</b> tag tells EMF that this method needs some code
+generated. If you add methods to the interface that don't have the <b>@model</b>
+tag, EMF will not generate implementations of those methods, so you will
+have to implement them yourself. Sometimes it makes sense to do this -
+for example, you might want to add some convenience methods to the model
+interfaces.
+<h3>
+Defining simple references</h3>
+A Family should have references to a mother and a father. Add the following
+methods to the Family interface:
+<pre>&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Return the father
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return the father
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @model
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **/
+<img SRC="images/tag_1.gif" height=13 width=24 align=CENTER>&nbsp; Male getFather();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Return the mother
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return the mother
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @model
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **/
+&nbsp;&nbsp;&nbsp;&nbsp; Female getMother();</pre>
+Notice that the method&nbsp;<img SRC="images/tag_1.gif" height=13 width=24 align=CENTER>
+is very similar to how an attribute is defined.
+<h3>
+Defining containment relations</h3>
+In the UML model above, the links with black diamonds on them are containment
+relations. For example, an Individual can be contained either by a Family
+or by a FamilyTree. An object can only have one container. For example,
+the relations between Family and Individual defined in the previous section
+are not containment relations - because people can be married more than
+once (even if generally not at the same time).
+<p>When instances of this model are created using the editor generated
+by EMF, there will be a single top-level FamilyTree object and all the
+other objects in the model will be contained by it, directly or indirectly.
+The model cannot be saved correctly if there are objects which have no
+container.
+<p>Add the following methods to FamilyTree to define its containment relations:
+<pre>&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Return a list of contained families
+<img SRC="images/tag_2.gif" height=13 width=24 align=CENTER>&nbsp;&nbsp; * @model type="Family" containment="true"
+&nbsp;&nbsp;&nbsp;&nbsp; **/
+&nbsp;&nbsp;&nbsp;&nbsp; java.util.List getFamilies();
+&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Return a list of contained individuals
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @model type="Individual" containment="true"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **/
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.util.List getIndividuals();
+</pre>
+Unlike the simple references defined in the previous section, these methods
+return Lists - thats because a FamilyTree can contain multiple Families
+and Individuals. The return type must be java.util.List or org.eclipse.emf.common.util.EList
+so that EMF recognizes that this is meant to be multi-valued. Notice the
+<b>@model</b> tag&nbsp;<img SRC="images/tag_2.gif" height=13 width=24 align=CENTER>
+declares the type of object that can appear in the List. In addition, the
+flag <b>containment="true"</b> indicates that this is a containment relation.
+<p>There is one other containment relation to define, in Family:
+<pre>&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Return children
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return list of child Individuals
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @model type="Individual" containment="true"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **/
+&nbsp;&nbsp;&nbsp;&nbsp; java.util.List getChildren();</pre>
+
+<h2>
+Step 3: Generating the model</h2>
+Now that the model has been defined, we can proceed to generate the model
+implementation.
+<ol>
+<li>
+In the File menu, select <b>New > Other...</b></li>
+
+<li>
+In the New File wizard, select <b>Ecore Model Framework</b> in the left-hand
+panel and <b>GenModel model</b> in the right-hand panel, then click <b>Next</b>.</li>
+
+<li>
+On the next page, select your project source folder, enter a filename with
+file type "genmodel", and click <b>Next</b>.</li>
+
+<li>
+Select the <b>Load from Java annotations</b> radio button and click <b>Finish</b>.
+Two new files will be created in your project folder, one is called <b>familytree.ecore</b>
+(this is an XMI file which contains a definition of the family tree model) and the other is the
+genmodel file which you entered a name for. The genmodel file contains additional information about
+how EMF should generate code for the model. The genmodel file is opened for editing.
+</li>
+
+<li>
+In the editor, select the root (first) node of the tree and right-click
+to bring up the popup menu.</li>
+
+<li>
+Select <b>Generate Model</b> to generate the model implementation code.</li>
+</ol>
+<p>
+Two new packages will be generated in your project, <b>com.ibm.example.familytree.impl</b> and
+<b>com.ibm.example.familytree.util</b>.
+If you look now at the original package <b>com.ibm.example.familytree</b>, you will find that
+two new interfaces called FamilytreeFactory and FamilytreePackage have appeared. These are used to
+programmatically create model elements and to query meta-data, respectively.
+At the same time as generating the model implementation, EMF has also made some changes to the other interfaces
+in this package. If you look at Family.java for example, you will see that the return type java.util.List
+has been changed to EList and that the interface now extends EObject. These changes are needed so that
+the generated model code works correctly.
+
+
+
+<h2>
+Step 4: Generating an editor</h2>
+The popup menu in the GenModel editor has four generation options:
+<ul>
+<li>
+<b>Generate Model</b> - generates the model implementation code, as you
+have just seen.</li>
+
+<li>
+<b>Generate EMF.Edit </b>- generates an extra plug-in containing adapter
+classes needed by the generated editor.</li>
+
+<li>
+<b>Generate EMF.Editor</b> - generates an editor plug-in for your model.</li>
+
+<li>
+<b>Generate All </b>- generates the model, edit plug-in and editor.</li>
+</ul>
+Since we have already generated the model, to generate the editor we need
+to first generate the EMF.Edit plug-in, then the EMF.Editor plug-in. This
+creates two new plug-in projects called <b>com.ibm.example.familytree.edit</b>
+and <b>com.ibm.example.familytree.editor</b>.
+<h2>
+Step 5: Trying out the generated plug-ins</h2>
+The generated editor can be used as a starting point for developing your
+application. However, resist the temptation to immediately start working
+on fancier views. First use the generated editor to check that your data
+model is able to cope with some sample data. If you find problems, you
+can then redesign the data model and repeat the process until you are happy
+with it. Its much easier to change your model now, than it would be after
+you have put a lot of work into the editor.
+<p>To run the example editor, you need to start a runtime workbench, making
+sure that it will be launched with the three generated plug-ins. If you
+aren't sure how to do this, see the EMF tutorial.
+<p>Once the workbench has started, you need to create a model file:
+<ol>
+<li>
+Create a new simple project</li>
+
+<li>
+Select from the menu <b>File > New > Other...</b></li>
+
+<li>
+Select <b>Example EMF Model Creation Wizards</b> and <b>Familytree Model</b>,
+and click
+<b>Next</b></li>
+
+<li>
+Select the new project, and enter a filename for the new file. The file
+should have the extension 'familytree'. Click Next.</li>
+
+<li>
+From the combo box, select <b>FamilyTree</b>, then click <b>Finish</b>.</li>
+</ol>
+The new file will be opened with the editor. This is a multipage editor,
+each page demonstrating different ways of displaying data from your model.
+The first page is a tree view, the root of the tree being the file you
+are editing. Expand the root and you will see a FamilyTree element - thats
+what the wizard created in the file. Select FamilyTree and right-click
+to bring up the popup menu. The menu allows you to add child elements -
+Family, Female or Male.
+<p>Add a Female or Male to the FamilyTree. If the Properties view is showing,
+you should see the properties for the Individual - there is only one: name.
+Set the name to something meaningful, and the label in the tree view will
+change.
+<p>When you add children to a Family, they appear as child items in the
+tree. You can use the properties view to set the mother and father for
+a Family, but setting these doesn't change the tree, because mothers and
+fathers are linked to families, not contained by them.
+<p>This is what the editor looks like when I have put in some test data:
+<p align="center"><img SRC="images/testdata.JPG"></p>
+
+<p>The test family tree shown here is in the file <a href="Test.familytree">Test.familytree</a>.
+This is an XMI file. By default, EMF uses XMI (a form of XML) to save model instance data.
+If you need to save your data in a different format, you can write code to do so.
+<h2>
+Anatomy of the EMF Editor</h2>
+As you can see, the editor generated by EMF does quite a lot. The content
+outline view (bottom left in the above image) shows the contents of the
+file you are editing as a tree view. Whatever element is selected in the
+content outline view is also shown selected on the first page of the editor,
+which is a similar tree view. Whenever you select an element either in
+the editor or in the outline, its properties are shown in the properties
+view. The properties view lets you edit all that elements attributes and
+any single-valued references to other model elements (by picking from all
+the available elements of the right type).
+<p>You can drag and drop elements to move them, and cut, copy and paste, delete,
+undo and redo edit actions are supported.
+<p>The other pages of the editor are -
+<ul>
+<li>
+<b>Parent </b>- whatever element is selected in the outline view, this
+tree view shows you how that element is contained.</li>
+
+<li>
+<b>List</b> - this page shows a list of elements contained by the selected
+element.</li>
+
+<li>
+<b>Tree</b> - same thing again, in a tree view</li>
+
+<li>
+<b>Table</b> - a table view of the children of the selected model element.</li>
+
+<li>
+<b>TableTree</b> - same again, using a table tree control.</li>
+</ul>
+
+<h1>
+Next steps</h1>
+You might decide at this point that some changes to the model are needed.
+For example, say I want to add a description attribute to Individual so
+I can add additional biographical information. I would edit the Individual
+interface as before and add the method:
+<pre>&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Return a description.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return a description
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @model
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **/
+&nbsp;&nbsp;&nbsp;&nbsp; String getDescription();</pre>
+Then to update the genmodel file, right-click on it to bring up the popup
+menu, and select <b>Reload...</b>. You will also need to regenerate all
+the generated code. If you make changes to the generated code, then remember
+to take out the <b>@generated</b> flag from the Javadoc so that your changes
+are not overwritten.
+<p>The generated editor is meant to be a starting point for your own development
+and a demonstration of the reusable user interfaces parts provided in EMF.&nbsp;
+Once you are satisfied that your model is how you want it to be, you can
+start customizing the generated editor, or writing your own.
+<h2>
+Source code</h2>
+To run the customized versions of the family tree plug-ins, unzip <a href="family2.zip">family2.zip</a>
+into your <i>plugins/ </i>subdirectory. All the source code is included.
+The customized editor has only two pages, the original first page and a
+modified table tree view. For details of the changes see the sections below.
+<h2>
+Labels and Images</h2>
+To change the labels that are used in the editor, you need to go and find
+the adapter classes generated in the <b>com.ibm.example.familytree.edit</b>
+project. In the package <b>com.ibm.example.familytree.provider</b>, there
+is one adapter class for each model class. The methods <b>getText</b> and
+<b>getImage</b> determine the label and image that are used in the editor.
+<p>If you change the <b>getText</b> method, remember to remove the <b>@generated</b>
+flag from the method javadoc comment so that your changes will be kept
+if you regenerate the code.
+<p>To change the icons, you can just change the gifs that are in the <i>icons</i>
+folder in this plug-in project.
+<p>In the customized version of the family tree .edit plug-in, the getText
+ methods have been changed in FamilyItemProvider, IndividualItemProvider, FemaleItemProvider
+ and MaleItemProvider. For example, here's the code from IndividualItemProvider:
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getText(Object object) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Individual individual = (Individual)object;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( individual.getName() == null )
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "Unnamed individual";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return individual.getName();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+
+<h2>
+Trees</h2>
+The simplest tree view is the one used for the generated editors
+content outline view and the selection tree view. The content provider
+for this is <b>org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider</b>,
+which uses the generated adapter classes from <b>com.ibm.example.familytree.edit</b>.
+The children of each element are the elements it contains.
+<p>You can create different tree views by writing your own content provider.
+However, make sure that you won't have the same element appearing twice
+in the tree as this will cause problems. The tree viewer assumes that each
+domain element maps to one tree item. If you need to show referenced elements
+in a tree, you will have to wrap them. Other structured viewers (tables
+and lists) behave the same way.
+<p>In the customized version of the family tree editor, I have changed
+the input of the content outline view so that the root of the tree is now
+FamilyTree instead of the resource (file), and changed the root and title
+of the selection tree view.
+<p>I have added the inner class ParentAdapterFactoryContentProvider in place of
+ ReverseAdapterFactoryContentProvider. This returns the parents of a child as
+ the tree 'children', resulting in a tree showing parents, grandparents, great-grandparents
+ etc. Here's how the getChildren method is implemented:
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object [] getChildren(Object object) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object parent = super.getParent(object);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( parent instanceof Family ){
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List parents = new ArrayList();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( ((Family)parent).getMother() != null )
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parents.add( ((Family)parent).getMother() );
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( ((Family)parent).getFather() != null )
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parents.add( ((Family)parent).getFather() );
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return parents.toArray();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Object[0];
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+
+</pre>
+
+<h2>
+Tables</h2>
+Table viewers require a content provider and a table label provider.
+<b>org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider</b>
+implements the <b>org.eclipse.jface.viewers.ITableLabelProvider</b> interface,
+but it delegates the real work to the generated adapter classes. Modify
+these to implement the <b>org.eclipse.emf.edit.provider.ITableItemLabelProvider</b>
+interface.
+Then change the constructor of FamilytreeItemProviderAdapterFactory so
+that it knows it can supply a table item label provider.
+<P>You will also need to set up the table with the right columns;
+in the generated editor this is done in the createPages method.
+<p>The second page of the editor is now a table tree, using the content
+provider described above. It shows parents of children. I have defined
+three columns - Parents, Father and Mother. You can expand items in the
+first column to see parents of parents.
+<p>I modified IndividualItemProvider so that it implements ITableItemLabelProvider.
+ The second column shows the individuals father, the third column their mother.
+ Here's how the method getColumnText is implemented in IndividualItemProvider:
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getColumnText(Object o, int index ){
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( index == 0 ){
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getText(o);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else{
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object f = getParent(o);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( f instanceof Family ){
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( index == 1 &amp;&amp; ((Family)f).getFather() != null ){
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // father
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getText(((Family)f).getFather());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if( index == 2 &amp;&amp; ((Family)f).getMother() != null ){
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // mother
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getText(((Family)f).getMother());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "unknown";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+<p>Heres the customized version of the editor, showing the table tree:
+<p align="center"> <img SRC="images/customized.JPG"></p>
+<h2>
+Menus</h2>
+The generated ActionBarContributor is responsible for the popup menus,
+toolbar and menu bar items. The popup menu contents depend only on the
+selected elements, not the active viewer.
+<p>The menu items New Child and New Sibling are somewhat confusing in
+this context, so I have changed the ActionBarContributor to just have the
+submenu Add New, with menu items Family, Male, Female.
+<h1>
+Conclusions</h1>
+This article has introduced the process of plug-in development using EMF
+and shown how to start customizing the EMF generated editor code for your
+own use. By using EMF in your own plug-ins you can benefit from reusing
+user interface parts that are based on EMF. When you are familiar with
+the framework, you can quickly build functional new editors and views.
+<p>For more information about EMF, see the EMF tutorial (in the Eclipse Help for
+EMF), documentation, and the EMF newsgroup (<a href="news://www.eclipse.org/eclipse.tools.emf">news://www.eclipse.org/eclipse.tools.emf</a>).
+<p>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries,
+or both.
+</body>
+</html>
diff --git a/Article-Using Images In Eclipse/Using Images In Eclipse.html b/Article-Using Images In Eclipse/Using Images In Eclipse.html
new file mode 100644
index 0000000..5bdda28
--- /dev/null
+++ b/Article-Using Images In Eclipse/Using Images In Eclipse.html
@@ -0,0 +1,355 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
+ <title>Using Images in the Eclipse UI</title>
+<link rel="stylesheet" href="../default_style.css">
+</head>
+<body>
+
+<div align=right>&nbsp; <font face="Times New Roman, Times, serif"><font size=-1>Copyright
+ &copy; 2001, 2002 Object Technology International, Inc.</font></font></div>
+
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table>
+
+<h1> <img SRC="../images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+Using Images in the Eclipse UI</h1></center>
+
+<blockquote><b>Summary</b>
+<br>
+ Managing images in a large graphical application can be a daunting task. Since
+ modern operating systems such as Windows&reg; only support a small number of images
+ in memory at once, an application’s icons and background images must be carefully
+ managed and sometimes shared between widgets. This article describes the image
+ management facilities provided by the Eclipse Platform, along with some best
+ practice guidelines to keep in mind when writing your own Eclipse UI plug-ins.
+ We assume the reader already has a basic understanding of Eclipse, the UI extension
+ points defined by the Eclipse Platform, and the Standard Widget Toolkit (SWT).
+ <p><b>By John Arthorne, OTI</b><br>
+ April 20, 2001; updated September 12, 2002 for Eclipse 2.0</blockquote>
+
+<h2> The Usual Suspects </h2>
+<p>We begin by describing the interesting classes to know about when writing UI
+ plug-ins that define their own images. Just about anybody writing substantial
+ UI components for a plug-in needs to understand these basic image management
+ objects. </p>
+<p>
+ <ul>
+ <li>
+ <p><b><tt>org.eclipse.swt.graphics.Image</tt></b>. Instances of <tt>Image</tt>
+ are ready for display on the screen. They have all their data in memory,
+ and they maintain a handle to an underlying OS resource. These are heavy-weight
+ objects that generally should not be held onto indefinitely. When no longer
+ needed, the user must call <tt>dispose()</tt> on the Image to free the
+ underlying resource. The crucial point to understand here is that these
+ objects are very expensive to leave lying around. The operating system
+ typically only allows a fixed number of images at once. For example, Windows
+ 98 only allows about 1000 images in memory before it begins to fail. Whenever
+ you create an instance of Image, think about how long it will be needed,
+ and make sure that a mechanism is in place to dispose of it when no longer
+ needed. You <b>cannot</b> rely on the Java&trade; garbage collector to do this
+ for you, since Images reference memory allocated by the OS, not the Java
+ virtual machine.&nbsp; An interesting characteristic of Images is that
+ one <tt>Image</tt> instance can be placed in multiple widgets, a technique
+ called image sharing.&nbsp; A major challenge of image management is to
+ take advantage of this sharing as much as possible, but to still know
+ when it is safe to dispose the image.</p>
+ </li>
+ <li> <b><tt>org.eclipse.jface.resource.ImageDescriptor</tt></b>. These objects
+ are very light-weight descriptions of images. They know how to find the
+ image data and load the image into memory, but they do not hold onto any
+ large structures themselves. There are a number of factory methods on ImageDescriptor
+ for creating descriptors from Java resource files, normal files, and URLs.
+ It is okay to create ImageDescriptors for all the images in your plug-in,
+ and keep them around for the lifetime of the UI.&nbsp; An SWT Image can
+ be created from an ImageDescriptor by calling its <tt>createImage</tt> method.&nbsp;
+ Each call to createImage returns a new instance of Image, and it is the
+ caller's responsibility to ensure that the created image gets disposed.</li>
+ <li> <b><tt>org.eclipse.jface.resource.ImageRegistry</tt></b>. Some images are
+ used very frequently by a plug-in, and are worth placing in a global pool
+ so that they can be shared and reused throughout the UI. These images should
+ be placed in your plug-in's ImageRegistry. It is important to keep the number
+ of images in your registry small, so that you don't unnecessarily hog OS
+ resources that may be needed by other plug-ins.</li>
+ </ul>
+ As a general rule of thumb, ImageDescriptors should be used wherever possible
+in your UI code.&nbsp; However, in places where you are creating real widgets,
+such as subclasses of <tt>org.eclipse.swt.widgets.Widget</tt>, or <tt>org.eclipse.jface.window.Window</tt>,
+you need to be manipulating SWT images.&nbsp; Generally, the code that creates
+the widget should also create the Images to go in it, and the code that disposes
+the widget should also dispose of its images.&nbsp; An exception to this rule
+is if you are using Images that are shared between multiple widgets.&nbsp; Image
+sharing should be approached with caution, because as we discussed earlier, sharing
+makes it difficult to figure out when to dispose of the images.&nbsp; <tt>org.eclipse.jface.viewers.ILabelProvider</tt>
+(described later), and <tt>org.eclipse.jface.resource.ImageRegistry</tt>, are two
+mechanisms provided by JFace that help to achieve image sharing in a controlled
+manner.
+<h2>Defining Images Through Your plugin.xml File</h2>
+ The simplest and most frequent way images get added to a UI plug-in is via their
+ plugin.xml file.&nbsp; Many UI extension points allow an image filename to be
+ provided directly in your extension definition, namely:
+ <ul>
+ <li> "actions" elements on the org.eclipse.ui.actionSets extension point</li>
+ <li> "editor" elements on the org.eclipse.ui.editors extension point</li>
+ <li> "action" elements on the org.eclipse.ui.editorActions extension point</li>
+ <li> "wizard" elements on the org.eclipse.ui.newWizards extension point</li>
+ <li> "wizard" elements on the org.eclipse.ui.importWizards extension point</li>
+ <li> "wizard" elements on the org.eclipse.ui.exportWizards extension point</li>
+ <li> "perspective" elements on the org.eclipse.ui.perspectives extension point</li>
+ <li> "action" elements on the org.eclipse.ui.popupMenus extension point</li>
+ <li> "page" elements on the org.eclipse.ui.propertyPages extension point</li>
+ <li> "action" elements on the org.eclipse.ui.viewActions extension point</li>
+ <li> "view" elements on the org.eclipse.ui.views extension point</li>
+ <li> "image" elements on the org.eclipse.ui.projectNatureImages extension point (since Eclipse 2.0)</li>
+ <li> "workingSet" elements on the org.eclipse.ui.workingSets extension point (since Eclipse 2.0)</li>
+
+
+ </ul>
+ For all of these element types, the way you specify images is the same.&nbsp;
+There is an attribute called "icon", whose value must be an image filename relative
+to your plug-in's install location.&nbsp; To give a quick example, here is an
+XML definition of an import wizard, taken from the extension point documentation:
+<pre><tt>&lt;extension</tt>
+ <tt>point="org.eclipse.ui.import"></tt>
+<tt>&nbsp;&nbsp; &lt;wizard</tt>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="com.xyz.ImportWizard1"</tt>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="XYZ Web Scraper"</tt>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="com.xyz.imports.ImportWizard1"</tt>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icon="./images/import1.gif"></tt>
+<tt>&nbsp;&nbsp; &lt;/wizard></tt>
+<tt>&lt;/extension></tt> </pre>
+<p>Here, the wizard is given an image called "import1.gif", found in a subdirectory
+ of the plug-in's base directory called "images".&nbsp; See the documentation
+ for each of the above extension points for more details and examples of their
+ use. </p>
+<p>There are many advantages to specifying images directly in your XML file, over
+ defining images programmatically in your UI code:
+<ul>
+ <li> You can let the Platform worry about loading the image, storing it, and
+ disposing of it when no longer needed, which means less code and less bugs
+ for you to worry about.</li>
+ <li> Most of your image filenames are encoded in one place, making it easier
+ to change and modify them.</li>
+ <li> Your plug-in will take advantage of the Platform's lazy plug-in loading
+ mechanism.&nbsp; Your classes and images will only be loaded when they are
+ referenced by the user, and not before.&nbsp; In fact, this is why extension
+ points always ask for a name and icon for your actions, views, etc.&nbsp;
+ That way, the Platform can present them in menus and toolbars without having
+ to load your classes until they are really needed.</li>
+ </ul>
+ <h2> Adding Images to Custom UI</h2>
+ You have begun experimenting with platform extension points, maybe contributing
+ some actions to popup menus or toolbars, or maybe you've even defined your own
+ custom view. In many of these cases, specifying an image file in the XML file
+ for your plug-in is all that is required, and the Platform takes care of the
+ rest.&nbsp; However, when you move on to writing more advanced UI components,
+ you may need to define images from within your code.&nbsp; The following example
+ demonstrates the simplest way to define images within UI code. In this example
+ we have a UI plug-in called MyPlugin, and some action called MyAction. We would
+ like to associate an image with MyAction.
+ <p>Step 1: Create an image using your favorite image editing program. For action
+ icons, the recommended format is a 16x16 pixel image in the GIF format. For
+ this example, we'll call the image "my_action.gif", and place it in a subdirectory
+ of the plug-in base directory called "images".
+ <p>Step 2: Define an ImageDescriptor in your MyAction class. It's a good idea
+ to make this field static so that it can be shared across instances of the
+ action.
+
+<pre>public class MyAction extends Action {
+ private static ImageDescriptor image;
+ static {
+ URL url = null;
+ try {
+ url = new URL(MyPlugin.getInstance().getDescriptor().getInstallURL(),
+ "images/my_action.gif");
+ } catch (MalformedURLException e) {
+ }
+ image = ImageDescriptor.createFromURL(url);
+ }
+ ... other methods and fields defined here ...
+}
+ </pre>
+ <p>Because plug-ins can be stored anywhere, we use URLs to describe their location.
+ The image location will always be the same relative to the plug-in location,
+ so we use that as the base of the image's URL. We then use the factory method
+ defined on the ImageDescriptor class to create our descriptor. The method
+ ImageDescriptor#createFromURL() will handle the case where a null URL is passed
+ to it, so we don't need to handle the possible URL exception. Images that
+ could not be loaded are visible in the UI as small red squares. If you see
+ a red square next to your action in the popup menu, it probably means you
+ got the image location wrong, or the image is missing.
+ <p>Step 3: Set the ImageDescriptor as the action's image in the constructor:
+
+<pre>public MyAction() {
+ super("My Action", image);
+}</pre>
+<p>That's it! Now, when you startup the Eclipse UI and find your action in a menu
+ or toolbar, your image will appear next to it. The same approach can be used
+ to define images within custom views and wizards.&nbsp; Note that since you
+ only had to deal with ImageDescriptors in this example, no disposal was required.&nbsp;
+ In this case the platform is responsible for creating, managing, and disposing
+ any SWT Image it creates from the image descriptor you supplied. </p>
+<h2> Viewers and Label Providers</h2>
+ Adding images to actions and view titles is fairly simple in Eclipse. In these
+cases, the platform handles the creation and management of the real, underlying
+SWT image. When you start to add your own objects to viewers, things get a little
+bit more complicated. This is mainly because many objects in viewers tend to have
+the same icon. For example, all files in the Navigator have the same icon, as
+do all public Java fields in the Java Development Tooling (JDT) views. To make
+this efficient, we want to reuse the same SWT image object for all these items.
+This is accomplished by creating a label provider for your viewer.
+<p>You can think of label providers as containing a pool of images that lasts
+ for the lifetime of a particular viewer.&nbsp; They allow the same SWT Images
+ to be reused throughout the time that viewer's widget is open.&nbsp; Note
+ that ILabelProviders don't provide a way to share the same Image across multiple
+ viewers, which is fine because there are rarely more than a couple of viewers
+ open at any given time that could share images anyway.&nbsp; Generally, sharing
+ images across multiple viewers introduces a great deal of complexity for very
+ little gain.
+ <p>To give you an idea of how ILabelProviders work, it is instructive to step
+ through the lifetime of an ILabelProvider instance.
+ <ul>
+ <li> <b>Creation:</b> The code that creates a viewer instance should also
+ create an instance of ILabelProvider to supply images for objects in that
+ viewer.&nbsp; The label provider is then set into the viewer by calling
+ <tt>org.eclipse.jface.viewer.ContentViewer#setLabelProvider(IBaseLabelProvider)<b>.
+ </b></tt><b>Important:</b>&nbsp; Once a label provider has been set into
+ a viewer, that viewer takes over ownership of the instance.&nbsp; A label
+ provider instance must never be passed to another viewer, or have any of
+ its methods invoked, once it has been allocated to a viewer.</li>
+ <li> <b>Disposal:</b>&nbsp; The viewer is responsible for invoking dispose()
+ on its label provider when the underlying widget is closed.&nbsp; This <tt>dispose()</tt>
+ method must dispose of any images that were ever dispensed by that label
+ provider instance.</li>
+ </ul>
+ Now that you have an idea of how label providers are created and used, let's
+ take a look at how to implement one for your viewer.&nbsp; <tt>ILabelProvider</tt>
+ defines the following method for creating images:
+
+<pre>public Image getImage(Object object);</pre>
+<p>This method is called by the viewer framework for each item in the viewer.
+ As a silly example, let's say you have a fruit view that wants to display
+ various fruits. Your label provider might look as follows:
+ <p><tt>public class FruitLabelProvider extends LabelProvider {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; private Image appleImage = new Image(…);</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; private Image kiwiImage = new Image(…);</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; public Image getImage(Object object) {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (object.getClass() == Apple.class)
+ {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
+ appleImage;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (object.getClass() == Kiwi.class)
+ {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
+ kiwiImage;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; public String getLabel(Object o) {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //return appropriate labels
+ for the various fruits</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; public void dispose() {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appleImage.dispose();</tt>
+ <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appleImage = null;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kiwiImage.dispose();</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kiwiImage = null;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>}</tt>
+ <p>Some interesting things to note about this label provider:
+ <ul>
+ <li> If it failed to find an appropriate image, it just returned null. This
+ is allowed by the spec, and it also means your code won't blow up if you
+ throw in some extra fruits later on. When dealing with images, it's generally
+ better to have no image than for your code to fail.</li>
+ <li> The images were disposed in the label provider's dispose method. This
+ is VERY IMPORTANT! Anywhere an SWT Image is defined, there must be corresponding
+ code to dispose the image. Even though this is Java, you can't rely on the
+ garbage collector to free up unused images.</li>
+
+ <li> The class extended LabelProvider rather than implementing the interface
+ ILabelProvider directly. This is handy because it means you don't have to
+ implement the methods on ILabelProvider for which you aren't interested.</li>
+ </ul>
+ <h2> The ImageRegistry</h2>
+ The <tt>ImageRegistry</tt> is only intended to be used for Images that appear
+ frequently (and in large numbers) in the UI. Since these high-use images need
+ to be shared, they cannot be disposed by those using them. For this reason,
+ the <tt>ImageRegistry</tt> is provided to automatically manage these images,
+ and to dispose of them when the plug-in is shutdown. Many of the images used
+ by a plug-in should not be placed in the registry, since OS limitations on the
+ number of images in memory can easily be reached. Lower-frequency images should
+ instead be managed by having a table of <tt>ImageDescriptor</tt> instances in
+ your plug-in, and to create new images each time they are needed from the information
+ in the table of descriptors.
+ <p>The easiest way to use an <tt>ImageRegistry</tt> in your plug-in is to make
+ your <tt>Plugin</tt> class a subclass of <tt>org.eclipse.ui.plugin.AbstractUIPlugin</tt>.&nbsp;
+ This class creates an <tt>ImageRegistry</tt> automatically (one per plug-in
+ instance), if requested using the <tt>getImageRegistry()</tt> method.&nbsp;
+ This registry can then be populated with ImageDescriptors in your plug-in
+ by overriding the <tt>initializeImageRegistry(ImageRegistry)</tt> method.&nbsp;
+ The registry will then lazily generate and manage SWT images as they are requested.&nbsp;
+ The registry knows how to dispose of itself when the UI shuts down.
+ <p>It is possible to create instances of <tt>ImageRegistry</tt> manually, without
+ using the <tt>AbstractUIPlugin</tt>'s mechanism. However, this should be done
+ with caution.&nbsp; An <tt>ImageRegistry</tt>, once created, cannot be closed
+ until the whole UI shuts down.&nbsp; They should only be created and used
+ if you genuinely have need for images that last for the whole lifetime of
+ your plug-in.
+
+<h2> Using Global Images Provided by Other Plug-ins</h2>
+ Some plug-ins may expose their global images so that other plug-ins can make
+use of them.&nbsp; Not only does this improve efficiency by allowing a single
+Image instance to be used across several plug-ins, it also helps to provided
+a consistent and integrated feel to the workbench.&nbsp; If a file, folder or
+bookmark looked different from plug-in to plug-in it would result in a confusing
+experience for end-users.
+<p>The technique used for making Images available in a plug-in's API may vary
+ between plug-ins.&nbsp; The Platform UI provides an interface called <tt>org.eclipse.ui.ISharedImages</tt>,
+ accessible from the workbench.&nbsp; This interface supplies images and image
+ descriptors corresponding to a set of keys defined in ISharedImages.&nbsp; See
+ the JavaDoc for that class for descriptions of all the available methods.&nbsp;
+ To give an example, say you want to obtain the image for a file object.&nbsp;
+ You would invoke the following:
+<p><tt>PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);</tt>
+ <p>The workbench is also accessible from <tt>AbstractUIPlugin</tt>, which your
+ plug-in class will typically subclass.&nbsp; Other plug-ins use a similar
+ approach for sharing their images.&nbsp; For example, the Java Development
+ Tooling supplies <tt>org.eclipse.jdt.ui.SharedImages</tt> in its API.
+ <p><b>Important: </b>Images provided by these APIs are shared, which means you
+ <b>must not </b>dispose of them.&nbsp; Again, following the general rule,
+ since you didn't create the image, it's not your responsibility to dispose
+ of it.
+ <p>If your plug-in defines images that may be useful to others, you may want
+ to use a similar approach to make them available in your API.&nbsp; Keep in
+ mind that the number of SWT Images shared by your plug-in should be small,
+ since these images will have to stay around for the lifetime of your plug-in.
+ <h2> Where Else Can I Look For Information About Images?</h2>
+ If this article has left you scratching your head, don't worry.&nbsp; Eclipse
+has many layers of complexity, and it can take some time to wrap your head around
+the issues involved.&nbsp; The best thing to do is start with one of the examples,
+such as the readme example, and see what it's doing.&nbsp; The extension point
+documentation is an excellent place to learn about the various ways the base UI
+can be extended.&nbsp; Also, the entire Platform has extensive JavaDoc that describes
+each class and method in detail, which makes it easy to just dive in and starting
+learning how it all works.&nbsp; And of course, the <a href="http://www.eclipsecorner.org">Eclipse
+Corner</a> forums can be used to pose questions and get answers from experienced
+Eclipse developers.
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html> \ No newline at end of file
diff --git a/Article-Using Images In Eclipse/history/Using Images In Eclipse_v1.0.htm b/Article-Using Images In Eclipse/history/Using Images In Eclipse_v1.0.htm
new file mode 100644
index 0000000..70c85b7
--- /dev/null
+++ b/Article-Using Images In Eclipse/history/Using Images In Eclipse_v1.0.htm
@@ -0,0 +1,363 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
+ <title>Using Images in the Eclipse UI</title>
+<!-- saved from url=(0063)http://www.eclipsecorner.org/community/articleHTMLTemplate.html -->
+<link rel="stylesheet" href="../default_style.css">
+</head>
+<body>
+
+<div align=right>&nbsp; <font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2001 Object Technology International, Inc.</font></font></div>
+
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table>
+
+<h1> <img SRC="../images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+Using Images in the Eclipse UI</h1></center>
+
+<blockquote><b>Summary</b>
+<br>
+ Managing images in a large graphical application can be a daunting task. Since
+ modern operating systems such as Windows&reg; only support a small number of images
+ in memory at once, an application’s icons and background images must be carefully
+ managed and sometimes shared between widgets. This article describes the image
+ management facilities provided by the Eclipse Platform, along with some best
+ practice guidelines to keep in mind when writing your own Eclipse UI plug-ins.
+ We assume the reader already has a basic understanding of Eclipse, the UI extension
+ points defined by the Eclipse Platform, and the Standard Widget Toolkit (SWT).
+ <p><b>By John Arthorne, OTI<br>
+ </b>April 20, 2001
+ <p>Editor's note: This article describes Eclipse release 1.0. It has been superceded
+ by the <a href="Article-Using%20Images%20In%20Eclipse/Using%20Images%20In%20Eclipse.html">updated
+ version of this article</a> for Eclipse release 2.0. </blockquote>
+
+<h2> The Usual Suspects </h2>
+<p>We begin by describing the interesting classes to know about when writing UI
+ plug-ins that define their own images. Just about anybody writing substantial
+ UI components for a plug-in needs to understand these basic image management
+ objects. </p>
+<p>
+ <ul>
+ <li>
+ <p><b><tt>org.eclipse.swt.graphics.Image</tt></b>. Instances of <tt>Image</tt>
+ are ready for display on the screen. They have all their data in memory,
+ and they maintain a handle to an underlying OS resource. These are heavy-weight
+ objects that generally should not be held onto indefinitely. When no longer
+ needed, the user must call <tt>dispose()</tt> on the image to free the
+ underlying resource. The crucial point to understand here is that these
+ objects are very expensive to leave lying around. The operating system
+ typically only allows a fixed number of images at once. For example, Windows
+ 98 only allows about 1000 images in memory before it begins to fail. Whenever
+ you create an instance of Image, think about how long it will be needed,
+ and make sure that a mechanism is in place to dispose of it when no longer
+ needed. You <b>cannot</b> rely on the Java&trade; garbage collector to do this
+ for you, since Images reference memory allocated by the OS, not the Java
+ virtual machine.&nbsp; An interesting characteristic of Images is that
+ one <tt>Image</tt> instance can be placed in multiple widgets, a technique
+ called image sharing.&nbsp; A major challenge of image management is to
+ take advantage of this sharing as much as possible, but to still know
+ when it is safe to dispose the image.</p>
+ </li>
+ <li> <b><tt>org.eclipse.jface.resource.ImageDescriptor</tt></b>. These objects
+ are very light-weight descriptions of images. They know how to find the
+ image data and load the image into memory, but they do not hold onto any
+ large structures themselves. There are a number of factory methods on ImageDescriptor
+ for creating descriptors from Java resource files, normal files, and URLs.
+ It is okay to create ImageDescriptors for all the images in your plug-in,
+ and keep them around for the lifetime of the UI.&nbsp; An SWT image can
+ be created from an ImageDescriptor by calling its createImage method.&nbsp;
+ Each call to createImage returns a new instance of Image, and it is the
+ caller's responsibility to ensure that the created image gets disposed.</li>
+ <li> <b><tt>org.eclipse.jface.resource.ImageRegistry</tt></b>. Some images are
+ used very frequently by a plug-in, and are worth placing in a global pool
+ so that they can be shared and reused throughout the UI. These images should
+ be placed in your plug-in's ImageRegistry. It is important to keep the number
+ of images in your registry small, so that you don't unnecessarily hog OS
+ resources that may be needed by other plug-ins.</li>
+ </ul>
+ As a general rule of thumb, ImageDescriptors should be used wherever possible
+in your UI code.&nbsp; However, in places where you are creating real widgets,
+such as subclasses of <tt>org.eclipse.swt.widgets.Widget</tt>, or <tt>org.eclipse.jface.window.Window</tt>,
+you need to be manipulating SWT images.&nbsp; Generally, the code that creates
+the widget should also create the Images to go in it, and the code that disposes
+the widget should also dispose of its images.&nbsp; An exception to this rule
+is if you are using Images that are shared between multiple widgets.&nbsp; Image
+sharing should be approached with caution, because as we discussed earlier, sharing
+makes it difficult to figure out when to dispose of the images.&nbsp; <tt>org.eclipse.jface.viewers.ILabelProvider</tt>
+(described later), and <tt>org.eclipse.jface.resource.ImageRegistry</tt>, are two
+mechanisms provided by JFace that help to achieve image sharing in a controlled
+manner.
+<h2>Defining Images Through your plugin.xml File</h2>
+ The simplest and most frequent way images get added to a UI plug-in is via their
+ plugin.xml file.&nbsp; Many UI extension points allow an image filename to be
+ provided directly in your extension definition, namely:
+ <ul>
+
+ <li> "actions" elements on the org.eclipse.ui.actionSets extension point</li>
+
+ <li> "editor" elements on the org.eclipse.ui.editors extension point</li>
+ <li> "action" elements on the org.eclipse.ui.editorActions extension point</li>
+
+ <li> "wizard" elements on the org.eclipse.ui.newWizards extension point</li>
+
+ <li> "wizard" elements on the org.eclipse.ui.importWizards extension
+ point</li>
+
+ <li> "wizard" elements on the org.eclipse.ui.exportWizards extension
+ point</li>
+ <li> "layout" elements on the org.eclipse.ui.perspective extension point</li>
+
+ <li> "action" elements on the org.eclipse.ui.popupMenus extension point</li>
+ <li> "page" elements on the org.eclipse.ui.propertyPages extension point</li>
+ <li> "action" elements on the org.eclipse.ui.viewActions extension point</li>
+ <li> "view" elements on the org.eclipse.ui.views extension point</li>
+ </ul>
+ For all of these element types, the way you specify images is the same.&nbsp;
+There is an attribute called "icon", whose value must be an image filename relative
+to your plug-IN's install location.&nbsp; To give a quick example, here is an
+XML definition of an import wizard, taken from the extension point documentation:
+<pre><tt>&lt;extension</tt>
+ <tt>point="org.eclipse.ui.import"></tt>
+<tt>&nbsp;&nbsp; &lt;wizard</tt>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="com.xyz.ImportWizard1"</tt>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="XYZ Web Scraper"</tt>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="com.xyz.imports.ImportWizard1"</tt>
+<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icon="./images/import1.gif"></tt>
+<tt>&nbsp;&nbsp; &lt;/wizard></tt>
+<tt>&lt;/extension></tt> </pre>
+<p>Here, the wizard is given an image called "import1.gif", found in a subdirectory
+ of the plug-IN's base directory called "images".&nbsp; See the documentation
+ for each of the above extension points for more details and examples of their
+ use. </p>
+<p>There are many advantages to specifying images directly in your XML file, over
+ defining images programmatically in your UI code:
+<ul>
+ <li> You can let the Platform worry about loading the image, storing it, and
+ disposing of it when no longer needed, which means less code and less bugs
+ for you to worry about.</li>
+ <li> Most of your image filenames are encoded in one place, making it easier
+ to change and modify them.</li>
+ <li> Your plug-in will take advantage of the Platform's lazy plug-in loading
+ mechanism.&nbsp; Your classes and images will only be loaded when they are
+ referenced by the user, and not before.&nbsp; In fact, this is why extension
+ points always ask for a name and icon for your actions, views, etc.&nbsp;
+ That way, the Platform can present them in menus and toolbars without having
+ to load your classes until they are really needed.</li>
+ </ul>
+ <h2> Adding Images to Custom UI</h2>
+ You have begun experimenting with platform extension points, maybe contributing
+ some actions to popup menus or toolbars, or maybe you've even defined your own
+ custom view. In many of these cases, specifying an image file in the XML file
+ for your plug-in is all that is required, and the Platform takes care of the
+ rest.&nbsp; However, when you move on to writing more advanced UI components,
+ you may need to define images from within your code.&nbsp; The following example
+ demonstrates the simplest way to define images within UI code. In this example
+ we have a UI plug-in called MyPlugin, and some action called MyAction. We would
+ like to associate an image with MyAction.
+ <p>Step 1: Create an image using your favorite image editing program. For action
+ icons, the recommended format is a 16x16 pixel image in the GIF format. For
+ this example, we'll call the image "my_action.gif", and place it in a subdirectory
+ of the plug-in base directory called "images".
+ <p>Step 2: Define an ImageDescriptor in your MyAction class. It's a good idea
+ to make this field static so that it can be shared across instances of the
+ action.
+
+<pre>public class MyAction extends Action {
+ private static ImageDescriptor image;
+ static {
+ URL url = null;
+ try {
+ url = new URL(MyPlugin.getInstance().getDescriptor().getInstallURL(),
+ "images/my_action.gif");
+ } catch (MalformedURLException e) {
+ }
+ image = ImageDescriptor.createFromURL(url);
+ }
+ ... other methods and fields defined here ...
+}
+ </pre>
+ <p>Because plug-ins can be stored anywhere, we use URLs to describe their location.
+ The image location will always be the same relative to the plug-in location,
+ so we use that as the base of the image's URL. We then use the factory method
+ defined on the ImageDescriptor class to create our descriptor. The method
+ ImageDescriptor#createFromURL() will handle the case where a null URL is passed
+ to it, so we don't need to handle the possible URL exception. Images that
+ could not be loaded are visible in the UI as small red squares. If you see
+ a red square next to your action in the popup menu, it probably means you
+ got the image location wrong, or the image is missing.
+ <p>Step 3: Set the ImageDescriptor as the action's image in the constructor:
+
+<pre>public MyAction() {
+ super("My Action", image);
+}</pre>
+<p>That's it! Now, when you startup the Eclipse UI and find your action in a menu
+ or toolbar, your image will appear next to it. The same approach can be used
+ to define images within custom views and wizards.&nbsp; Note that since you
+ only had to deal with ImageDescriptors in this example, no disposal was required.&nbsp;
+ In this case the platform is responsible for creating, managing, and disposing
+ any SWT Image it creates from the image descriptor you supplied. </p>
+<h2> Viewers and Label Providers</h2>
+ Adding images to actions and view titles is fairly simple in Eclipse. In these
+cases, the platform handles the creation and management of the real, underlying
+SWT image. When you start to add your own objects to viewers, things get a little
+bit more complicated. This is mainly because many objects in viewers tend to have
+the same icon. For example, all files in the Navigator have the same icon, as
+do all public Java fields in the Java Development Tooling (JDT) views. To make
+this efficient, we want to reuse the same SWT image object for all these items.
+This is accomplished by creating a label provider for your viewer.
+<p>You can think of label providers as containing a pool of images that lasts
+ for the lifetime of a particular viewer.&nbsp; They allow the same SWT Images
+ to be reused throughout the time that viewer's widget is open.&nbsp; Note
+ that ILabelProviders don't provide a way to share the same Image across multiple
+ viewers, which is fine because there are rarely more than a couple of viewers
+ open at any given time that could share images anyway.&nbsp; Generally, sharing
+ images across multiple viewers introduces a great deal of complexity for very
+ little gain.
+ <p>To give you an idea of how ILabelProviders work, it is instructive to step
+ through the lifetime of an ILabelProvider instance.
+ <ul>
+ <li> <b>Creation:</b> The code that creates a viewer instance should also
+ create an instance of ILabelProvider to supply images for objects in that
+ viewer.&nbsp; The label provider is then set into the viewer by calling
+ <tt>org.eclipse.jface.viewer.ContentViewer#setLabelProvider(IBaseLabelProvider)<b>.
+ </b></tt><b>Important:</b>&nbsp; Once a label provider has been set into
+ a viewer, that viewer takes over ownership of the instance.&nbsp; A label
+ provider instance must never be passed to another viewer, or have any of
+ its methods invoked, once it has been allocated to a viewer.</li>
+ <li> <b>Disposal:</b>&nbsp; The viewer is responsible for invoking dispose()
+ on its label provider when the underlying widget is closed.&nbsp; This <tt>dispose()</tt>
+ method must dispose of any images that were ever dispensed by that label
+ provider instance.</li>
+ </ul>
+ Now that you have an idea of how label providers are created and used, let's
+ take a look at how to implement one for your viewer.&nbsp; <tt>ILabelProvider</tt>
+ defines the following method for creating images:
+
+<pre>public Image getImage(Object object);</pre>
+<p>This method is called by the viewer framework for each item in the viewer.
+ As a silly example, let's say you have a fruit view that wants to display
+ various fruits. Your label provider might look as follows:
+ <p><tt>public class FruitLabelProvider extends LabelProvider {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; private Image appleImage = new Image(…);</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; private Image kiwiImage = new Image(…);</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; public Image getImage(Object object) {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (object.getClass() == Apple.class)
+ {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
+ appleImage;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (object.getClass() == Kiwi.class)
+ {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
+ kiwiImage;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; public String getLabel(Object o) {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //return appropriate labels
+ for the various fruits</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; public void dispose() {</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appleImage.dispose();</tt>
+ <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appleImage = null;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kiwiImage.dispose();</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kiwiImage = null;</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; }</tt> <br>
+ <tt>}</tt>
+ <p>Some interesting things to note about this label provider:
+ <ul>
+ <li> If it failed to find an appropriate image, it just returned null. This
+ is allowed by the spec, and it also means your code won't blow up if you
+ throw in some extra fruits later on. When dealing with images, its generally
+ better to have no image than for your code to fail.</li>
+ <li> The images were disposed in the label provider's dispose method. This
+ is VERY IMPORTANT! Anywhere an SWT Image is defined, there must be corresponding
+ code to dispose the image. Even though this is Java, you can't rely on the
+ garbage collector to free up unused images.</li>
+
+ <li> The class extended LabelProvider rather than implementing the interface
+ ILabelProvider directly. This is handy because it means you don't have to
+ implement the methods on ILabelProvider for which you aren't interested.</li>
+ </ul>
+ <h2> The ImageRegistry</h2>
+ The <tt>ImageRegistry</tt> is only intended to be used for Images that appear
+ frequently (and in large numbers) in the UI. Since these high-use images need
+ to be shared, they cannot be disposed by those using them. For this reason,
+ the <tt>ImageRegistry</tt> is provided to automatically manage these images,
+ and to dispose of them when the plug-in is shutdown. Many of the images used
+ by a plug-in should not be placed in the registry, since OS limitations on the
+ number of images in memory can easily be reached. Lower-frequency images should
+ instead be managed by having a table of <tt>ImageDescriptor</tt> instances in
+ your plug-in, and to create new images each time they are needed from the information
+ in the table of descriptors.
+ <p>The easiest way to use an <tt>ImageRegistry</tt> in your plug-in is to make
+ your <tt>Plugin</tt> class a subclass of <tt>org.eclipse.ui.plugin.AbstractUIPlugin</tt>.&nbsp;
+ This class creates an <tt>ImageRegistry</tt> automatically (one per plug-in
+ instance), if requested using the <tt>getImageRegistry()</tt> method.&nbsp;
+ This registry can then be populated with ImageDescriptors in your plug-in
+ by overriding the <tt>initializeImageRegistry(ImageRegistry)</tt> method.&nbsp;
+ The registry will then lazily generate and manage SWT images as they are requested.&nbsp;
+ The registry knows how to dispose of itself when the UI shuts down.
+ <p>It is possible to create instances of <tt>ImageRegistry</tt> manually, without
+ using the <tt>AbstractUIPlugin</tt>'s mechanism. However, this should be done
+ with caution.&nbsp; An <tt>ImageRegistry</tt>, once created, cannot be closed
+ until the whole UI shuts down.&nbsp; They should only be created and used
+ if you genuinely have need for images that last for the whole lifetime of
+ your plug-in.
+
+<h2> Using Global Images Provided by Other Plug-ins</h2>
+ Some plug-ins may expose their global images so that other plug-ins can make
+use of them.&nbsp; Not only does this improve efficiency by allowing a single
+Image instance to be used across several plugin-ins, it also helps to provided
+a consistent and integrated feel to the workbench.&nbsp; If a file, folder or
+bookmark looked different form plugin-in to plug-in it would result in a confusing
+experience for end-users.
+<p>The technique used for making Images available in a plug-in's API may vary
+ between plug-ins.&nbsp; The Platform UI provides an interface called <tt>org.eclipse.ui.ISharedImages</tt>,
+ accessible from the workbench.&nbsp; This interface supplies images and image
+ descriptors corresponding to a set of keys defined in ISharedImages.&nbsp; See
+ the JavaDoc for that class for descriptions of all the available methods.&nbsp;
+ To give an example, say you want to obtain the image for a file object.&nbsp;
+ You would invoke the following:
+<p><tt>PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);</tt>
+ <p>The workbench is also accessible from <tt>AbstractUIPlugin</tt>, which your
+ plug-in class will typically subclass.&nbsp; Other plug-ins use a similar
+ approach for sharing their images.&nbsp; For example, the Java Development
+ Tooling supplies <tt>org.eclipse.jdt.ui.SharedImages</tt> in its API.
+ <p><b>Important: </b>Images provided by these APIs are shared, which means you
+ <b>must not </b>dispose of them.&nbsp; Again, following the general rule,
+ since you didn't create the image, its not your responsibility to dispose
+ of it.
+ <p>If your plug-in defines images that may be useful to others, you may want
+ to use a similar approach to make them available in your API.&nbsp; Keep in
+ mind that the number of SWT Images shared by your plugin should be small,
+ since these images will have to stay around for the lifetime of your plugin-in.
+ <h2> Where Else Can I Look For Information About Images?</h2>
+ If this article has left you scratching your head, don't worry.&nbsp; Eclipse
+has many layers of complexity, and it can take some time to wrap your head around
+the issues involved.&nbsp; The best thing to do is start with one of the examples,
+such as the readme example, and see what it's doing.&nbsp; The extension point
+documentation is an excellent place to learn about the various ways the base UI
+can be extended.&nbsp; Also, the entire Platform has extensive JavaDoc that describes
+each class and method in detail, which makes it easy to just dive in and starting
+learning how it all works.&nbsp; And of course, the <a href="http://www.eclipsecorner.org">Eclipse
+Corner</a> forums can be used to pose questions and get answers from experienced
+Eclipse developers.
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html> \ No newline at end of file
diff --git a/Article-VE-Custom-Widget/customwidget.html b/Article-VE-Custom-Widget/customwidget.html
new file mode 100644
index 0000000..e11a19a
--- /dev/null
+++ b/Article-VE-Custom-Widget/customwidget.html
@@ -0,0 +1,2724 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <title>Visual Editor Tutorial</title>
+ <link rel="stylesheet" type="text/css"
+ href="../default_style.css">
+ <style type="text/css">
+ .PictureParagraph { margin-left: 10% }
+ .PictureStyle { border-style: ridge; border-width: 1px; padding: 1px }
+
+ </style>
+</head>
+
+<body link="#0000ff" vlink="#800080">
+ <div align="right">
+ &nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2005 IBM and other contributors</font>
+
+ <table border="0" cellpadding="2" cellspacing="0" width="100%">
+ <tbody>
+ <tr>
+ <td colspan="2" align="left" bgcolor="#0080c0" valign="top">
+ <b><font face="Arial,Helvetica"><font color="#ffffff">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div align="left">
+ <h1><img src="../images/Idea.jpg" align="middle" height="86" width=
+ "120"></h1>
+ </div>
+
+ <p>&nbsp;</p>
+
+ <h1 align="center">Extending The Visual Editor:<br>
+ Enabling support for a custom widget</h1>
+
+ <blockquote>
+ <p><b>Summary</b><br>
+ This tutorial
+ shows how to extend the Visual Editor to support a custom widget.
+ It covers topics such as adding to the Visual Editor's palette,
+ building a BeanInfo class, and working with
+ EMF .override files to
+ introduce custom editor behavior.</p>
+ <p><b>Dave Orme, db4objects</b><br>
+ <b>Gili Mendel, IBM</b><br>
+ <b>Joe Winchester, IBM</b><br>
+ <font size="-1">June 20, 2005</font></p>
+ </blockquote>
+
+<hr width="100%">
+
+<h2><a name="Introduction"></a>Introduction</h2>
+<p>The <a href="http://www.eclipse.org/vep">Visual Editor</a> project
+provides reference implementations of a graphical user interface
+builder for the JFC and SWT widget toolkits built around an extensible
+framework.&nbsp; The motivation for this came from experience with
+previous GUI builders that, while they provided high function end
+points for particular toolkits, were unable to be adapted to support
+custom behavior. This typically would be for areas of functionality
+such as user defined widgets, new layout managers, or flexible code
+generation patterns. A design goal of the Visual Editor is that is none
+of its own custom behavior for any JFC or SWT classes is done with hard
+coding and all logic that the VE employs to enable specific bespoke
+function such dropping a control on a composite or showing feedback for
+a particular layout manager is soft coded through extension points. The
+intention is that the same techniques can be leveraged by anyone
+wishing to employ similar techniques for their own scenario.</p>
+<p>In this tutorial a 3.1 based Eclipse plugin&nbsp; <i>org.eclipse.ve.example.customwidget</i>
+is created that illustrates some of the extension points of the visual
+editor.&nbsp; To do this an SWT custom widget is built that combines a
+Label, Text and Button in a single widget called <span
+ style="font-style: italic;">org.eclipse.ve.examples.customwidget.MyCustomPrompter</span>.&nbsp;</p>
+<p><img style="width: 243px; height: 34px;" alt="CustomWidget"
+ src="images/CustomWidget.png"></p>
+<p>MyCustomPrompter has two properties: <span
+ style="font-style: italic;">type</span> and <span
+ style="font-style: italic;">text</span>.&nbsp; These each have get and
+set methods and can be used to configure the behavior of the Button and
+the Text's text value.&nbsp; There is also a <span
+ style="font-style: italic;">ButtonSelectionEvent</span> event that is
+raised when the prompter's button is pressed and listeners can register
+for this callback using <span style="font-style: italic;">addButtonSelectionListener(ButtonSelectionListener
+aListener);</span></p>
+<p>In the absence of the plugin that this tutorial creates<span
+ style="font-family: monospace;">,</span> the <span
+ style="font-family: monospace;">MyCustomPrompter</span> widget can
+still be used by a user who drops it onto an SWT composite by adding a
+jar (or folder) containing the class to their Java project's build path<span
+ style="font-family: monospace;">.</span> Within the Visual Editor the
+class can be selected by using <span style="font-style: italic;">ChooseBean</span>
+from the palette to drop <span style="font-family: monospace;">MyCustomPrompter</span>
+onto a composite. Through inheritance (<span
+ style="font-family: monospace;">MyCustomPrompter</span> extends <span
+ style="font-family: monospace;">org.eclipse.swt.widgets.Composite</span>)
+the custom control will be rendered correctly and its properties will
+be determined using JavaBeans<sup>TM</sup> reflection allowing it to be
+modified using the Properties Viewer.&nbsp; The new event will also be
+determined automatically through introspection by the Visual Editor and
+available to the user to add callback logic to through the <span
+ style="font-style: italic;">Add Event</span> dialog.&nbsp;</p>
+<p>This tutorial shows how to extend the edit experience by creating a
+plugin that enables specific Visual Editor behavior over and above the
+default that is determined through inheritance.&nbsp; This results in a
+higher level edit experience for end users of the <span
+ style="font-style: italic;">MyCustomPrompter</span> class.&nbsp; The
+examples given are purely for illustrative purposes only and to
+highlight some of the available ways to extend the behavior of the
+Visual Editor, and it is expected that the reader of this tutorial will
+use it to learn the extension mechanism and then apply this to their
+own custom widget or Java class.&nbsp;</p>
+<h3><a name="Intro_Palette"></a>Palette</h3>
+<p>The visual editor provides a palette of classes from which the user
+can choose commonly used classes.&nbsp; The tutorial shows how to
+create a new palette category containing the CustomWidget to allow it
+to be brought to the user's selection and easily selected and dropped
+without having to use <span style="font-style: italic;">ChooseBean</span>
+and enter the class name</p>
+<table style="text-align: left; width: 50%;" border="1" cellspacing="2"
+ cellpadding="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">Before</td>
+ <td style="vertical-align: top;">With plugin showing <span
+ style="font-style: italic;">Custom</span> category with the <span
+ style="font-style: italic;">MyCustomPrompter</span> class</td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><img
+ style="width: 147px; height: 241px;" alt="OriginalPalette"
+ src="images/OriginalPalette.png"><br>
+ </td>
+ <td style="vertical-align: top;"><img
+ style="width: 143px; height: 240px;" alt="NewPalette"
+ src="images/NewPalette.png"> </td>
+ </tr>
+ </tbody>
+</table>
+<h3><a name="Intro_Property_sheet"></a>Property sheet</h3>
+<p><span style="font-family: monospace;">MyCustomPrompter</span> has an
+<span style="font-style: italic;">int</span> property called <span
+ style="font-style: italic;">type</span> that affects the text shown on
+the CustomPrompter's button.&nbsp; This has a set of restricted values
+corresponding to static constraints.&nbsp; For example, 0 is the
+constant <span style="font-family: monospace;">CustomPrompter.DOTS</span>,
+1 is <span style="font-family: monospace;">CustomPrompter.MORE</span>
+and 2 is <span style="font-family: monospace;">CustomPrompter.OPEN.</span>
+Rather than have the user have to remember this the property sheet will
+be extended so that there is a drop down list of available values and
+the existing value is shown as its meaningful name rather than its
+internal <span style="font-style: italic;">int</span> value.</p>
+<table style="text-align: left; width: 75%;" border="1" cellspacing="2"
+ cellpadding="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">Before</td>
+ <td style="vertical-align: top;">With plugin</td>
+ <td style="vertical-align: top;">With plugin</td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span style="font-style: italic;">type</span>
+property displayed with default <span style="font-style: italic;">int</span>
+editor</td>
+ <td style="vertical-align: top;"><span style="font-style: italic;">type</span>
+property displayed as static constant name</td>
+ <td style="vertical-align: top;"><span style="font-style: italic;">type</span>
+property edited with drop down list of enumerated allowable values</td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><img
+ style="width: 217px; height: 85px;" alt="OriginalType"
+ src="images/OriginalTypeProperty.png"><br>
+ </td>
+ <td style="vertical-align: top;"><img
+ style="width: 216px; height: 86px;"
+ alt="TypePropertyLabelProviderWithPlugin"
+ src="images/TypePropertyLabelProvider.png"><br>
+ </td>
+ <td style="vertical-align: top;"><img
+ style="border: 1px solid ; width: 216px; height: 86px;"
+ alt="TypePropertyCellEditor" src="images/TypePropertyCellEditor.png"></td>
+ </tr>
+ </tbody>
+</table>
+<p><span style="font-family: monospace;">MyCustomPrompter</span> has a
+String property called <span style="font-style: italic;">text</span>
+that reflects the value shown on the CustomPrompter's text
+widget.&nbsp; The default property sheet editor for a String property
+is a Text field that allows the value to be changed, however the
+tutorial shows how to have a custom property editor that launches a
+separate dialog through which the value can be changed</p>
+<table style="text-align: left; width: 50%;" border="1" cellspacing="2"
+ cellpadding="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">Before with default String
+editor behavior for <span style="font-style: italic;">text</span>
+property</td>
+ <td style="vertical-align: top;">With plugin showing custom
+editor for <span style="font-style: italic;">text</span> property</td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><img
+ style="border: 1px solid ; width: 212px; height: 47px;"
+ alt="OriginalTextProperty" src="images/OriginalTextProperty.png"> </td>
+ <td style="vertical-align: top;"><img
+ style="border: 1px solid ; width: 211px; height: 46px;"
+ alt="TextPropertyCellEditor" src="images/TextPropertyCellEditor.png"> </td>
+ </tr>
+ </tbody>
+</table>
+<h3><a name="Intro_Graphical_behavior"></a>Graphical behavior</h3>
+<p>The visual editor uses the graphical editor framework or GEF to
+render the visual classes to the user.&nbsp; GEF is a powerful
+framework which uses EditPart classes as mediators between the
+underlying model and the draw2d view layer.&nbsp; This is similar to
+the controller in an MVC pattern and described in overview at <a
+ href="http://www-128.ibm.com/developerworks/opensource/library/os-gef/index.html">
+Create an Eclipse based application using GEF.</a> The default behavior
+for a visual class is a WYSIWYG rendering where a preview of the live
+runtime widget is drawn.&nbsp; There are times when you may wish to
+override this for a specific component such as to visually annotate the
+feedback for the figure such as drawing grid lines, additional handles
+or other features provided by GEF.&nbsp; As an example of how to alter
+the edit part used by the visual editor the tutorial shows how to have <span
+ style="font-style: italic;">MyCustomPrompter&nbsp;</span> rendered
+with an icon <img style="width: 16px; height: 16px;" alt="Custom"
+ src="images/custom.gif"> and the text <span
+ style="color: rgb(255, 0, 0);">VE Rules</span> super imposed over the
+image of the live visual control.&nbsp; In addition the default
+behavior of a Composite graphical edit part is to draw a border around
+it in the editor so that it can be located by the user irrespective of
+whether it has child controls or not.&nbsp; <span
+ style="font-style: italic;">MyCustomPrompter</span> is an aggregate of
+three child controls into a custom widget so the graphical edit part
+will remove the artificial border.</p>
+<table style="text-align: left; width: 100%;" border="1" cellspacing="2"
+ cellpadding="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">Before with default behavior
+showing the image of the live visual control with a border</td>
+ <td style="vertical-align: top;">With plugin showing custom edit
+part with an icon and label and no border</td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><img
+ style="border: 1px solid ; width: 342px; height: 172px;"
+ alt="originalGEF" src="images/OriginalGraphicalEditPart.png"> </td>
+ <td style="vertical-align: top;"><img
+ style="border: 1px solid ; width: 341px; height: 171px;"
+ alt="GraphicalEditPart" src="images/GraphicalEditPart.png"> </td>
+ </tr>
+ </tbody>
+</table>
+<h3><a name="Intro_Code_generation"></a>Code generation</h3>
+<p>Code generation uses decoder classes to mediate between the visual
+editor's model and the Java source model.&nbsp; This tutorial shows how
+to create a custom code generation rule for the <span
+ style="font-style: italic;">text</span> property of <span
+ style="font-style: italic;">MyCustomPrompter</span> so that it has an
+additional comment placed on the line with the set method.&nbsp; This
+is the string <span style="color: rgb(0, 102, 0);">// Prompter Text
+Property</span></p>
+<table style="text-align: left; width: 100%;" border="1" cellspacing="2"
+ cellpadding="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">Before with default code
+generation behavior</td>
+ <td style="vertical-align: top;">With plugin showing the extra
+comment line code generated for the setText(String) method</td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top; font-family: monospace;"><span
+ style="color: rgb(153, 0, 0);">private void</span>
+createMyCustomPrompter() {<br>
+&nbsp; myCustomPrompter = <span style="color: rgb(153, 0, 0);">new</span>
+MyCustomPrompter(sShell, SWT.<span
+ style="font-style: italic; color: rgb(51, 51, 255);">NONE</span>);&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<br>
+&nbsp; myCustomPrompter.setText(<span style="color: rgb(51, 51, 255);">"Text
+Value"</span>);<br>
+}</td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;"><span style="color: rgb(153, 0, 0);">private
+void</span> createMyCustomPrompter() {</span><br
+ style="font-family: monospace;">
+ <span style="font-family: monospace;">&nbsp; myCustomPrompter = <span
+ style="color: rgb(153, 0, 0);">new</span> MyCustomPrompter(sShell, SWT.<span
+ style="font-style: italic; color: rgb(51, 51, 255);">NONE</span>);&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> <br
+ style="font-family: monospace;">
+ <span style="font-family: monospace;">&nbsp;
+myCustomPrompter.setText(<span style="color: rgb(51, 51, 255);">"Text
+value"</span>); <span style="color: rgb(0, 153, 0);">// Prompter Text
+Property</span></span> <br style="font-family: monospace;">
+ <span style="font-family: monospace;">}</span> </td>
+ </tr>
+ </tbody>
+</table>
+<h3><a name="Intro_Preferred_Event"></a>Preferred Event</h3>
+<p><span style="font-style: italic;">MyCustomPrompter</span> signals an
+event when its button is pressed.&nbsp;&nbsp; Listeners can register
+interest in this with the method <span style="font-style: italic;">addButtonSelectionListener(ButtonSelectionListener
+aListener)</span> and remove interest with the method <span
+ style="font-style: italic;">removeButtonSelectionListener(ButtonSelectionListener
+aListener).&nbsp;</span> The Visual Editor will automatically detect
+this event because the naming convention of the methods and the
+listener class follows the JavaBeans specification.&nbsp; The event
+will be available from the list of all available events for the custom
+control, however it is included in the list that has everything from
+mouse through keyboard and paint events.&nbsp; This tutorial shows how
+to promote the event to the list of <span style="font-style: italic;">preferred</span>
+events whereupon it will be shown on the <span
+ style="font-style: italic;">Add Events</span> menu for the class.</p>
+<table style="text-align: left; width: 100%;" border="1" cellspacing="2"
+ cellpadding="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">Before where the Events menu has
+no preferred events</td>
+ <td style="vertical-align: top;">With plugin the Events menu has <span
+ style="font-style: italic;">buttonSelected</span> as a preferred event</td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><img
+ style="border: 1px solid ; width: 502px; height: 412px;"
+ alt="OriginalEventsMenu" src="images/OriginalEventsMenu.png"> </td>
+ <td style="vertical-align: top;"><img
+ style="border: 1px solid ; width: 501px; height: 411px;"
+ alt="EventsMenuAfter" src="images/EventsMenuAfter.png"> </td>
+ </tr>
+ </tbody>
+</table>
+<h2><a name="Getting_started">Getting started</a></h2>
+<p>This tutorial goes go through the steps required to build a plugin
+called<i>org.eclipse.ve.example.customwidget</i><span
+ style="font-style: italic;"><span style="font-weight: bold;">.&nbsp;&nbsp;&nbsp;</span></span>
+The pre-requisites are an Eclipse 3.1 target environment which has a
+3.1 code-base for the Visual Editor, GEF and EMF installed.&nbsp; These
+can be obtained from the <a
+ href="http://download.eclipse.org/tools/ve/downloads/index.php">Visual
+Editor's download page</a>.&nbsp; There is an SDK version of the Visual
+Editor available as well as a runtime, and to develop this tutorial
+ensure you have the SDK download for the VE. If you obtain the SDK
+drivers for GEF and EMF it means you will be able to view their source
+and debug code more easily.</p>
+<p><img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;">&nbsp;&nbsp;&nbsp; Although the
+plugin is designed to target 3.1 it can be developed in an earlier
+environment such as 3.0.1.&nbsp; The target environment is the one that
+is run when the <span style="font-weight: bold;">Run ... Eclipse
+Environment</span> is used to launch a runtime workbench.&nbsp; You can
+use <span style="font-weight: bold;">Windows-&gt;Preference-&gt;PDE-&gt;Target
+Platform</span> to view and change the target environment and <span
+ style="font-weight: bold;">Help About</span> to see the version of
+Eclipse.</p>
+<p>The completed plugin can be obtained separately as described in the
+section <a href="#A_complete_example">A complete example</a></p>
+<h2><a name="Creating_the_Plugin">Creating the Plugin</a></h2>
+<p>This section describes how to build the plugin <span
+ style="font-style: italic;">org.eclipse.ve.example.customwidget.&nbsp;</span>
+This will be used to package the CustomWidget itself as well as to
+include the extensions required to override its default behavior.&nbsp;
+The end result for users is that they will install this plugin onto
+their Eclipse environment and then configure their Java projects to use
+the custom widget jar that is included in this plugin <a
+ href="#Using_a_classpath_container">using a class path container</a>.</p>
+<p>To create the plugin select open the New Project wizard using the
+menu options <span style="font-weight: bold;">File &gt; New &gt;
+Project</span> and choose <span style="font-weight: bold;">Plug-in
+Project</span><br>
+</p>
+<p><br>
+On the first page of the creation wizard name the plugin <i>org.eclipse.ve.example.customwidget</i>,
+select 3.1 as the target version and select the check box <span
+ style="font-style: italic;">Create an OSGi bundle manifest.&nbsp;&nbsp;</span>
+Press <span style="font-style: italic;">Next</span> to bring up the <span
+ style="font-style: italic;">Plug-in-Content</span> page and enter a
+plugin name such as <span style="font-style: italic;">Customwidget VE
+Example Plugin</span> in the <span style="font-style: italic;">Plugin-In
+Name</span> text field and set the name of runtime library to <span
+ style="font-style: italic;">customwidgetplugin.jar</span>.&nbsp;</p>
+<p><img style="border: 1px solid ; width: 499px; height: 253px;" alt=""
+ src="images/CreatePluginWizard.png"></p>
+<p><img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;"> The reason the default suggested
+runtime library name of <span style="font-style: italic;">customwidget</span><span
+ style="font-style: italic;"><span style="font-style: italic;">.jar</span></span>
+is renamed to <span style="font-style: italic;">customwidgetplugin.jar</span>
+is to distinguish the jar file used by the workbench code for the
+plugin from the name that will be given to the runtime jar containing
+the custom widget.&nbsp; This is covered in the section <a
+ href="#Different_jars_and_packages">Different jars and packages for
+workbench and widget code</a></p>
+<p>Press <span style="font-style: italic;">Finish</span> to have the
+PDE generate the stub plugin.&nbsp; The workbench might then ask you to
+switch to the PDE perspective which you can answer <span
+ style="font-style: italic;">Yes</span> to.&nbsp; The plugin manifest
+editor should be opened by default.&nbsp; This is an editor that allows
+you to view and edit the contents of the files called <span
+ style="font-style: italic;">plugin.xml and manifest.mf</span> that
+reside within the plugin.&nbsp; These are both important files as they
+describe the extension points used and also the list of pre-requisite
+plugins.</p>
+<p>A plugin represents a component that can be installed onto an
+Eclipse environment and contributes code.&nbsp; Every plugin has a set
+of dependent plugins which is those it requires to function.&nbsp; This
+list would typically include pre-requisite plugins with classes or
+interfaces extended or any extension points that have been used.&nbsp;
+The list of pre-requisite plugins for a plugin extending the visual
+editor is:</p>
+<ul>
+ <li>org.eclipse.ui</li>
+ <li>org.eclipse.core.runtime</li>
+ <li>org.eclipse.ve.java.core</li>
+ <li>org.eclipse.jdt.core</li>
+ <li>org.eclipse.jem</li>
+ <li>org.eclipse.jem.proxy</li>
+ <li>org.eclipse.ve.cde</li>
+ <li><img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_1.gif">org.eclipse.ve.swt</li>
+ <li>org.eclipse.ve.propertysheet</li>
+ <li>org.eclipse.gef</li>
+ <li>org.eclipse.emf.ecore</li>
+</ul>
+<p>The pre-requisite plugin&nbsp;<img style="width: 24px; height: 13px;"
+ alt="" src="../images/tag_1.gif"> org.eclipse.ve.swt is not necessarily
+required by everyone extending the visual editor.&nbsp; It contains the
+code that enables the visual editor to work with the SWT and because <span
+ style="font-style: italic;">MyCustomPrompter</span> is an SWT custom
+widget the plugin will be extending SWT base behavior.&nbsp; If your
+plugin was for a JFC toolkit such as AWT or Swing you would not
+necessarily include <span style="font-style: italic;">org.eclipse.ve.swt</span>
+in your list of dependencies but instead would use <span
+ style="font-style: italic;">org.eclipse.ve.jfc.&nbsp;</span> If your
+plugin was for an entirely new widget toolkit you might include neither.</p>
+<p>To set up the list of required plugins select the <span
+ style="font-style: italic;">Dependencies</span> tab on the plugin
+editor, select the <span style="font-style: italic;">Add ...</span>
+button beside the list of Required Plug-ins and enter the list of
+plugins listed above.</p>
+<p><img style="border: 1px solid ; width: 353px; height: 166px;"
+ alt="PreReqPlugins" src="images/PreReqPlugins.png"></p>
+<p>Having created the plugin there are two major steps remaining.&nbsp;
+The first is to create the actual custom widget class itself and test
+it, and the second is to extend the visual editor to have the
+customized behavior described in the <a href="#Introduction">introduction</a>.</p>
+<h2><a name="Different_jars_and_packages"></a>Different jars and
+packages for workbench and widget code</h2>
+<p>There are two jar files being created as part of this
+tutorial.&nbsp; The reason for this is based on the architecture of the
+Visual Editor and how it uses a separate JVM for the classes
+instantiated by the editor rather with re-use or share the JVM used by
+Eclipse itself.<br>
+<br>
+The Visual Editor can be considered as an extension to the Java
+Development Tooling (JDT) that lets you preview any visual controls
+that are part of the Java class being edited.&nbsp; The raw Java editor
+on its own lets you view and modify the source code for a <span
+ style="font-style: italic;">.java</span> file, and edit it using
+features like Code assist and the Outline viewer.&nbsp; When you use
+code assist the list of available classes is scoped to be only those
+that are valid for the current compilation unit, namely those present
+in the Java build path of the project.&nbsp; The Java build path is
+specified through the project's properties and can be thought of as the
+list of <span style="font-style: italic;">-classpath</span> entries
+that make up the <span style="font-style: italic;">javac</span>
+command.&nbsp; If you try to use a class that isn't on the build path
+you will get a compile error.&nbsp; If you try to call a method that
+doesn't exist on a valid class you will get a compile error, although
+if you were to change the build path so that it now contained a version
+of the class that had the method it would compile.&nbsp; The build
+path's entries determine the environment in which the class you're
+editing is being created for and the editor responds accordingly.<br>
+<br>
+When the Visual Editor is open it uses the JDT's Java editor (as the
+bottom half of the screen or a separate tab depending on the workbench
+preferences) and parses the code to recognize visual classes and how
+they are constructed and associated with each other together with their
+initial property values. To create a preview of the visuals these
+classes must be actually instantiated in a live environment following
+the constructor pattern detected from the source and set methods
+actually invoked against the live objects for the desired properties
+and relationships.&nbsp; To do this a JVM environment must exist that
+contains the list of <span style="font-style: italic;">-classpath</span>
+entries that match those in the Java build path so that the JVM can
+load and use the actual instances the user is editing their project
+with.&nbsp; This can't be the Eclipse's JVM as this is started with the
+.jar files required for it to behave as an editor, so a separate JVM is
+created each time the Visual Editor is opened on a class.&nbsp; This is
+sometimes referred to as the <span style="font-style: italic;">target
+VM</span> and its purpose is to host prototype Java instances that the
+Visual Editor instantiates and uses based on the source statements in
+the <span style="font-style: italic;">.java</span> file being
+edited.&nbsp;&nbsp; A good analogy to this process is the one used by
+the <span style="font-style: italic;">Run As&gt;Java Application</span>
+option in the JDT.&nbsp; If you write a Java class with a public void
+main(String[] args) method the JDT lets you edit it inside the Eclipse
+JVM, however to test it a separate JVM is launched by the <span
+ style="font-style: italic;">Java Application</span> launcher.&nbsp;
+The JDT launcher's separate JVM can be viewed from the <span
+ style="font-style: italic;">Debug</span> viewer allowing you to set
+breakpoints and step through code, while the Visual Editor's <span
+ style="font-style: italic;">target VM</span> is deliberately hidden
+from the <span style="font-style: italic;">Debug</span> viewer to stop
+users from accidentally terminating it.<br>
+<br>
+When writing the plugin for this tutorial there are two jar files that
+will finally be created.&nbsp; The first of these is the <a
+ href="#Plugin_Jar">plugin side jar</a> and contains the Eclipse
+workbench code that is used within the IDE's VM and contains code such
+as a JFace property sheet editor, a GEF graphical edit part and a
+custom source decoder.&nbsp; The second is the <a href="#Runtime_jar">runtime
+side jar</a> that contains the actual <font face="Courier New">MyCustomPrompter</font>
+class itself and doesn't run inside the IDE but instead is placed in
+the Java build path of the user's project and runs in the target
+VM.&nbsp; The runtime side jar also contains the BeanInfo class for
+MyCustomPrompter that contains the extensions that conform to the
+JavaBeans component model which is covered more in the sections on the <a
+ href="#Using_an_ENUM_cell_editor"><span style="font-style: italic;">type</span>
+property editor</a> and creating the <a href="#Preferred_Event">preferred
+event</a>.<br>
+<br>
+<img style="width: 601px; height: 515px;" alt=""
+ src="images/JARdiagram.png"><br>
+</p>
+<h3><a name="Plugin_Jar"></a>Plugin jar</h3>
+<p>The plugin code for this tutorial is placed in <span
+ style="font-style: italic;">customwidgetplugin.jar</span> that is
+defined as the runtime jar for the plugin itself.&nbsp; On the New
+Project wizard we explicitly changed the default prompted jar name to
+be <i>customwidgetplugin.jar</i> so that is will not be confused with
+the <a href="#Runtime_jar">run time jar</a>. The <span
+ style="font-style: italic;">customwidgetplugin.jar </span>contains
+the Eclipse code that will run inside the workbench and its definition
+can be seen in the in the <span style="font-style: italic;">Runtime</span>
+tab of the manifest editor for the plugin's plugin.xml file.&nbsp;<br>
+<br>
+<img style="border: 1px solid ; width: 357px; height: 155px;" alt=""
+ src="images/RuintimeLibraryPluginName.png"><br>
+<br>
+<img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;"> The name of the plugin code's jar
+is either held in a <span style="font-family: monospace;">&lt;runtime&gt;&lt;library
+name="customwidgetplugin.jar"&gt;&lt;/runtime&gt;</span> tag in the <span
+ style="font-style: italic;">plugin.xml</span> file for a pre 3.1
+plugin, or else for an OSGI 3.1compatible only plugin the jar file name
+is held in the <span style="font-style: italic;">MANIFEST.MF</span>
+file in the line <span style="font-family: monospace;">Bundle-ClassPath:
+customwidgetplugin.jar</span>.&nbsp;<br>
+<br>
+The package <span style="font-family: monospace;">org.eclipse.ve.example.customwidget</span>
+contains the Java code that is used to create the contents of the <span
+ style="font-style: italic;">customwidgetplugin.jar</span>.<br>
+</p>
+<h3><a name="Runtime_jar"></a>Runtime jar</h3>
+<p>The code for the <span style="font-family: monospace;">MyCustomPrompter</span>
+and its BeanInfo class are placed in the package<span
+ style="font-family: monospace;">org.eclipse.ve.example.customwidget.prompter</span>.&nbsp;
+When the plugin is deployed these classes are compiled not into the
+plugin's <span style="font-style: italic;">customwidgetplugin.jar</span>
+but
+instead to a file customwidgets.jar.&nbsp;&nbsp; The steps to create
+the customwidgets.jar are described in the section <a
+ href="#The_Custom_Widget">The Custom Widget</a>.</p>
+<h2><a name="The_Custom_Widget">The Custom Widget</a></h2>
+<p>The custom widget used in this tutorial extends SWT composite and
+has three child controls on it; a label, a text field, and a
+button.&nbsp; For this tutorial we used the Visual Editor to build the
+custom widget which, although a good exercise in using the Visual
+Editor, is outside the scope of what this tutorial is designed to cover
+- you can download it directly from CVS to begin working.&nbsp; You
+should download the two classes <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/src/org/eclipse/ve/example/customwidget/prompter/MyCustomPrompter.java">
+<font face="Courier New">MyCustomPrompter.java</font></a>, and <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/src/org/eclipse/ve/example/customwidget/prompter/ButtonSelectionListener.java">
+<font face="Courier New">ButtonSelectionListener.java</font></a> and
+place them into the plugin project in a package <span
+ style="font-style: italic;">org.eclipse.ve.customwidget.prompter.&nbsp;</span>
+This is illustrated below together with the Visual Editor opened
+against the <span style="font-style: italic;">MyCustomPrompter</span>
+class to show the three child controls.&nbsp; The package <span
+ style="font-style: italic;">org.eclipse.ve.example.customwidget</span>
+is where the visual editor classes&nbsp; (such as the specialized
+graphical edit part or code generation decoder) will reside, and the
+package <span style="font-style: italic;">org.eclipse.ve.customwidget.prompter</span>
+is where the classes reside that the user will use to build their
+runtime GUIs with.&nbsp;</p>
+<p><img style="border: 1px solid ; width: 721px; height: 357px;"
+ alt="RuntimeClasses" src="images/CustomWidgetPackage.png"></p>
+<p>For deployment the classes <span style="font-style: italic;">MyCustomPrompter</span>
+and <span style="font-style: italic;">ButtonSelectionListener</span>
+will be packaged in a runtime jar.&nbsp; To do this select the runtime
+package and use the pop up menu option <span style="font-weight: bold;">Export</span>
+to bring up the Export wizard.&nbsp; Select the JAR file option and
+name the JAR file <span style="font-style: italic;">customwidgets.jar.&nbsp;</span>
+This JAR file will be placed inside the plugin itself and there are two
+ways to do this.&nbsp; The first is to either export the JAR to a
+temporary location on your computer and then import it into the
+project.&nbsp; If you do this you should import the <span
+ style="font-style: italic;">customwidgets.jar</span> not as a JAR file
+as it contains no code of any interest to the plugin itself, but
+instead as a raw <span style="font-style: italic;">File</span>.&nbsp;&nbsp;
+The reason for this is that the inclusion of the runtime code in the
+plugin is not for the benefit of Eclipse and it will never be loaded by
+the Visual Editor into the Eclipse JVM.&nbsp; The user of the plugin
+will configure their Java project to use the custom prompter which is
+described in the later section <a href="#Using_a_classpath_container">Using
+a classpath container</a>, and the visual editor will insert the JAR
+into the -classpath of the VM that it uses to host the Java classes
+that make up the user's classes.<br>
+<br>
+The second way to ensure that the <span style="font-style: italic;">customwidgets.jar</span>
+is included in the plugin that avoids having to export to the file
+system and then re-import as a file, is to export straight to the
+directory used by the plugin itself.&nbsp; To see the location of the
+plugin you can open its properties and select Info.&nbsp; The figure
+below shows an example of this where the workbench location is
+D:\temp\tutorial and the JAR wizard creates customwidgets.jar into the
+directory used by the <span style="font-style: italic;">org.eclipse.ve.example.customwidget</span>
+plugin.&nbsp; If you do export directly to the workbench as shown below
+afterwards you will need to do a manual refresh of the project's
+contents using F5 (or the pop-up menu option) to ensure that the
+Eclipse workbench is in sync with the file system contents that have
+just been altered.<br>
+</p>
+<img style="border: 1px solid ; width: 466px; height: 401px;"
+ alt="JarExport" src="images/JARExport.png"><br>
+<br>
+<h3><a name="Testing_MyCustomPrompter"></a>Testing MyCustomPrompter</h3>
+<p>Having created the plugin you can now test it.&nbsp; To do this
+create an Eclipse launch configuration using the <span
+ style="font-weight: bold;">Run</span> menu to bring up the list of
+available launch configurations, selecting <span
+ style="font-style: italic;">Eclipse Application</span> and <span
+ style="font-style: italic;">New</span> and then running this using the
+default application.</p>
+<p><img alt="" style="border: 1px solid ; width: 261px; height: 311px;"
+ src="images/LaunchConfig.png"></p>
+<p><img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;"> On Eclipse 3.0.x an <i>Eclipse
+Application</i> launch configuration is called <i>Run-time Workbench.</i></p>
+<p>This will launch a second Eclipse workbench - the first being your
+one that you are using to develop the plugin and the second being the
+one you are going to use to deploy the plugin into.&nbsp; In the
+deployed workbench create a Java project and add <i>customwidgets.jar</i>
+to the Java build path.&nbsp; This is done using the pop-up menu option
+to open the <span style="font-weight: bold;">Properties</span> of the
+project and selecting <span style="font-weight: bold;">Java Build path
+...</span>.&nbsp; On the build path select the <span
+ style="font-style: italic;">Libraries</span> tab and <span
+ style="font-style: italic;">Add External Jar ...</span>.&nbsp; Point
+to the location of the jar in the plugin itself - for the example
+figure above this would be <span style="font-style: italic;">D:\temp\tutorial\org.eclipse.ve.example.customwidget.customwidgets.jar.</span>&nbsp;
+Having added the JAR containing the <span style="font-style: italic;">MyCustomPrompter</span>
+class you can now use it within a visual editor class.&nbsp; Create a
+test sample using <span style="font-weight: bold;">File &gt; New &gt;
+Visual class</span> and selecting <span style="font-weight: bold;">SWT
+&gt; Shell.&nbsp;</span> This will open the Visual Editor over a class
+with an SWT shell.&nbsp; Select the <span style="font-style: italic;">Choose
+Bean</span> palette entry and because <span style="font-style: italic;">customwidgets.jar</span>
+is in the project's build path (the effective -classpath used by the
+Eclipse Java compiler and by the Visual Editor) you can choose <span
+ style="font-style: italic;">MyCustomPrompter</span> and drop it onto
+the Shell.<br>
+<br>
+The behavior of <span style="font-style: italic;">MyCustomPrompter</span>
+is everything picked up by default as the Visual Editor will realize
+that <span style="font-style: italic;">MyCustomPrompter</span> extends
+<span style="font-style: italic;">org.eclipse.swt.widgets.Composite</span>
+so it will be rendered visually and have default property sheet, code
+generation, graphical edit part and event menu behavior.&nbsp; The
+remainder of this tutorial shows how to customize this behavior as
+described in the <a href="#Introduction">introduction</a>.</p>
+<h2><a name="Creating_a_Classpath_Container">Creating a classpath
+container</a></h2>
+<p>For the test described at the end of the preceding section the <span
+ style="font-style: italic;">MyCustomPrompter</span> class was made
+available to the user's Java project by them adding it as an external
+JAR.&nbsp; This isn't ideal as it requires the user knowing the
+location of the plugin directory on their computer and physically
+pointing to it.&nbsp; A better way is to use a classpath
+container.&nbsp; This allows one-touch configuration of a Java project
+to use a named container which handles all the internals of how to
+locate the correct runtime code.&nbsp;</p>
+<p>A Java container is a class that implements the JDT interface <span
+ style="font-style: italic;">org.eclipse.jdt.core.IClasspathContainer</span>.&nbsp;&nbsp;
+It is added to a Java project's build path using the <span
+ style="font-style: italic;">Add Library</span> button on the <span
+ style="font-style: italic;">Libraries</span> tab and an example of one
+used by the Visual Editor is <span style="font-style: italic;">org.eclipse.ve.internal.swt.SWTContainer</span>.&nbsp;&nbsp;
+As well as the JDT using the container to locate the runtime classes
+the Visual Editor uses this as a marker for extension behavior.&nbsp;
+When the Visual Editor opens over a project all of the containers are
+scanned and matched against extension points to see if there are any
+plugins that wish to contribute to the palette or any other custom
+visual editor behavior based on the classes included within the
+container.</p>
+<p>This tutorial doesn't create a new container class because the
+complexities involved doing this require knowledge of JDT concepts such
+as IPath and IClassPathEntry[].&nbsp; It is expected that commercial
+quality plugins extending the Visual Editor will create their own
+containers in which case the <span style="font-style: italic;">SWTContainer</span>
+class is a good example to look at to learn how to do this, however for
+simplicity the visual editor provides a reference implementation
+container class&nbsp; <span style="font-style: italic;">org.eclipse.ve.internal.java.core.RegisteredClassPathContainer.&nbsp;</span>
+The Registered container uses extension points to determine the JAR
+files it will add to the user's build path.</p>
+<p>The user experience is that a container called "Custom Prompter"
+will be available for them to add to a Java project's build path.&nbsp;
+This is described in the section <a href="#Using_a_classpath_container">Using
+a classpath container</a>.&nbsp; The JDT extension point <span
+ style="font-style: italic;">org.eclipse.jdt.ui.classpathContainerPage</span>
+allows contributions to be made for an entry to appear in the list of
+containers and be available for the user to select, as well as the
+wizard page that will then appear once <span
+ style="font-style: italic;">Next</span> is pressed.&nbsp; The wizard
+page is responsible for configuring the project's build path to
+actually add the container classpath entry.</p>
+<p>To add the <span style="font-style: italic;">Custom Prompter</span>
+entry to the list of available containers add the following to the <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/plugin.xml">
+plugin.xml</a> of the <span style="font-style: italic;">org.eclipse.ve.examples.customwidget</span>
+plugin.</p>
+<pre> <a name="ContainerPageDefinition"></a>&lt;extension<br> point="org.eclipse.jdt.ui.classpathContainerPage"&gt;<br> &lt;classpathContainerPage<br><img
+ style="width: 24px; height: 13px;" alt="tag1" src="../images/tag_1.gif"> name="Custom Prompter"<br><img
+ style="width: 24px; height: 13px;" alt="tag2" src="../images/tag_2.gif"> class="org.eclipse.ve.internal.java.wizard.RegisteredClasspathContainerWizardPage"<br><img
+ style="width: 24px; height: 13px;" alt="tag3" src="../images/tag_3.gif"> id="org.eclipse.ve.example.PrompterContainer"&gt;<br> &lt;/classpathContainerPage&gt;<br> &lt;/extension&gt;<br></pre>
+<p>The name <img style="font-style: italic; width: 24px; height: 13px;"
+ alt="tag1" src="../images/tag_1.gif"><span style="font-style: italic;">"Custom
+Prompter"</span> is the user visible String shown in the list of
+available libraries from the <span style="font-style: italic;">Add
+Library</span> wizard on the <span style="font-style: italic;">Libraries</span>
+tab on the <span style="font-style: italic;">Java build path.&nbsp;</span>
+In a commercial quality plugin it is expected this would come from a
+resource bundle and be externalized for different locales however this
+tutorial will hard code it to the literal <span
+ style="font-style: italic;">"Custom Prompter"</span>.&nbsp; Once the
+user selects a container library to be added and presses <span
+ style="font-style: italic;">Next</span> a wizard page is brought up
+showing configuration details of the particular container.&nbsp; This
+wizard page <span style="font-style: italic;">implements
+org.eclipse.jdt.ui.wizards.IClasspathContainerPage</span> and for a
+commercial quality plugin it is expected that a custom page would be
+written.&nbsp; The visual editor SWT container page
+org.eclipse.ve.internal.swt.SWTcontainerWizardPage is a good example to
+look at if your intention is to create a full wizard page, however the
+visual editor provides an example <span style="font-style: italic;">org.eclipse.ve.internal.java.wizard.RegisteredClasspathContainerWizardPage</span>
+that can be used <img style="width: 24px; height: 13px;" alt="tag2"
+ src="../images/tag_2.gif">.&nbsp;&nbsp;<br>
+<br>
+The container needs an id that uniquely identifies it within an Eclipse
+environment and this tutorial uses&nbsp;<img
+ style="width: 24px; height: 13px;" alt="tag3" src="../images/tag_3.gif"> <span
+ style="font-style: italic;">org.eclipse.ve.example.PrompterContainer.</span><br>
+<br>
+The RegisteredClasspathContainerWizardPage will add the container
+RegisteredClasspathContainer to the build path of the user's project
+once they select it.&nbsp; This is a generic container and to identify
+it as being an entry that should point to the runtime files required
+for the <span style="font-style: italic;">MyCustomPrompter</span> and
+its supporting classes requires two further extension points.&nbsp; If
+a specific custom container is being used then these are not required.<br>
+<br>
+The extension point <span style="font-style: italic;">org.eclipse.jdt.core.classpathContainerInitializer</span>
+specificies a container initializer that will be used by the JDT to
+configure containers.&nbsp; The following lines should be added to the
+plugin.xml for the <span style="font-style: italic;">org.eclipse.ve.examples.customwidget</span>
+plugin.</p>
+<pre> &lt;extension<br> point="org.eclipse.jdt.core.classpathContainerInitializer"&gt;<br> &lt;classpathContainerInitializer<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> class="org.eclipse.ve.internal.java.core.RegisteredClasspathContainerInitializer"<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> id="org.eclipse.ve.example.PrompterContainer"&gt;<br> &lt;/classpathContainerInitializer&gt;<br> &lt;/extension&gt;<br><br></pre>
+<p>The class used is a reference implementation provided by the Visual
+Editor and is <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_1.gif"> <span style="font-style: italic;">org.eclipse.ve.internal.java.core.RegisteredClasspathcontainerInitializer.&nbsp;</span>
+The id used must match the one described earlier as the id of the
+container wizard page.&nbsp; This tutorial is using <img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> <span
+ style="font-style: italic;">org.eclipse.ve.example.PrompterContainer.<br>
+<br>
+</span> Having configured the wizard page and the container initializer
+this will now add an instance of the RegisteredClasspathContainer to
+the user's build path of their Java project.&nbsp; This needs to be
+told where to locate the jars that contain the runtime code.&nbsp;
+There is an extension point used by the RegisteredClasspathContainer
+class named <span style="font-style: italic;">org.eclipse.ve.java.core.registrations.&nbsp;</span>
+To use it add the following lines to the plugin.xml.&nbsp; Note that if
+a true container implementation is being done instead then this
+extension point is not required - it is only used by the
+RegisteredClasspathContainer.&nbsp; For example, the project
+org.eclipse.ve.swt that defines the SWT extensions for the visual
+editor has its own custom behavior and does not require use of this
+extension point.&nbsp;</p>
+<pre> &lt;extension<br> point="org.eclipse.ve.java.core.registrations"&gt;<br> &lt;registration<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> container="org.eclipse.ve.example.PrompterContainer"<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> description="Custom Prompter"&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"> &lt;<a
+ name="library_definition"></a>library runtime="customwidgets.jar"/&gt;<br> &lt;/registration&gt;<br> &lt;/extension&gt;<br></pre>
+<p>The&nbsp; name of the container must match the id used when the
+classpath wizard page and container initializer were defined.&nbsp;
+This tutorial is using <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_1.gif"> <span style="font-style: italic;">org.eclipse.ve.example.PrompterContainer.&nbsp;&nbsp;</span>
+The container needs a description that will appear in the Java build
+path list of classpath entries and the tutorial uses the hard coded
+literal <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_2.gif"> <span style="font-style: italic;">"Custom
+Prompter".&nbsp;</span> The plugin element&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif">
+&lt;library runtime="customwidgets.jar".&gt; describes the actual
+location of the runtime jars that contain the <span
+ style="font-style: italic;">MyCustomPrompter</span> class.&nbsp; If
+there are multiple jars then the entry can be repeated.&nbsp;&nbsp; The
+location of the jar is relative to the plugin itself, so if <span
+ style="font-style: italic;">customwidgets.jar</span> were in a
+directory called <span style="font-style: italic;">jars</span> within
+the plugin then the entry would be runtime="jars/.customwidgets.jar".<br>
+<br>
+Having updated the plugin.xml file to define the classpath container
+the next step is to test this.</p>
+<h2><a name="Using_a_classpath_container"></a>Using a classpath
+container</h2>
+<p>Launch the Eclipse Application workbench using the <span
+ style="font-weight: bold;">Run</span> menu to open the runtime
+environment in which the <span style="font-style: italic;">MyCustomPrompter</span>
+class can be tested.&nbsp; If you have previously done this and created
+a Java project with a build path entry pointing to the <span
+ style="font-style: italic;">customwidgets.jar</span> as described
+earlier remove the jar from the build path.&nbsp; Otherwise create a
+new Java project.</p>
+<p>The next steps are the experience that a user of the plugin will
+take to configure a Java project to work with the <span
+ style="font-style: italic;">MyCustomPrompter</span> custom
+control.&nbsp; Open the properties for the Java project using the <span
+ style="font-weight: bold;">Properties</span> choice on the pop-up menu
+and select <span style="font-style: italic;">Java Build Path.</span><span
+ style="font-weight: bold;"><span style="font-style: italic;">&nbsp;</span></span>
+Select the <span style="font-style: italic;">Libraries</span> tab and
+choose the <span style="font-style: italic;">Add Library</span>
+button.&nbsp; This will bring up a list of all known Java containers
+which will include the <span style="font-style: italic;">Custom
+Prompter</span> as defined using the extension point
+org.eclipse.jdt.ui.classpathcontainerPage <a
+ href="#ContainerPageDefinition">earlier.</a> The figure below shows
+the Java build path for a project called <span
+ style="font-style: italic;">Test</span> and the Custom Prompter
+displayed in the list of available libraries opened from the <span
+ style="font-style: italic;">Add Library</span> button</p>
+<p><img style="border: 1px solid ; width: 641px; height: 471px;" alt=""
+ src="images/CustomPrompterContainer.png"></p>
+<p>Select the <span style="font-style: italic;">Custom Prompter</span>
+and press Next to view the wizard page <span
+ style="font-style: italic;">org.eclipse.ve.internal.java.wizard.RegisteredClasspathContainerWizardPage</span>
+defined <a href="#ContainerPageDefinition">earlier</a>.&nbsp; This is
+a generic example of a page and shows details of the jar that will be
+added by the page.&nbsp; For commercial quality plugins it is expected
+that this page however will be a specific to the particular
+plugin.&nbsp;</p>
+<p>Pressing Finish on the wizard page will configure the project (using
+the RegisteredClasspathcontainerInitializer defined earlier) to include
+the container <span style="font-style: italic;">RegisteredClasspathContainer</span>
+together with the id of<span style="font-style: italic;">org.eclipse.ve.examples.PrompterContainer.&nbsp;</span>
+Expanding the container in the project's build path will show that it
+points to the correct location for the customwidgets.jar as described
+in the <span style="font-family: monospace;">&lt;library
+runtinme="customwidgets.jar"&gt;</span> plugin.xml tag described <a
+ href="#library_definition">earlier</a>.<br>
+<br>
+<img style="border: 1px solid ; width: 281px; height: 147px;" alt=""
+ src="images/TestProjectBuildPath.png"><br>
+<br>
+<img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;"> The figures above for configuring
+the project Test's build path to include the <span
+ style="font-style: italic;">Custom Prompter</span> container entry
+show two other containers, namely the <span style="font-style: italic;">JRE
+System library</span> and the <span style="font-style: italic;">Standard
+Widget Toolkit.</span>&nbsp;&nbsp; The JRE container will be present on
+the Java project by default when it is first created, however the SWT
+container will not be.&nbsp; This is a container defined by the plugin
+project <span style="font-style: italic;">org.eclipse.ve.swt</span>
+that enables the Visual Editor to work with the SWT.&nbsp; If you
+created the Test project in the step <a
+ href="#Testing_MyCustomPrompter">Testing the custom prompter</a>
+described earlier when you created the test class using the <span
+ style="font-style: italic;">New Visual Class Wizard</span>and selected
+SWT application the wizard automatically added the SWT container to the
+project's build path as required.&nbsp; SWT support for the Visual
+Editor can be manually added by using the steps described above but
+selecting <span style="font-style: italic;">Standard Widget Toolkiit</span>
+instead of <span style="font-style: italic;">Custom Prompter</span> on
+the <span style="font-style: italic;">Add Library</span> wizard
+page.&nbsp; Adding dependent containers (CustomPrompter requires SWT)
+is not something that is supported by the reference implementation of
+RegisteredClassPathContainer and it is expected that commercial quality
+plugins will provide their own container class with the required logic
+to ensure consistency of dependent containers in the user's build path.<br>
+<br>
+Having configured the Test project to use the <span
+ style="font-style: italic;">Custom Prompter</span> container you can
+now test it by creating an SWT Shell from the <span
+ style="font-style: italic;">New Visual Class Wizard</span> and
+dropping <span style="font-style: italic;">MyCustomPrompter</span>
+using the <span style="font-style: italic;">Choose Bean ...</span>
+palette entry.&nbsp; the next step is to configure the palette so that
+a new category called <span style="font-style: italic;">Custom</span>
+is added that has an entry for the <span style="font-style: italic;">MyCustomPrompter</span>
+class.</p>
+<h2><a name="Adding_a_palette_category_for_our_widget">Adding a palette
+category for MyCustomPrompter</a></h2>
+<p>The visual editor's palette is described by an EMF model.&nbsp; EMF
+serializes to&nbsp; <a
+ href="http://www.omg.org/technology/documents/formal/xmi.htm">XMI</a>
+which is an XML representation of a graph of EMF objects.&nbsp; Plugins
+can define their own XMI files that describe the categories to be added
+to the palette, the groups these belong to, and the actual entries
+themselves.&nbsp; For the org.eclipse.ve.examples.customwidgets plugin
+there will be a palette XMI file that describes the single category and
+class to add.<br>
+<br>
+Create a file called customprompter.xmi in the plugin and open it with
+a text editor.&nbsp; The data for the file is shown below and can be
+downloaded directly from <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/customprompter.xmi">
+CVS</a> to avoid re-entry.<br>
+<br>
+</p>
+<pre> &lt;xmi:XMI xmi:version="2.0"<br> xmlns:xmi="http://www.omg.org/XMI"<br> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" <br> xmlns:palette="http:///org/eclipse/ve/internal/cde/palette.ecore"<br> xmlns:utility="http:///org/eclipse/ve/internal/cde/utility.ecore"&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> &lt;palette:CategoryCmp&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> &lt;categoryLabel xsi:type="utility:ConstantString" string="Custom"/&gt;<br> &lt;cmpGroups xsi:type="palette:GroupCmp"&gt;<br><br><img
+ style="width: 23px; height: 13px;" alt="" src="../images/tag_3.gif"> &lt;cmpEntries xsi:type="palette:AnnotatedCreationEntry" xmi:id="entry2" icon16Name="platform:/plugin/org.eclipse.ve.example.customwidget/icons/custom.gif"&gt;<br> &lt;objectCreationEntry xsi:type="palette:EMFCreationToolEntry"<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif"> creationClassURI<b>=</b>"java:/org.eclipse.ve.example.customwidget.prompter#MyCustomPrompter"/&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif"> &lt;entryLabel xsi:type="utility:ConstantString" string="Prompter"/&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_6.gif"> &lt;values xmi:type="ecore:EStringToStringMapEntry" key="org.eclipse.ve.internal.cde.core.nameincomposition" value="customPrompter"/&gt; <br> &lt;/cmpEntries&gt;<br><br> &lt;/cmpGroups&gt;<br> &lt;/palette:CategoryCmp&gt;<br> &lt;/xmi:XMI&gt;<br></pre>
+<p>The&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_1.gif"> &lt;palette:categoryCmp&gt; tag describes a
+palette category that has a label and groups, each group containing a
+number of entries.&nbsp; In the example for the tutorial the label is
+hard coded to the literal&nbsp;<img style="width: 24px; height: 13px;"
+ alt="" src="../images/tag_2.gif"> <span style="font-style: italic;">"Custom".&nbsp;</span>
+<img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;"> For
+a plugin that needed to support different language locales there is an
+EMF class utility:TranslatableString and examples of its usage can be
+found in the palette files for the plugin org.eclipse.ve.jfc.<br>
+<br>
+A single group is defined for the Custom category.&nbsp; If multiple
+groups are defined the palette demarks these visually with a
+separator.&nbsp; The group has a single entry that defines the&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif">
+graphic, the qualified&nbsp;<img style="width: 24px; height: 13px;"
+ alt="" src="../images/tag_4.gif"> name of the class and the literal <img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif">
+string that is displayed on the palette entry.&nbsp; To ensure that a
+good default name is used each time the user drops an instance of the
+CustomPrompter a&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_6.gif"> default <span style="font-style: italic;">nameincomposition
+</span>is specified to be "customPrompter". &nbsp; The&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif">
+graphic points to the URL of where the image is located, in this case
+the entry points to a file <span style="font-style: italic;">custom.gif</span>
+in the <span style="font-style: italic;">icons</span> directory of the
+plugin called <span style="font-style: italic;">org.eclipse.ve.example.customwidget.&nbsp;</span>
+The graphic used&nbsp;<img style="width: 16px; height: 16px;" alt=""
+ src="images/custom.gif"> is available in <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/icons/custom.gif">CVS</a>
+and you will
+need to create a folder called <span style="font-style: italic;">icons</span>
+in the plugin and copy it there.<br>
+<br>
+<img style="border: 1px solid ; width: 264px; height: 148px;" alt=""
+ src="images/IconsFolder.png"></p>
+<p><img src="../images/tip.gif" alt="Tip:"
+ style="width: 62px; height: 13px;">
+Because XMI files do not have anything to validate them at design time
+errors made in their syntax can easily be made that cause runtime
+problems that can be hard to trace and debug.&nbsp; The most
+straightforward way to write a Visual Editor XMI file is to copy an
+existing one that is similar to what you desire and then alter just the
+parts that need changing.</p>
+<p>Having created the <span style="font-style: italic;">customprompter.xmi</span>
+file we need to enable the Visual Editor to use it.&nbsp; This is done
+by associating the palette file with a classpath container, in our case
+the Custom Prompter.&nbsp;</p>
+<p>Now that we have our palette xmi file available, we need to
+contribute it to the Visual Editor.&nbsp; We do so by adding to the
+following extension in the plugin's&nbsp; <span
+ style="font-style: italic;">plugin.xml</span> manifest
+file.</p>
+<pre> &lt;extension<br><img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_1.gif"> point="org.eclipse.ve.java.core.contributors"&gt;<br> &lt;palette<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> container="org.eclipse.ve.example.PrompterContainer"<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"> categories="<b>customprompter.xmi</b>"/&gt;<br> &lt;/extension&gt; <br></pre>
+<p>The extension point used is&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> <span
+ style="font-style: italic;">org.eclipse.ve.java.core.contributors.</span>
+This has a &lt;palette&gt; child XML tag that points to the id of
+the&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_2.gif"> container whose inclusion in a project's
+build path causes the palette categories defined in the&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif">
+categories tag to be included. The palette categories tag is relative
+to the root of the plugin project, for example If the palette XMI file
+is in a folder called <span style="font-style: italic;">palette</span>
+then the entry would be <span style="font-family: monospace;">categories="palette/customprompter.xmi".</span></p>
+<p>When the Visual Editor starts it scans all of the project's build
+path entries and for any that are containers it looks to see whether
+there are any palette files.&nbsp; These are combined together to
+create the overall palette.</p>
+<p><img style="width: 63px; height: 13px;" src="../images/note.gif"
+ alt="Note:"> As well as describing palette entries directly it is
+possible to configure the Visual Editor to have an <font
+ face="Courier New">IConfigurationContribution</font> that has the
+ability to manipulate both the -classpath of the Visual Editor's VM and
+the palette with more fine control.&nbsp; An example of where this is
+done is by SWT that has to add runtime packages such as DLLs or
+packages to the VM's arguments, or a plugin that might wish to remove
+some of the existing palette entries (such as the JFC ones) for
+projects configured with their container present.</p>
+<p><img style="height: 13px; width: 62px;" alt="Tip:"
+ src="../images/tip.gif"> As
+well as defining containers to be the trigger point for Visual Editor
+custom behavior you can also use plugins by direct name&nbsp;using the <span
+ style="font-style: italic;">plugin=</span> tag. An example of where
+you might do this is if you were extending the Visual Editor to work
+with a set of classes that were contained in a specific plugin, so the
+user experience to enable a Java project would be to add a dependent
+plugin rather than a classpath container.&nbsp; An example of this
+might be something like a PDE type development environment for the
+actual end user.</p>
+<h3><a name="Testing_the_custom_palette"></a>Testing the custom palette</h3>
+<p>Having modified the manifest of the example plugin to include the
+plugin the next step is so test it.&nbsp; Do this by launching the
+Eclipse Application workbench and creating, or re-opening, a class <font
+ face="Courier New">MyShell</font> that was created from the <span
+ style="font-style: italic;">New Visual Class <span
+ style="font-style: italic;">Wizard</span></span> as an SWT
+application.&nbsp; The Visual Editor should detect that the container
+with an id of <span style="font-style: italic;">org.eclipse.ve.example.PrompterContainer</span>
+is in the project's build path and include the palette categories
+contained in the <span style="font-style: italic;">custompalette.xmi</span>
+file.&nbsp; This is shown in the figure below where the Prompter
+palette entry has been selected and dragged out onto the Shell.&nbsp;<br>
+<br>
+<img style="border: 1px solid ; width: 758px; height: 396px;" alt=""
+ src="images/CustomPalette.png"><br>
+<br>
+<img src="../images/tip.gif" alt="Note:" style="height: 13px; width: 62px;">
+When
+you launch the Eclipse Application workspace use the <span
+ style="font-style: italic;">-clean</span> option, as each time the <span
+ style="font-style: italic;">plugin.xml</span> manifest file has
+changed we need to be sure the runtime Eclipse environment clears its
+cached manifest details<br>
+<br>
+At this point in the tutorial you should have defined a classpath
+container that the user can configure a Java project with to include
+the jar containing the runtime code for the <span
+ style="font-style: italic;"><span style="font-style: italic;"><span
+ style="font-style: italic;">MyCustomPrompter</span></span></span>
+class.&nbsp; The extension point <span style="font-style: italic;">org.eclipse.ve.java.core.contributors</span>
+has been used to point to the location of a palette XMI file that
+contains a category with an entry for the class.<br>
+<br>
+The next steps are to configure the Visual Editor so that <span
+ style="font-style: italic;">MyCustomPrompter</span> has custom
+behavior over and above that it inherits by virtue of extending <span
+ style="font-style: italic;">org.eclipse.swt.widgets.Composite</span>.</p>
+<h2><a name="Using_an_ENUM_cell_editor">Enumerated values for the <span
+ style="font-style: italic;">type</span> property</a></h2>
+<p><span style="font-family: monospace;">MyCustomPrompter</span> class
+has an <i>int</i> property named <i style="font-weight: bold;">type</i>with
+<i>getType</i>() and <i>setType</i>(int aType) methods.&nbsp; While
+the signature of <i>setType</i> allows it to accept any int, the class
+itself only works with one of the three values 0, 1, or 2 The
+definition of the values is held in three static constants on the <span
+ style="font-family: monospace;">MyPrompterClass</span>.</p>
+<pre><span style="color: rgb(153, 0, 0);">public final static int</span> <span
+ style="font-style: italic; color: rgb(51, 51, 255);">DOTS</span> = 0;<br><span
+ style="color: rgb(153, 0, 0);">public final static int</span> <span
+ style="color: rgb(51, 51, 255); font-style: italic;">MORE</span> <span
+ style="font-style: italic;">=</span> 1;<br><span
+ style="color: rgb(153, 0, 0);">public final static int</span> <span
+ style="color: rgb(51, 51, 255); font-style: italic;">OPEN</span> = 2;<br></pre>
+<p>The significance of the three values is that they alter the button
+text for <span style="font-family: monospace;">MyCustomPrompter to</span>
+be either "...", "More", or "Open" respectively.&nbsp;&nbsp; The
+following code shows this for <span style="font-family: monospace;">MyCustomPrompter</span>'s
+<span style="font-family: monospace;">setType(int type)</span> method.</p>
+<pre><span style="color: rgb(153, 0, 0);">public void</span> setType (<span
+ style="color: rgb(153, 0, 0);">int</span> type) {<br> <span
+ style="color: rgb(153, 0, 0);">switch</span> (type) {<br> <span
+ style="color: rgb(153, 0, 0);">case</span> <span
+ style="font-style: italic; color: rgb(51, 51, 255);">DOTS</span>: button.setText(<span
+ style="color: rgb(51, 51, 255);">"..."</span>);<br> <span
+ style="color: rgb(153, 0, 0);">break</span>;<br> <span
+ style="color: rgb(153, 0, 0);">case</span> <span
+ style="font-style: italic; color: rgb(51, 51, 255);">MORE</span>: button.setText(<span
+ style="color: rgb(51, 51, 255);">"More"</span>);<br> <span
+ style="color: rgb(153, 0, 0);">break</span>;<br> <span
+ style="color: rgb(153, 0, 0);">case</span> <span
+ style="font-style: italic; color: rgb(51, 51, 255);">OPEN</span>: button.setText(<span
+ style="color: rgb(51, 51, 255);">"Open"</span>);<br> <span
+ style="color: rgb(153, 0, 0);">break</span>;<br> <span
+ style="color: rgb(153, 0, 0);">default</span>:<br> <span
+ style="color: rgb(153, 0, 0);">throw new</span> IllegalArgumentException(<span
+ style="color: rgb(51, 51, 255);">"Value "</span> + type + <span
+ style="color: rgb(51, 51, 255);">" must be one of 0, 1 or 2"</span>);<br> }<br>}<br></pre>
+<p>Whenever a class is selected in the Visual Editor graphical canvas
+or Java Beans tree viewer the Properties view will show its properties
+and their current values.&nbsp; The view can also be used to edit the
+property values, and the Visual Editor has a number of pre-defined
+editors associated with specific types.&nbsp; <span
+ style="font-style: italic;">int</span> properties for example have an
+editor that allows only valid <span style="font-style: italic;">int</span>
+values to be entered and by default the Visual Editor will use this
+whenever the <span style="font-style: italic;">type</span> property is
+selected based on its signature.</p>
+<p>This step of the tutorial describes how to override the default
+behavior so that the <span style="font-style: italic;">type</span>
+property is edited using a drop down list of the three allowable
+values.&nbsp; Also, instead of the values 0, 1 and 2 being displayed as
+the current values the literals "Dots", "More" and "Open" will be used
+instead.&nbsp; This is described as an objective of the tutorial in the
+<a href="#Introduction">Introduction</a>.</p>
+<p>To override the behavior of the <span style="font-style: italic;">type</span>
+property so that it has the desired behavior involves using a BeanInfo
+class.&nbsp; BeanInfo classes provide a way to describe a classes'
+design time behavior and art part of the <a
+ href="http://java.sun.com/products/javabeans/reference/api/index.html">JavaBeans
+specification</a>.&nbsp; The Visual Editor uses the JavaBeans
+specification wherever possible to define edit time behavior for a
+JavaBean.&nbsp;</p>
+<p>The BeanInfo specification allows for a class with the same name as
+its Java peer to exist that describes the edit time behavior of the
+class.&nbsp; For example, the tutorial class is named <span
+ style="font-family: monospace;">MyCustomPrompter</span> so there would
+be a class <span style="font-family: monospace;">MyCustomPrompterBeanInfo</span>
+that implements the interface <span style="font-family: monospace;">java.beans.BeanInfo</span>
+associated with it.&nbsp; The simplest way to create this class is to
+put it in the same package as the class it describes (e.g. <span
+ style="font-family: monospace;">org.eclipse.ve.example.customwidget</span>)
+.&nbsp; Strictly speaking this isn't good physical separation of
+behaviors as the BeanInfo classes should be kept apart from the runtime
+in a separate package and separate jar so they don't become part of the
+end user's actual deployment configuration.&nbsp; The Visual Editor
+does support scenarios where the BeanInfo is in separate packages and
+separate jars, however for the purpose of this tutorial the class <span
+ style="font-family: monospace;">org.eclipse.ve.examples.customwidget.MyCustomPrompterBeanInfo</span>
+will be created that extends the abstract superclass <span
+ style="font-family: monospace;">java.beans.SimpleBeanInfo</span>.</p>
+<p>The full source code for the BeanInfo can be downloaded from <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/src/org/eclipse/ve/example/customwidget/prompter/MyCustomPrompterBeanInfo.java">
+CVS.</a>&nbsp; A BeanInfo class is responsible for describing the list
+of properties used by a tool such as the Visual Editor, and also their
+edit time behavior.&nbsp; This is done by specializing the method <span
+ style="font-family: monospace;">PropertyDescriptor[]
+getPropertyDescriptors()</span>.&nbsp; The method returns an array of <span
+ style="font-family: monospace;">java.beans.PropertyDescriptor</span>
+objects, each one representing an item that will appear as a row in the
+Properties view and containing information about its display name, the
+Java get and set method associated with the property, as well as the
+rules for how the property shoud be edited.&nbsp; The specification
+allows support for editing behavior is provided by having a <span
+ style="font-family: monospace;">java.beans.PropertyEditor</span>
+defined against the <span style="font-family: monospace;">PropertyDescriptor</span>,
+and while the Visual Editor will work correctly if a <span
+ style="font-family: monospace;">PropertyEditor</span> class has been
+defined it also supports a shorthand notation for describing a list of
+enumerated values because this pattern occurs frequently in widget
+libraries (for example orientation properties on scroll bars, alignment
+values on layout constraints, etc...) and is the pattern used by the
+MyCustomPrompter's <span style="font-style: italic;">type</span>
+property.&nbsp; This shorthand notation involves defining a key value
+pair on the PropertyDescriptor, the key of which is the string literal <span
+ style="font-style: italic;">enumerationValues</span> and the value of
+which is an array of tri values.&nbsp; The structure of the array is a
+repeating set of <span style="font-weight: bold;">displayName, value,
+initializationString</span>.&nbsp; The displayName is the user visible
+string shown to the user in the Properties view, the value is the
+actual object that identifies the trivalue against a live property
+setting, and the initializationString is the fully qualified code
+fragment that is generated as argument to the property's set
+method.&nbsp; This is illustrated below in the method <span
+ style="font-family: monospace;">getPropertyDescriptors()</span> for
+the class <span style="font-family: monospace;">MyCustomPrompterBeanInfo</span>.</p>
+<pre> <span style="color: rgb(153, 0, 0);">public</span> PropertyDescriptor[] getPropertyDescriptors() {<br><br> <span
+ style="color: rgb(153, 0, 0);">try</span> {<br> PropertyDescriptor[] result = <span
+ style="color: rgb(153, 0, 0);">new</span> PropertyDescriptor[2];<br><br> result[0] = <span
+ style="color: rgb(153, 0, 0);">new</span> PropertyDescriptor(<span
+ style="color: rgb(51, 51, 255);">"text"</span>,MyCustomPrompter.class);<br> result[1] = <span
+ style="color: rgb(153, 0, 0);">new</span> PropertyDescriptor<span
+ style="font-weight: bold;">(<span style="color: rgb(51, 51, 255);">"type"</span></span>,MyCustomPrompter.class);<br><br> result[1].setValue(<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"><span
+ style="color: rgb(51, 51, 255);">"enumerationValues"</span>, <span
+ style="color: rgb(153, 0, 0);">new</span> Object[] {<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> <span
+ style="color: rgb(51, 51, 255);">"Dots"</span>, <span
+ style="color: rgb(153, 0, 0);">new</span> Integer(MyCustomPrompter.<span
+ style="color: rgb(51, 51, 255); font-style: italic;">DOTS</span>), <span
+ style="color: rgb(51, 51, 255);">"org.eclipse.ve.example.customwidget.prompter.MyCustomPrompter.DOTS"</span>,<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"> <span
+ style="color: rgb(51, 51, 255);">"More"</span>, <span
+ style="color: rgb(153, 0, 0);">new</span> Integer(MyCustomPrompter.<span
+ style="color: rgb(51, 51, 255); font-style: italic;">MORE</span>), <span
+ style="color: rgb(51, 51, 255);">"org.eclipse.ve.example.customwidget.prompter.MyCustomPrompter.MORE"</span>,<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif"> <span
+ style="color: rgb(51, 51, 255);">"Open"</span>, <span
+ style="color: rgb(153, 0, 0);">new</span> Integer(MyCustomPrompter.<span
+ style="color: rgb(51, 51, 255); font-style: italic;">OPEN</span>), <span
+ style="color: rgb(51, 51, 255);">"org.eclipse.ve.example.customwidget.prompter.MyCustomPrompter.OPEN"</span> <br> });<br> <br> <span
+ style="color: rgb(153, 0, 0);">return</span> result;<br> } <span
+ style="color: rgb(153, 0, 0);">catch</span> (IntrospectionException e) { <br> e.printStackTrace();<br> <span
+ style="color: rgb(153, 0, 0);">return null</span>;<br> }<br>}<br></pre>
+<p>The getPropertyDescriptors() method returns an array of two
+properties; <span style="font-style: italic;">text</span> and <span
+ style="font-style: italic;">type.&nbsp;</span> The <span
+ style="font-style: italic;">type</span> property has a key value pair
+assigned to it with a key of <img style="width: 24px; height: 13px;"
+ alt="" src="../images/tag_1.gif"> <span style="font-style: italic;">enumerationValues</span>
+and a value that is an array of nine elements.&nbsp; These nine
+elements represent the three enumerated values defined as a
+tri-values.&nbsp; The first of these is for the value 0 and is defined
+as <span style="font-weight: bold;">displayName,value,initString</span>
+of&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_2.gif"> "Dots", 0, "0".&nbsp; Instead of hard
+coding the 0 however they are coded to be the dynamic lookups of the
+actual value from the static constant, allowing the constant to
+internally change without requiring BeanInfo modification.&nbsp; The
+other two values <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_3.gif"> "More" and <img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif">
+"Open" are defined as tri-values for the 4th, 5th and 6th elements of
+the array and the 7th, 8th and 9th respectively.</p>
+<p>The <span style="font-family: monospace;">getPropertyDescriptors()</span>
+method returns a fully inclusive set of property descriptors for the
+JavaBean.&nbsp; For <span style="font-family: monospace;">MyCustomPrompter</span>
+the user experience the tutorial wants is that the inherited properties
+such as background, foreground, size, etc.. are present on the
+class.&nbsp; To achieve this rather than having the <span
+ style="font-family: monospace;">getPropertyDescriptors()</span> method
+collect the full list of all desired properties, the JavaBeans
+specification allows for the method <span
+ style="font-family: monospace;">BeanInfo[] getAdditionalBeanInfo()</span>
+to be specialized.&nbsp; This returns an array of <span
+ style="font-family: monospace;">BeanInfo</span> classes whose
+properties are merged together with the result of <span
+ style="font-family: monospace;">getPropertyDescriptors()</span> to
+create the complete list.</p>
+<pre> <span style="color: rgb(153, 0, 0);">public</span> BeanInfo[] getAdditionalBeanInfo(){<br> <span
+ style="color: rgb(153, 0, 0);">try</span>{<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> <span
+ style="color: rgb(153, 0, 0);">return new</span> BeanInfo[]{Introspector.<span
+ style="font-style: italic;">getBeanInfo</span>(Control.<span
+ style="color: rgb(153, 0, 0);">class</span>)};<br> } <span
+ style="color: rgb(153, 0, 0);">catch</span> (IntrospectionException e){<br> <span
+ style="color: rgb(153, 0, 0);">return new</span> BeanInfo[0];<br> }<br></pre>
+<img src="../images/tip.gif" alt="Note:" style="width: 62px; height: 13px;">
+<p>To create the array of BeanInfo classes representing the set of
+descriptors to merge one technique might be to write the code <span
+ style="font-family: monospace;"><span style="color: rgb(153, 0, 0);">return
+new</span> BeanInfo[] {CompositeBeanInfo.<span
+ style="color: rgb(153, 0, 0);">class</span>, ControlBeanInfo.<span
+ style="color: rgb(153, 0, 0);">class</span>, WidgetBeanInfo.<span
+ style="color: rgb(153, 0, 0);">class</span>}</span>.&nbsp; However
+doing so would be an attempt to hard code the names of the BeanInfo
+classes that may currently be associated with the superclass chain of <span
+ style="font-family: monospace;">MyCustomPrompter</span> but would fail
+if new BeanInfo classes were introduced or removed.&nbsp; The preferred
+technique for picking up inherited properties is with the statement <span
+ style="font-family: monospace;"><span style="color: rgb(153, 0, 0);">return
+new</span> BeanInfo[]{Introspector.<span style="font-style: italic;">getBeanInfo</span>(Composite.<span
+ style="color: rgb(153, 0, 0);">class</span>)}</span> where the
+argument to the <span
+ style="font-style: italic; font-family: monospace;">getBeanInfo</span><span
+ style="font-family: monospace;">(Class aClass)</span> method is the
+current bean's superclass.&nbsp; Rather than using <span
+ style="font-family: monospace;">Composite</span> as the starting point
+for merging inherited properties which is the immediate superclass of <span
+ style="font-family: monospace;">MyCustomPrompter</span>, <img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif">&nbsp;
+<span style="font-family: monospace;">Control</span> is used
+instead.&nbsp; The reason for this is that while <span
+ style="font-family: monospace;">MyCustomPrompter</span> extends <span
+ style="font-family: monospace;">Composite</span> it does this more for
+physical reasons so it can have its three child controls (the <span
+ style="font-family: monospace;">Label</span>, <span
+ style="font-family: monospace;">Text</span> and <span
+ style="font-family: monospace;">Button</span>), however as a black box
+custom class it itself doesn't want to inherit the behavior of <span
+ style="font-family: monospace;">Composite</span> such as the ability
+to have its layout changed.&nbsp; For this reason it is logically a
+subclass of <span style="font-family: monospace;">Control.</span></p>
+<h3><a name="Testing_the_enumerated_values_for_type"></a>Testing the
+enumerated values for <span style="font-style: italic;">type</span></h3>
+<p>Having updated <span style="font-family: monospace;">MyCustomPrompterBeanInfo.java</span>
+this must be re-exported to the <span style="font-style: italic;">customwidgets.jar</span>
+file.&nbsp; The customwidgets.jar in the plugin is the one that the <span
+ style="font-style: italic;">Custom Prompter</span> classpath container
+uses in its build path, and if the step of re-creating the <span
+ style="font-style: italic;">customwidgets.jar</span> file is not done
+when you launch the Eclipse Application you will be using the old
+version of the code.&nbsp; Currently Eclipse 3.1 does not support
+classpath container entries pointing to folder structures otherwise the
+RegisteredClassPathContainer could be coded to automatically look back
+into the directory structure of the development environment that
+launched it so for now don't forget to keep re-creating the <span
+ style="font-style: italic;">customwidgets.jar</span> file each time
+any of its contents have changed.</p>
+<img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;">
+<p>The Visual Editor caches information about a class and under some
+builds prior to VE 1.1 there are some issues with the cache going stale
+and not being automatically refreshed.&nbsp; If this occurs you can
+manually recycle the cache by selecting <span
+ style="font-weight: bold;">Project &gt; Clean</span> and also manually
+removing the directory <span style="font-style: italic;">org.eclipse.ve.beaninfo/cache</span>
+from the workbench directory.&nbsp;<br>
+<br>
+The changes to the <span style="font-family: monospace;">MyCustomPrompterBeanInfo</span>
+should mean that the <span style="font-style: italic;">type</span>
+property is now rendered with its display name rather than just the raw
+<span style="font-family: monospace;">int</span> value.&nbsp; The
+Properties view also will create a drop down list of the three
+allowable values.&nbsp; The figure below shows the list of the three
+values and when one is selected the argument to the <span
+ style="font-family: monospace;">setType(int)</span> method will be
+generated with the initializationString as defined in the <span
+ style="font-family: monospace;">BeanInfo</span> array.<br>
+<br>
+<br>
+<img style="border: 1px solid ; width: 808px; height: 527px;" alt=""
+ src="images/TypeCodeGeneration.png"><br>
+<br>
+The BeanInfo mechanism provides one technique to override default edit
+behavior for a Java class.&nbsp; The Visual Editor uses BeanInfo
+classes internally for many of its customizations and it recognizes
+externally created BeanInfo classes according to the JavaBeans
+specification.<br>
+<br>
+Some kinds of customization are not possible through the BeanInfo
+mechanism because while it provides a powerful way to describe edit
+time behavior and shape for a class the Visual Editor needs to be able
+to export some of its innermost extension points to the creator of the
+Java class, and the BeanInfo mechanism is designed to provide a
+portable way of customizing a Java class that can be transported easily
+between different IDEs and tools.&nbsp; For example, the next exercise
+in the tutorial is to override the behavior that occurs when the <span
+ style="font-style: italic;">text</span> property is edited to launch a
+dialog editor.&nbsp; This dialog editor will be written using the SWT
+and implement Eclipse specific interfaces, so describing it on the
+BeanInfo would violate the idea that BeanInfo classes are portable (as
+Eclipse interfaces and the SWT are not necessarily available to other
+visual design tools).<br>
+<br>
+For this reason the Visual Editor has a separate mechanism to extend a
+class's edit time behavior that is done through <span
+ style="font-style: italic;">override</span> files<span
+ style="font-style: italic;">.</span> This works in conjunction with
+the BeanInfo mechanism and provides the ability to leverage any Eclipse
+IDE or Visual Editor specific behavior for a class.</p>
+<h2><a name="The_EMF_override_mechanism"></a>The EMF override mechanism</h2>
+<p>At the heart of the Visual Editor is an EMF model that describes a
+class being edited.&nbsp; This model describes the instances, their
+relationships, scope, and property settings. Instances of objects in
+this model implement <span style="font-family: monospace;">org.eclipse.jem.internal.instantiation.base.IJavaInstance</span>.&nbsp;
+For example, a visual editor class that has a <span
+ style="font-family: monospace;">Shell</span> whose size is 200,200
+will contain two <span style="font-family: monospace;">IJavaInstance</span>
+objects.&nbsp; The first of these is for the <span
+ style="font-family: monospace;">Shell</span> itself and the second is
+for a <span style="font-family: monospace;">Point</span> representing
+the size.&nbsp; An EMF relationship between the <span
+ style="font-family: monospace;">Shell</span> and the <span
+ style="font-family: monospace;">Point</span> instance will exist whose
+structural feature represents the size property.<br>
+<br>
+EMF is a self describing structure, so behind the instance model there
+is a meta-model that describes the classes themselves - their methods,
+properties, events and hierarchy. The meta-model is created by the
+Visual Editor using a combination of reflection and JavaBeans
+Introspection.&nbsp; Instances in this metamodel consist of <span
+ style="font-family: monospace;">org.eclipse.jem.java.JavaClass</span>&nbsp;
+for each Java class.&nbsp; The structural features in the model are
+instances of EReference and represent the properties of the Java class.</p>
+<p>There are times when it is necessary to provide additional
+information that should be merged in with the EMF model of a
+JavaClass.&nbsp; An example of this is a new feature has to be added
+over and above those that can be determined by reflection.</p>
+<p>The Visual Editor uses the EMF model of a JavaClass not only to
+define its shape but also to define a number of helper classes used by
+the Visual Editor.&nbsp; These are typically mediator classes that are
+used by the different Visual Editor subsystems.&nbsp; The names of the
+mediator classes to use for a given JavaClass are held in the EMF
+model, thereby allowing specific classes to have custom behavior for
+each subsystem.&nbsp; Rather than hold these directly against the
+JavaClass (which is a generic model of Java classes that can be used by
+Eclipse plugins other than the Visual Editor)&nbsp; they are held
+against decorator classes that annotate the descriptive information of
+a class.&nbsp; These can be thought of similar to key value pairs that
+hold information rather than provide functionality.&nbsp;</p>
+<p>In summary, override files are used as means to modify, add to or
+delete from an EMF JavaClass whose shape is determined through using
+standard Java reflection combined with BeanInfo introspection.</p>
+<p>For a plugin to contribute override files its plugin manifest must
+implement the extension point <span style="font-style: italic;">org.eclipse.jem.beaninfo.registrations</span>.&nbsp;
+This specifies the trigger in the build path that will cause the
+overrides to be applied (either a classpath container or pre-requisite
+project) as well as the name of a Java package and where override files
+for its contents are held within the plugin folder structure.&nbsp; The
+code below shows the extension used for the plugin.xml for the <span
+ style="font-style: italic;">org.eclipse.ve.examples.customwidget</span>
+example in this tutorial.</p>
+<pre> &lt;extension<br> point="org.eclipse.jem.beaninfo.registrations"&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> &lt;registration container="org.eclipse.ve.example.PrompterContainer"&gt;<br> &lt;override<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> package="org.eclipse.ve.example.customwidget.prompter"<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"> path="overrides/org/eclipse/ve/example/customwidget/prompter"&gt;<br> &lt;/override&gt;<br> &lt;/registration&gt;<br> &lt;/extension&gt;<br></pre>
+<p>The classpath container with an id of <img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> is
+the one used by the <span style="font-style: italic;">Custom Prompter</span>
+library.&nbsp; The class being overriden is <span
+ style="font-family: monospace;">org.eclipse.ve.example.customwidget.prompter.MyCustomPrompter</span>
+so its<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_2.gif"> package is declared together with&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"> a
+folder location for where the override files will be stored.&nbsp; The
+location of the override folder is up to the creator of the plugin and
+is any arbitrary folder, however there is a convention that the Visual
+Editor uses where override files are held in a top level folder called <span
+ style="font-style: italic;">overrides</span> and then sub folders
+created for the package path. &nbsp; The Figure below shows the
+directory structure of the <span style="font-style: italic;">org.eclipse.ve.example.customwidget</span>
+plugin with the folder structure of <span style="font-style: italic;">/overrides/org/ecliose/ve/example/customwidget/prompter</span>
+(which matches that defined in the registration path=<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif">
+extension point).&nbsp;</p>
+<p><img style="border: 1px solid ; width: 361px; height: 253px;" alt=""
+ src="images/OverrideFileStructure.png"></p>
+<p>The Figure also shows a file <font face="Courier New">MyCustomPrompter.override</font>
+present in the override directory for the package.&nbsp; When the
+Visual Editor builds up the EMF JavaClass instance representing the
+shape of the MyCustomPrompter class this file will be read and merged
+into the definition.&nbsp; The syntax of this file can become complex
+due to the number of different ways in which different JavaClasses
+needed to be leveraged to implement custom functionality.&nbsp;&nbsp;
+The remainder of the three examples in this tutorial are each achieved
+through settings in the .override file.&nbsp; These are:</p>
+<ul>
+ <li>Custom cell editing for the text property</li>
+ <li>Overriding a GEF edit part</li>
+ <li>Overriding an expression decoder</li>
+</ul>
+<p>Each of these three is done through adding decorator classes.&nbsp;
+Decorator classes are added to ECore elements in the EMF model
+representing a class, either the JavaClass itself or an EReference
+representing one of its structural features&nbsp;&nbsp; Decorators are
+added through the &lt;annotations&gt; property of an ECore object.</p>
+<p>The type <span style="font-family: monospace;">org.eclipse.ve.internal.cde.decorators.BasePropertyDecorator</span>
+is responsible for specifying property sheet information such as the
+name of the classes for the JFace label provider or cell editor, or
+whether the entry in the property sheet should override the default
+behavior for whether it is expandable, whether null values are allowed,
+etc...</p>
+<p>The type <span style="font-family: monospace;">org.eclipse.ve.internal.cde.decorators.ClassDescriptorDecorator</span>
+is responsible for specifying custom GEF behavior such as custom edit
+parts for the graphical editor or the Java Beans tree view.</p>
+<h2><a name="Creating_A_SWT_cell_editor">Custom cell editing for the <span
+ style="font-style: italic;">text</span> property</a></h2>
+<p>Because <span style="font-family: monospace;">MyCustomPrompterBeanInfo</span>
+returns a <span style="font-style: italic;">text <span
+ style="font-family: monospace;">PropertyDescriptor</span></span> <span
+ style="font-family: monospace;"><span
+ style="font-family: arial,helvetica,geneva;">in</span></span> list of
+properties from the method <span style="font-family: monospace;">getPropertyDescriptors()[]</span>
+it will be included as an entry in the Properties view.&nbsp; Even
+without the explicit BeanInfo the class's signature includes the two
+methods <span style="font-family: monospace;"><span
+ style="color: rgb(153, 0, 0);">public</span> String getText()</span>
+and <span style="font-family: monospace; color: rgb(153, 0, 0);">public</span>
+<span style="font-family: monospace;">void setText(String aText)</span>
+which, because they follow the JavaBeans specification naming
+convention for a property's get and set methods, would be automatically
+detected by the Visual Editor through Introspection.</p>
+<p>The rules for the Properties view is that for a given property a
+BasePropertyDecorator is first looked for on the EReference
+representing the property in the EMF model.&nbsp; If one is found and
+it has an explicit labelProviderClassName or cellEditorClassName then
+this is used as appropiate.&nbsp; This is the mechanism that will be
+used for the <span style="font-style: italic;">text</span>
+property.&nbsp; If no decorator exists in the property defining an
+editor then if the EReference came originally through introspection the
+java.beans.PropertyDescriptor is queried to look for a
+propertyEditorClass or key of <span style="font-style: italic;">enumerationValues.&nbsp;</span>
+Failing both of these a default editor is used for the type of the
+property.</p>
+<p><img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;">
+To determine the default editor for a property based on its type a <span
+ style="font-family: monospace;">BasePropertyDecorator</span> on the <span
+ style="font-family: monospace;">JavaClass</span> EMF definition is
+used.&nbsp; If no direct decorator can be found annotating the <span
+ style="font-family: monospace;">JavaClass</span> then the superclass
+chain is searched to look for a decorator that provides a custom cell
+editor or label provider. For example, the <span
+ style="font-style: italic;">text</span> property is typed to <span
+ style="font-family: monospace;">java.lang.String</span> and the plugin
+<span style="font-style: italic;">org.eclipse.ve.java.core</span>
+provides a <span style="font-style: italic;">String.override</span>
+file that annotates the <span style="font-family: monospace;">JavaClass</span>
+with a a <span style="font-family: monospace;">BasePropertyDecorator</span>
+defining the label provider as <span style="font-family: monospace;">org.eclipse.ve.internal.java.core.StringJavaLabelProvider</span>
+and the cell editor as <span style="font-family: monospace;">org.eclipse.ve.internal.java.core.StringJavaCellEditor.</span>&nbsp;
+This is an example of where the Visual Editor's implementations of the
+JFC and SWT are done thoroughly using its own API.</p>
+<p>The cell editor that will be written for the <span
+ style="font-style: italic;">text</span> property will be placed in the
+package <span style="font-family: monospace;">org.eclipse.ve.example.customwidget</span>.&nbsp;
+This package will form part of the contents of the plugin jar that
+makes up the code that runs in the workbench and extends the Visual
+Editor with new Eclipse workbench behavior.&nbsp; The class created is <span
+ style="font-family: monospace;">org.eclipse.ve.example.customwidget.CustomLabelEditor</span>
+and extends the abstract superclass <span
+ style="font-family: monospace;">org.eclipse.jface.viewers.DialogCellEditor</span>.&nbsp;</p>
+<p>IDE specific extensions are defined by annotating the EMF JavaClass
+meta object that the Visual Editor uses.&nbsp; This is done with a
+.override file, and the contents of <span style="font-style: italic;">MyCustomPrompter.override</span>
+should be written as follows:</p>
+<pre> &lt;?xml version="1.0" encoding="UTF-8"?&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> &lt;xmi:XMI xmi:version="2.0" <br> xmlns:xmi="http://www.omg.org/XMI" <br> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br> xmlns:org.eclipse.ve.internal.cde.decorators="http:///org/eclipse/ve/internal/cde/decorators.ecore"<br> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" <br> xmlns:event="event.xmi"&gt;<br><br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> &lt;event:Add featureName="eStructuralFeatures"&gt;<br> &lt;addedEObjects xsi:type="ecore:EReference" <img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif">name="text" unsettable="true"&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif"> &lt;eAnnotations<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif"> xsi:type="org.eclipse.ve.internal.cde.decorators:BasePropertyDecorator" <br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_6.gif"> cellEditorClassname="org.eclipse.ve.example.customwidget/org.eclipse.ve.example.customwidget.CustomLabelEditor"/&gt;<br> &lt;/addedEObjects&gt;<br> &lt;/event:Add&gt;<br><br> &lt;/xmi:XMI&gt;<br></pre>
+<p>The header of a .override file declares the namespaces of the EMF
+packages used.&nbsp; Two packages are required to define the objects
+required for the CustomLabelEditor, the&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif">
+decorators.ecore package and the event model's package.</p>
+<p>The purpose of the file is to create a BasePropertyDecorator that
+defines the cell editor and annotate the structural feature for the <span
+ style="font-style: italic;">text</span> property.&nbsp; This is done
+by&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_2.gif"> adding a structural feature whose name is <span
+ style="font-style: italic;"><img style="width: 24px; height: 13px;"
+ alt="" src="../images/tag_3.gif"></span> <span
+ style="font-style: italic;">text.&nbsp;</span> Even through the object
+used is an <span style="font-style: italic;">Add</span> from the event
+model, the Visual Editor will pick up the fact that there is a <span
+ style="font-style: italic;">text</span> property defined from
+introspection (the one explicitly specified in the
+MyCustomPrompterBeanInfo or in its absence the one determined through
+get and set method pair matching) and merge in with this
+property.&nbsp; This way information that has come from introspection
+such as the get and set method names are combined with the EReference
+defined in the .override file.</p>
+<p>The&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_4.gif"> eAnnocations property defines the
+annotations for the EReference and the class we're creating is an
+instance of <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_5.gif"> <font face="Courier New">org.eclipse.ve.internal.cde.decorators.BasePropertyDecorator</font>.&nbsp;
+<img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;"> The <a name="xsi:type_structure"></a>xsi:type
+structure does not point to the
+Java package directly.&nbsp; The first portion of
+org.eclipse.ve.internal.cde.decorators points to the name of a
+namespace defined in the&nbsp;<img style="width: 24px; height: 13px;"
+ alt="" src="../images/tag_1.gif"> xmi:XMI opening tag.&nbsp; This
+namespace relates to the URL of decorators.ecore EMF package that
+itself is declared in the plugin org.eclipse.ve.cde with its own use of
+the extension point <span style="font-style: italic;">org.eclipse.emf.ecore.generated_package</span>
+to be the EMF package class
+org.eclipse.ve.internal.cde.decorators.DecoratorsPackage.</p>
+<p>The class
+org.eclipse.ve.internal.cde.decorators.BasePropertyDecorator has an EMF
+feature&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_6.gif"> cellEditorClassname.&nbsp; This will be
+used by the Visual Editor in the Properties view when the property is
+edited and points to our custom editor.</p>
+<p>Having defined the .override file that extends the <span
+ style="font-family: monospace;">MyCustomPrompter</span>'s <span
+ style="font-style: italic;">text</span> feature to have a custom IDE
+cell editor the next step is to write the code for the custom editor
+itself.&nbsp; <span style="font-family: monospace;">CustomLabelEditor</span>
+extends DialogCellEditor that provides the framework support for
+displaying a button to open the actual dialog.&nbsp;</p>
+<p><img style="border: 1px solid ; width: 211px; height: 46px;" alt=""
+ src="images/TextPropertyCellEditor.png"></p>
+<p>The next step is to write the dialog that allows the user to edit
+the <span style="font-style: italic;">text</span> property and ensure
+that this is launched from CustomLabelEditor.</p>
+<p>The dialog is created by extending the JFace helper class <span
+ style="font-family: monospace;">org.eclipse.jface.dialogs.TitleAreaDialog</span>
+that provides support for the title area and buttons.&nbsp; The content
+or client area of this will be built using the Visual Editor itself as
+a visual component class <span style="font-family: monospace;">org.eclipse.ve.example.customwidget.LabelDialogContentArea.</span></p>
+<p><img style="width: 719px; height: 524px;" alt=""
+ src="images/CustomTextEditorDialog.png"></p>
+<p>&nbsp;</p>
+<p>To logic for what occurs when the dialog is requested to be open is
+done by specializing the method <span style="font-family: monospace;">openDialogBox(Control
+cellEditorWindow)</span> in <span style="font-family: monospace;">CustomLabelEditor<span
+ style="font-family: arial,helvetica,geneva;">.</span></span> The
+contents for this method are shown below and perform two important
+steps.&nbsp; The first of these is to open an actual dialog that lets
+the user specify their text property, and the second is to get the
+result of this and create a new <span style="font-family: monospace;">IJavaInstance</span>
+that represents the next String for the Visual Editor's EMF instance
+model.&nbsp; The code below shows how to do this for <span
+ style="font-family: monospace;">CustomLabelEditor</span>.</p>
+<pre><span style="color: rgb(153, 0, 0);">protected</span> Object openDialogBox(Control cellEditorWindow) {<br> Display display = cellEditorWindow.getDisplay();<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> TitleAreaDialog dialog = <span
+ style="color: rgb(153, 0, 0);">new</span> TitleAreaDialog(display.getActiveShell()) {<br> LabelDialogContent content;<br> <span
+ style="color: rgb(153, 0, 0);">protected</span> Control createContents(Composite parent) {<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> Control result = super.createContents(parent);<br> setTitleImage(CustomwidgetPlugin.getCustomImage());<br> setTitle(<span
+ style="color: rgb(51, 51, 255);">"Prompter's text property editor"</span>);<br> setMessage(<span
+ style="color: rgb(51, 51, 255);">"Enter the text property, or select a default one by checking the Hello or GoodBye"</span>,IMessageProvider.<span
+ style="font-style: italic;">INFORMATION</span>); <br> <span
+ style="color: rgb(153, 0, 0);">return</span> result;<br> }<br> <span
+ style="color: rgb(153, 0, 0);">protected</span> Control createDialogArea(Composite parent) {<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"> content = <span
+ style="color: rgb(153, 0, 0);">new</span> LabelDialogContent(parent, SWT.<span
+ style="font-style: italic; color: rgb(51, 51, 255);">NONE</span>);<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif"> content.setString(stringValue);<br> <span
+ style="color: rgb(153, 0, 0);">return</span> content;<br> }<br> <span
+ style="color: rgb(153, 0, 0);">public</span> String toString() {<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif"> <span
+ style="color: rgb(153, 0, 0);">return</span> content.getString();<br> }<br> }; <br> <span
+ style="color: rgb(153, 0, 0);">if</span> (dialog.open() != Window.<span
+ style="font-style: italic; color: rgb(51, 51, 255);">CANCEL</span>) {<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_6.gif"> <span
+ style="color: rgb(153, 0, 0);">return</span> createStringJavaObject(dialog.toString());<br> } <span
+ style="color: rgb(153, 0, 0);">else</span> { <span
+ style="color: rgb(153, 0, 0);"> return</span> getValue();<br> }<br> }<br></pre>
+<p>The dialog editor used is an&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif">
+inner class that extends the jface abstract class
+org.eclipse.jface.dialogs.TitleAreaDialog.&nbsp; Three methods are
+specialized:</p>
+<p>The createContents(Composite parent) method is used to build the
+actual SWT content area of the dialog.&nbsp; The TitleAreaDialog
+supeclass provides a default structure that is invoked through
+calling&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_2.gif"> <span style="font-family: monospace;">super.createContents(parent)</span>,
+although details such as the image and title are overridden. The
+content area of the dialog is the area we're interested in putting out
+custom editing experience into, and this is done by creating an
+instance of&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_3.gif"> <span style="font-family: monospace;">LabelDialogContent</span>
+(that is built below).</p>
+<p>The content area for the TitleAreaDialog created by the
+LabelCellEditor is the class
+org.eclipse.ve.examples.customwidget.LabelDialogContent.&nbsp; This is
+available in CVS <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/src/org/eclipse/ve/example/customwidget/LabelDialogContent.java">LabelDialogContent.java</a>
+and extends <span style="font-family: monospace;">org.eclipse.swt.Composite</span>
+and was built using the Visual Editor.&nbsp; This has the methods <span
+ style="font-family: monospace;">public setString(String aString)</span>
+to set the current value of the String, and <span
+ style="font-family: monospace;">public String getString()</span> to
+return it.&nbsp; These are both called by the <span
+ style="font-family: monospace;">CustomLabelEditor</span> when it&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif">
+initializes the content area and&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif">
+returns the value.&nbsp;</p>
+<p>The <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_5.gif"> <span style="font-family: monospace;">toString()</span>
+method is specialized to return the value of the LableDialogContent,
+which represents the String entered by the user as the new <span
+ style="font-style: italic;">text</span> property.&nbsp; This is so
+that the value can be referenced by the CustomLabelEditor itself when
+it <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_6.gif">has created the actual object that will be
+set into the Visual Editor model.</p>
+<p>If the TitleAreaDialog isn't cancelled then the JFace cell editor
+needs to return the value of the newly created object representing the
+value of the <span style="font-style: italic;">text</span>
+property.&nbsp; The LabelDialogContent returns a java.lang.String and
+this requires conversion into an IJavaInstance representing the EMF
+JavaClass instance for the Visual Editor's model.&nbsp; This is done
+with the helper method&nbsp;<img style="width: 24px; height: 13px;"
+ alt="" src="../images/tag_6.gif"> <span style="font-family: monospace;">IJavaInstance
+createStringJavaObject(String aString);</span></p>
+<p>To create an <span style="font-family: monospace;">IJavaInstance</span>
+requires two steps.&nbsp; First the EMF <span
+ style="font-family: monospace;">JavaClass</span> needs to be located
+and then an instance of <span style="font-family: monospace;">IJavaInstance</span>
+needs to be created using this with rules as to how the actual
+instantion of the live Java object should occur (both in code and by
+the target VM).</p>
+<p>To locate a <span style="font-family: monospace;">JavaClass</span>
+involves looking up for the object on the current resource set.&nbsp; A
+resource set is a physical grouping of EMF documents and to locate the
+one being used by the Visual Editor it is held on the editorPart's GEF
+editDomain.&nbsp; The Visual Editor uses a subclass of default GEF edit
+domain called <span style="font-family: monospace;">org.eclipse.ve.internal.cde.core.EditDomain</span>.&nbsp;
+The editDomain provides a way of passing common objects (such as the
+target VM helper classes, the set of viewers, and the EMF resource set)
+around between different Visual Editor subsystems.&nbsp; For a cell
+editor to be given a reference to the edit domain it should implement
+the interface <span style="font-family: monospace;">org.eclipse.ve.internal.propertysheet.INeedData</span>
+that has a single method <span style="font-family: monospace;">public
+void setData(Object data);&nbsp;</span> The argument to this will be
+set by the Visual Editor to the editDomin object and the cell editor
+should store this in an instance variable.</p>
+<pre><span style="font-family: monospace;"><span
+ style="color: rgb(153, 0, 0);">public class</span> CustomLabelEditor <span
+ style="color: rgb(153, 0, 0);">extends</span> DialogCellEditor <span
+ style="color: rgb(153, 0, 0);">implements</span> INeedData {<br> private EditDomain fEditDomain;<br></span><span
+ style="font-family: monospace;"><span style="font-family: monospace;"><span
+ style="color: rgb(51, 204, 0);"><span style="color: rgb(0, 153, 0);"> // Remainder of class definition ...</span></span></span><br></span></pre>
+and<br>
+<pre> <span style="color: rgb(153, 0, 0);">public void</span> setData(Object data) {<br> fEditDomain = (EditDomain) data;<br> }<br></pre>
+<p>To lookup the resource set from an EditDomain can be done using the
+static helper method<span style="font-family: monospace;">JavaEditDomainHelper.getResourceSet(EditDomain
+anEditDomain);</span></p>
+<p>Now that the <span style="font-family: monospace;">CustomLabelEditor</span>
+has a handle to the Visual Editor's model's resource set it can look up
+<span style="font-family: monospace;">JavaClass</span> objects using
+the API <span style="font-family: monospace;">org.eclipse.jem.internal.beaninfo.core.Utilities.getJavaClass(String
+className, ResourceSet resourceSet);</span>&nbsp;&nbsp;&nbsp; In EMF to
+instantiate actual objects the package's factory should be used, so
+having obtained the <span style="font-family: monospace;">JavaClass</span>
+to get the <span style="font-family: monospace;">IJavaInstance</span>
+requires the method call <span style="font-family: monospace;">javaClass.getEPackage().getEFactoryInstance().create(javaClass);</span>&nbsp;</p>
+<p>Rather than having to do both steps however there is a helper API
+method <span style="font-family: monospace;">org.eclipse.ve.internal.java.core.BeanUtilities.createJavaObject(String
+qualifiedClassName, ResourceSet aResourceSet, String initString)</span>;&nbsp;
+Examples of its usage are shown below:</p>
+<pre>BeanUtilities.createJavaObject(<span
+ style="color: rgb(51, 51, 255);">"java.lang.Boolean"</span>, aResourceSet, <span
+ style="color: rgb(51, 51, 255);">"Boolean.TRUE"</span>); <span
+ style="color: rgb(0, 153, 0);">// Create a Boolean.TRUE instance</span><br>BeanUtilities.createJavaObject(<span
+ style="color: rgb(51, 51, 255);">"java.awt.Color"</span>, aResourceSet , <span
+ style="color: rgb(51, 51, 255);">"java.awt.Color.red"</span>); <span
+ style="color: rgb(0, 153, 0);">// Create an instance of the AWT color red</span><br>BeanUtilities.createJavaObject(<span
+ style="color: rgb(51, 51, 255);">"boolean"</span>, aResourceSet, <span
+ style="color: rgb(51, 51, 255);">"true"</span>); <span
+ style="color: rgb(0, 153, 0);">// Create an instance of the primitive boolean true</span><br>BeanUtilities.createJavaObject(<span
+ style="color: rgb(51, 51, 255);">"java.lang.String"</span>, aResourceSet, <span
+ style="color: rgb(51, 51, 255);">"\\"Hello World\\""</span>); <span
+ style="color: rgb(0, 153, 0);">// Create an instance of the String "Hello World"</span>
+</pre>
+<p><img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;">
+The third argument to the method represents the code fragment that will
+be used to instantiate the actual live Java instance.&nbsp; This is the
+actual argument that is used by the Visual Editor when it generates the
+<span style="font-family: monospace;">setProperty(Object propertyValue)</span>
+method.&nbsp; For the last example that was itself a String for the
+quotation marks to be present in the String when the code is generated
+they must be present in the literal itself which requires escaping them
+with a <span style="color: rgb(51, 51, 255);">\\.</span></p>
+<p>The protected helper method on <span style="font-family: monospace;">CustomLabelEditor</span>
+and called by <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_6.gif"> <span style="font-family: monospace;">openDialogBox(Control
+cellEditorWindow)</span> can now be written as follows.</p>
+<pre> <span style="color: rgb(153, 0, 0);">private</span> IJavaInstance createStringJavaObject(String aString) {<br> <span
+ style="color: rgb(153, 0, 0);">return</span> BeanUtilities.createJavaObject(<br> <span
+ style="color: rgb(51, 51, 255);">"java.lang.String"</span>,<br> JavaEditDomainHelper.getResourceSet(fEditDomain),<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> BeanUtilities.createStringInitString(aString)<br> );<br> }<br></pre>
+<p>Rather than just writing <span style="color: rgb(51, 51, 255);">"\\"</span>
++ aString + <span style="color: rgb(51, 51, 255);">"\\"</span> a
+helper method on&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_1.gif"> <span style="font-family: monospace;">BeanUtilities</span>
+is used to quote the user's string.&nbsp; The helper handles cases such
+as the string containing bona-fide escape characters the user put there
+that themselves need quoting.</p>
+<h3><a name="Rendering_the_text_value_in_the"></a>Rendering the <span
+ style="font-style: italic;">text value&nbsp;</span> in the Properties
+view</h3>
+<p>When the <span style="font-style: italic;">text</span> property is
+displayed in the Properties view we wish the user to be able to see the
+current value.&nbsp; This occurs with nothing extra to be done, because
+the <span style="font-style: italic;">text</span> property is typed to
+<span style="font-family: monospace;">java.lang.String</span> and there
+is a default label provider class for this provided by the <span
+ style="font-style: italic;">org.eclipse.ve.java.core</span> plugin as
+part of its <span style="font-style: italic;">String.override</span>.&nbsp;
+For this reason file the Visual Editor already knows how to render
+String properties as shown below.</p>
+<p><span style="font-family: monospace;"><img
+ style="border: 1px solid ; width: 266px; height: 63px;" alt=""
+ src="images/TextPropertyDisplayed.png"></span></p>
+<p>With the CustomLabelEditor however specific code is required to
+ensure that it displays the current value of the <span
+ style="font-style: italic;">text</span> property</p>
+<p><img style="border: 1px solid ; width: 265px; height: 66px;" alt=""
+ src="images/TextCurrentValue.png"></p>
+<p>This is done by specializing the method <span
+ style="font-family: monospace;">doSetValue(Object value);&nbsp;</span>
+This method is given an argument of an <span
+ style="font-family: monospace;">IJavaInstance</span> which represents
+the current value of the String object in the Visual Editor's EMF
+model.&nbsp; To convert from this to this to a <span
+ style="font-family: monospace;">java.lang.String</span> object can be
+done by accessing the target VM to query the value of the live String
+object.</p>
+<p>To write the code for the <span style="font-family: monospace;">doSetValue(Object
+value)</span> method requires an understanding of the API to work with
+the Visual Editor target VM objects</p>
+<h4><a name="Target_VM_and_its_APIs"></a>Target VM and its APIs</h4>
+<p>Live objects used by the Visual Editor exist only on the target VM
+and are never loaded by the Visual Editor inside the actual Eclipse
+workbench's JVM.&nbsp; For every object created on the target VM there
+is a proxy to it held by the Visual Editor inside the Eclipse
+JVM.&nbsp;&nbsp;&nbsp; This proxy is an instance of <span
+ style="font-family: monospace;">org.eclipse.jem.internal.proxy.core.IBeanProxy</span>
+and is able to perform tasks such as remote method&nbsp; invocation on
+the actual target VM instance.<br>
+<br>
+The API for this is modelled on the<span style="font-family: monospace;">java.lang.reflect</span>
+API however, unlike the reflection API which performs dynamic
+invocation within a single JVM, the bean proxy mechanism works between
+the Eclipse workbench's JVM where the proxies are, and Visual Editor's
+target JVM where the live instances exist.</p>
+<table style="text-align: left; width: 75%;" border="1" cellspacing="2"
+ cellpadding="2">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">java.lang and java.lang.reflect
+API</td>
+ <td style="vertical-align: top;">org.eclipse.jem.internal.proxy.core
+API</td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">Object</span> </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IBeanProxy</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">Class</span> </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IBeanTypeProxy</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">object.getClass()</span> </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IBeanProxy.getTypeProxy()</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">Method</span> </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IMethodProxy</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">Class.getMethod(String methodName)</span>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IBeanTypeProxy.getMethodProxy(String
+methodName)</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">Constructor</span> </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IConstructorProxy</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">Class.getConstructor(Class[] types)</span>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IBeanTypeProxy.getConstructorProxy(IBeanTypeProxy[]
+types)</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">Constructor.newInstance(Object[]
+initArgs)</span> </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IConstructorProxy.newInstance(IBeanProxy[]
+initArgs)</span> </td>
+ </tr>
+ </tbody>
+</table>
+<p>To locate instances of <span style="font-family: monospace;">IBeanProxy</span>
+(from which method and constructor proxies can be retrieved) a factory
+is used that is held on a proxy factory registry.&nbsp; The registry is
+used to create and cache instances of <span
+ style="font-family: monospace;">IBeanTypeProxy</span>, and can be
+located through a helper method which retrieves it from the GEF edit
+domain.&nbsp; The <span style="font-family: monospace;">IProxyFactoryRegistry</span>
+can return factories for retrieving instances of IBeanTypeProxy through
+the method getBeanTypeProxy(String typeName) as well as factories for
+creating new instances of <span style="font-family: monospace;">IBeanProxy</span>
+through the overloaded method <span style="font-family: monospace;">getBeanProxy(Object
+anObject)</span> with arguments representing the nine Java primitives,
+their <span style="font-family: monospace;">java.lang</span> peers as
+well as <span style="font-family: monospace;">java.lang.String</span>.</p>
+<p>The following code samples show how to create an instance of a <span
+ style="font-family: monospace;">java.io.File</span> for the file name <span
+ style="font-style: italic;">"C:\temp\foo.txt"</span> (i.e. the result
+of evaluating <span style="font-family: monospace;"><span
+ style="color: rgb(153, 0, 0);">new</span> java.io.File(<span
+ style="color: rgb(51, 51, 255);">"C:\temp\foo.txt"</span>)</span> on
+the target VM.</p>
+<pre>IProxyFactoryRegistry aProxyFactoryRegistry = JavaEditDomainHelper.getBeanProxyDomain(anEditDomain).getProxyFactoryRegistry();<br>IBeanTypeProxy javaIOFileBeanTypeProxy = aProxyFactoryRegistry.getBeanTypeProxy(<span
+ style="color: rgb(51, 51, 255);">"java.io.File"</span>);<br></pre>
+<p>Having obtained the <span style="font-family: monospace;">IBeanTypeProxy
+<span style="font-family: arial,helvetica,geneva;">the instance of</span></span>
+an <span style="font-family: monospace;">IBeanProxy</span> for the
+java.io.File can be created by locating the correct <span
+ style="font-family: monospace;">IConstructorProxy</span> and calling <span
+ style="font-family: monospace;">newInstance(IBeanProxy[])</span> with
+the correct arguments.</p>
+<pre>IBeanProxy fooStringBeanProxy = aProxyFactoryRegistry.getBeanProxyFactory().createBeanProxyWith(<span
+ style="color: rgb(51, 51, 255);">"C:\temp\foo.txt"</span>);<br>IConstructorProxy fileConstructorProxy = javaIOFileBeanTypeProxy.getConstructorProxy(<span
+ style="color: rgb(51, 51, 255);">"java.lang.String"</span>);<br>IBeanProxy fileProxy = fileConstructorProxy.newInstance(fooStringBeanProxy);<br></pre>
+<p>In addition to locating the IConstructorProxy and invoking as shown
+above there is a shorthand way of creating a bean proxy with a specific
+Java initialization string.&nbsp; This is with the method <span
+ style="font-family: monospace;">newInstance(String
+javaInitializationString)</span> on <span
+ style="font-family: monospace;">IBeanTypeProxy</span>.&nbsp; Using
+this the above code can be shortened to</p>
+<pre>IBeanProxy fileProxy = javaIOFileBeanTypeProxy.newInstance(<span
+ style="color: rgb(51, 51, 255);">"C:\temp\foo.txt"</span>);<br></pre>
+<p>The Visual Editor's model for the Java class being visually is an
+EMF graph of <span style="font-family: monospace;">IJavaInstance</span>
+objects. The API method <span style="font-family: monospace;">org.eclipse.jem.internal.proxy.core.BeanProxyUtilities.getBeanProxy(IJavaInstance
+aJavaInstance)</span> exists to obtain the bean proxy fom a Visual
+Editor EMF object.&nbsp; These are some more examples of the API for
+working with bean proxies.</p>
+<pre><span style="color: rgb(0, 153, 0);">// Retrieve a proxy to the result of calling the method getType() on a target VM for an IJavaInstance of MyCustomPrompter</span><br>IBeanProxy prompterProxy = BeanProxyUtilities.getBeanProxy(prompterJavaInstance); <span
+ style="color: rgb(0, 153, 0);">// Obtain an IBeanProxy from an IJavaInstance</span><br>IMethodProxy getTypeMethodProxy = prompterProxy.getTypeProxy().getMethodProxy(<span
+ style="color: rgb(51, 51, 255);">"getType"</span>);<br>IBeanProxy proxyToGetTypeResult = getTypeMethodProxy.invoke(prompterProxy);<br><br><span
+ style="color: rgb(0, 153, 0);">// Set the value of setType(String) method to the value "Frog"<br></span>IBeanProxy frogProxy = prompterProxy.getProxyFactoryRegistry().getBeanProxyFactory().createBeanProxyWith(<span
+ style="color: rgb(51, 51, 255);">"Frog"</span>);<br>IMethodProxy setTypeMethodProxy = prompterProxy.getTypeProxy().getMethodProxy(<span
+ style="color: rgb(51, 51, 255);">"setType"</span>,<span
+ style="color: rgb(51, 51, 255);">"java.lang.String"</span>);<br>setTypeMethodProxy.invoke(prompterProxy,frogProxy);<br></pre>
+<p>Working with remote proxies from the Eclipse workbench's JVM that
+point to instances of real live objects in the Visual Editor's target
+JVM provides a way of ensuring that the two are totally insultated and
+no class within the user's build path of a Java project needs to be
+loaded by the class loader or instantantiated within Eclipse.&nbsp;
+This provides a true editing sandbox which allows multiple instances of
+classes to exist across different editors working with different build
+paths and is the design principle that allows the Visual Editor to be
+extended to support new target environment and topologies other than
+just pure Java.&nbsp; However at some point the Visual Editor does need
+to transport objects back from the target JVM to Eclipse.&nbsp; An
+example of this is that having got an <span
+ style="font-family: monospace;">IBeanProxy</span> for a rectangle
+result to the <span style="font-family: monospace;">getBounds()</span>
+method this must be converted in its four constituient int values so
+that a draw2D rectangle can be created for the GEF figure.&nbsp;
+Likewise the Properties view shows the user the values of the target VM
+objects.&nbsp; The point at which an object on the target VM can be
+retrieved within the Eclipse workbench is when it is a primitive object
+or a java.lang peer of a primitive or a String instance.&nbsp; This is
+done by having four subinterfaces of <span
+ style="font-family: monospace;">IBeanProxy</span> in the package <span
+ style="font-family: monospace;">org.eclipse.jem.internal.proxy.core</span>.</p>
+<table cellpadding="2" cellspacing="2" border="1"
+ style="text-align: left; width: 50%;">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;">java.lang Object lookup</td>
+ <td style="vertical-align: top;">primitive lookup</td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IStringBeanProxy</span> </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">java.lang.String stringValue()</span> </td>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">IBooleanBeanProxy</span> </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">java.lang.Boolean getBooleanValue()</span>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">boolean booleanValue()</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">ICharacterBeanProxy</span> </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">java.lang.Character characterValue()</span>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">char charValue()</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">INumberBeanProxy</span> </td>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">int intValue()</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">long longValue()</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">byte byteValue()</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">short shortValue()</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">float floatValue()</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">double doubleValue()</span> </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"> <br>
+ </td>
+ <td style="vertical-align: top;"><span
+ style="font-family: monospace;">number numberValue()</span> </td>
+ </tr>
+ </tbody>
+</table>
+<br>
+<p><img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;">
+It is possible to register custom sub instances of <span
+ style="font-family: monospace;">IBeanProxy</span> for plugin specific
+objects and this occurs with <span style="font-style: italic;">org.eclipse.ve.jfc</span>
+plugin that has introduces the types <span
+ style="font-family: monospace;">IPointBeanProxy</span>, <span
+ style="font-family: monospace;">IRectangleBeanProxy</span> and <span
+ style="font-family: monospace;">IDimensionBeanProxy</span>.&nbsp; This
+can occur safely if you know that the Eclipse workbench's JVM contains
+the classes in its -classpath and that these are a compatible shape
+with the target VM's instances.&nbsp; This and other advanced topics
+such handling arrays, installing helper class on the target VM's
+-classpath for a classpath container, exceptions and debugging the
+target VM are covered in a later tutorial specific to the target VM
+architecture.</p>
+<h3><a name="Retrieving_the_target_VM_property_value"></a>Retrieving
+the target VM property value</h3>
+<p>Having covered some of the background to the target VM API the
+method <span style="font-family: monospace;">doSetValue(Object value)</span>
+can now be overriden on CustomLabelEditor.&nbsp; This is so that the
+Properties view can render correctly the value of the <span
+ style="font-style: italic;">text</span> property<span
+ style="font-style: italic;">.&nbsp;</span></p>
+<pre><img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_1.gif"> <span style="color: rgb(153, 0, 0);">protected</span> String stringValue = <span
+ style="color: rgb(51, 51, 255);">""</span>;<br> <span
+ style="color: rgb(0, 153, 0);"> // ...</span><br> <span
+ style="color: rgb(153, 0, 0);">protected void</span> doSetValue(Object value) {<br> <span
+ style="color: rgb(153, 0, 0);">if</span> (value != <span
+ style="color: rgb(153, 0, 0);">null</span>){<br> IStringBeanProxy stringBeanProxy =<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"> (IStringBeanProxy) BeanProxyUtilities.getBeanProxy(<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif">(IJavaInstance) value);<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif"> stringValue = stringBeanProxy.stringValue();<br> }<br> <span
+ style="color: rgb(153, 0, 0);">super</span>.doSetValue(value);<br> }<br> <span
+ style="color: rgb(0, 153, 0);"> // ...</span>
+<img style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif"> <span
+ style="color: rgb(153, 0, 0);">protected void</span> updateContents(Object value) {<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_6.gif"> <span
+ style="color: rgb(153, 0, 0);">super</span>.updateContents(stringValue);<br> }<br></pre>
+<p>A String instance varialble&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> is
+created to store the value of the <span style="font-style: italic;">text</span>
+property result that the CustomLabelEditor is working with.&nbsp;</p>
+<p>The doSetValue(Object) method will be called when the editor is
+first created by the Properties view and after each time the dialog
+editor is closed. The argument to this is an&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif">
+IJavaInstance for the String inside the Visual Editor's EMF model, so
+the target VM can be used to locate the IBeanProxy which, because the <span
+ style="font-style: italic;">type</span> property is typed to <span
+ style="font-family: monospace;">java.lang.String</span>, will be an
+instance of&nbsp; <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_3.gif"><span style="font-family: monospace;">IStringBeanProxy</span>.&nbsp;&nbsp;
+The <span style="font-family: monospace;">java.lang.String</span>
+value of this inside the workbench's JVM is retrieved using&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif"> <span
+ style="font-family: monospace;">IStringBeanProxy.stringValue()</span>
+and this is stored in the instance field <span
+ style="font-family: monospace;">stringValue</span>;</p>
+<p>To ensure that the contents of the Label used by the cell editor
+shows the string correctly the method&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif"> <span
+ style="font-family: monospace;">updateContents(Object value)</span> is
+overriden to ignore the argument and call&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_6.gif"> <span
+ style="font-family: monospace;">super.updateContents()</span> with the
+actual String.</p>
+<h3><a name="Testing_the_text_dialog_cell_editor"></a>Testing the <span
+ style="font-style: italic;">text</span> dialog cell editor</h3>
+<p>To create the curstom <span style="font-style: italic;">text</span>
+editor several steps were involved:</p>
+<ul>
+ <li>Use the extension point <span style="font-style: italic;">org.eclipse.ve.jem.beaninfo.registrations</span>
+to declare the /override folder structure associated with the
+PrompterContainer for the Java package org.eclipse.ve.examples.prompter</li>
+ <li>Create a <span style="font-style: italic;">MyCustomPrompter.override</span>
+file in the /overrides directory that added a BasePropertyDecorator to
+the EReference for the <span style="font-style: italic;">text</span>
+structural feature.</li>
+ <li>Set the <span style="font-style: italic;">cellEditorClassname</span>
+property of the BasePropertyDecorator to be the class
+org.eclipse.ve.examples.CustomLabelEditor</li>
+ <li>Create the <span style="font-family: monospace;">CustomLabelEditor</span>
+class extending the JFace abstract <span
+ style="font-family: monospace;">DialogEditorClass</span> (and
+implementing the interface <span style="font-family: monospace;">INeedData</span>
+to ensure it is given the Visual Editor's EditDomain)</li>
+ <li>Override the method <span style="font-family: monospace;">openDialogBox(Control
+aControl)</span> on <span style="font-family: monospace;">CustomLabelEditor</span>
+to open an inner subclass of <span style="font-family: monospace;">TextDialogEditor</span></li>
+ <li>The <span style="font-family: monospace;">TextDialogEditor</span>
+contains a content pane which allows the <span
+ style="font-style: italic;">text</span> property to be edited - this
+is a subclass of <span style="font-family: monospace;">Composite</span>
+called <span style="font-family: monospace;">LabelDialogContent</span></li>
+ <li>To render the property correctly in CustomLabelEditor the method<span
+ style="font-family: monospace;">doSetValue(Object)</span> and <span
+ style="font-family: monospace;">updateContents(value)</span> is
+overriden and the target VM string retrieved and displayed</li>
+</ul>
+<p>To test the <span style="font-style: italic;">text</span> property
+start the runtime Eclipse workbench, drop an instance of <span
+ style="font-family: monospace;">MyCustomPrompter</span> onto a <span
+ style="font-family: monospace;">Shell</span> or <span
+ style="font-family: monospace;">Composite</span> and select and edit
+the <span style="font-style: italic;">text</span> property.&nbsp; If
+it fails and has the default String label and cell editor look in the <span
+ style="font-style: italic;">.log</span> file in the .metadata
+directory of the target workbench for any syserr output.&nbsp; These
+will typically be because some XMI syntax in the .override file was
+entered incorrectly.&nbsp; If there is no output then it is possible
+that the definition of the beaninfo.registrations extension point is
+incorrect, and for this debug the <span style="font-family: monospace;">BeanInfoClassAdapter</span>
+class to see that the .override file being searched for.&nbsp;<br>
+<br>
+The next step of the tutorial will create a special GEF edit part for
+MyCustomPrompter that instead of just drawing an image of the live
+custom control, renders some text and icon on top of the graphic.<br>
+</p>
+<h2><a name="Overriding_a_GEF_edit_part">Supplying a custom GEF edit
+part</a></h2>
+<p>Classes implement the interface <span
+ style="font-family: monospace;">org.eclipse.gef.GraphicalEditPart</span>
+act as mediators between a model object and the draw2D API that renders
+the object onto the GEF canvas.&nbsp; The edit part to use for a given <span
+ style="font-family: monospace;">IJavaInstance</span> (the model
+object) by the Visual Editor is obtained from the <span
+ style="font-family: monospace;">ClassDescriptorDecorator</span> that
+annotates its JavaClass.&nbsp; If no explicitly defined <span
+ style="font-family: monospace;">ClassDescriptorDecorator</span> can be
+found, or the one found doesn't have a graphical edit part class
+defined, then the inheritance chain of the EMF <span
+ style="font-family: monospace;">JavaClass</span> (that shadows the
+Java type hierarchy) is searched until a graphical edit part class name
+is found.&nbsp; following this rule, in the absence of any override for
+<span style="font-family: monospace;">MyCustomPrompter</span> the
+Visual Editor will pick up the inherited edit part class <span
+ style="font-family: monospace;">CompositeGraphicalEditPart</span>
+because <span style="font-family: monospace;">MyCustomPrompter</span>
+extends <span style="font-family: monospace;">Composite</span> and
+this is what gives <span style="font-family: monospace;">MyCustomPrompter</span>
+its initial default edit experience.</p>
+<p>This section of the tutorial will build a custom graphical edit part
+named <span style="font-family: monospace;">org.eclipse.ve.example.customwidget.CustomWidgetGraphicalEditPart</span>.&nbsp;
+This will be declared in the <span style="font-style: italic;">MyCustomPrompter.override</span>
+file as being the graphical edit part class to use, and the class will
+be specialized to create the draw2D desired effects.</p>
+<p>MyCustomPrompter.override should be updated as below.&nbsp; (The <span
+ style="color: rgb(153, 153, 153);">grey</span> text fragments of XMI
+represents elements in the original file written for the <span
+ style="font-style: italic;">text</span> property custom editor and the
+black the new lines to add)</p>
+<pre><span style="color: rgb(153, 153, 153);"><br>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br> &lt;xmi:XMI xmi:version="2.0" <br> xmlns:xmi="http://www.omg.org/XMI" <br> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;<br></span><span
+ style="color: rgb(153, 153, 153);"><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"></span> <span
+ style="color: rgb(153, 153, 153);">xmlns:org.eclipse.ve.internal.cde.decorators="http:///org/eclipse/ve/internal/cde/decorators.ecore"</span><br><span
+ style="color: rgb(153, 153, 153);"> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" <br> xmlns:event="event.xmi"&gt;<br><br></span><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> &lt;event:Add featureName="eAnnotations"&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"> &lt;addedEObjects xsi:type="org.eclipse.ve.internal.cde.decorators:ClassDescriptorDecorator"<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif"> graphViewClassname="org.eclipse.ve.example.customwidget/org.eclipse.ve.example.customwidget.CustomWidgetGraphicalEditPart"&gt;<br> &lt;/addedEObjects&gt;<br> &lt;/event:Add&gt;<br><br><span
+ style="color: rgb(153, 153, 153);"><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif"> &lt;event:Add featureName="eStructuralFeatures"&gt;</span> <span
+ style="color: rgb(153, 153, 153);"> <br> &lt;addedEObjects xsi:type="ecore:EReference" name="text" unsettable="true"&gt;</span> <span
+ style="color: rgb(153, 153, 153);"> <br> &lt;eAnnotations xsi:type="org.eclipse.ve.internal.cde.decorators:BasePropertyDecorator"<br></span> <span
+ style="color: rgb(153, 153, 153);">cellEditorClassname="org.eclipse.ve.example.customwidget/org.eclipse.ve.example.customwidget.CustomLabelEditor"/&gt;</span> <span
+ style="color: rgb(153, 153, 153);"> <br> &lt;/addedEObjects&gt;</span> <span
+ style="color: rgb(153, 153, 153);"> <br> &lt;/event:Add&gt;<br></span> <span
+ style="color: rgb(153, 153, 153);">&lt;/xmi:XMI&gt; &lt;/xmi:XMI&gt;</span>
+</pre>
+<p>To specify that <span style="font-family: monospace;">BasePropertyDecorator</span>
+as annotating the <span style="font-style: italic;">type</span>
+structural feature (as was done for the CustomLabelEditor earlier)
+an&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_5.gif"> event:Add was created for the EMF feature <span
+ style="font-style: italic;">eStructuralFeature</span><span
+ style="font-style: italic;">s</span>.&nbsp; This represents the
+features or properties on the JavaClass, and the decorator was then
+defined as annotating the feature.&nbsp; To annotate the actual
+JavaClass (as opposed to one of its specific features) an&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> <span
+ style="font-family: monospace;">event:Add</span> is created directly
+on the <span style="font-style: italic;">eAnnotations</span> feature
+as a top level element in the XMI.&nbsp; Because the file name is <span
+ style="font-style: italic;">MyCustomPrompter.override</span> the
+Visual Editor will process this as an addition to the annotations of
+the EMF definition of the <span style="font-family: monospace;">MyCustomPrompter</span>
+class.</p>
+<p>The class being added as an annotation to MyCustomPrompter is an
+instance of&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_3.gif">
+org.eclipse.ve.internal.cde.decorators.ClassDescriptorDecorator.&nbsp;
+As described <a href="#xsi:type_structure">earlier</a> the XMI
+describes this as <span style="font-style: italic;">EMFPackageName:EMFClassName</span>
+which corresponds to the EMF registered package <span
+ style="font-family: monospace;">org.eclipse.ve.internal.cde.decorators.DecoratorsPackage</span>.&nbsp;&nbsp;
+A common coding error with XMI is to declare the element for an
+annotation assuming that it is the <span style="font-style: italic;">packageName:classNam</span>e
+without having the namespace definition&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> at
+the top of the XMI file.<br>
+&nbsp;<br>
+<span style="font-family: monospace;">ClassDescriptorDecorator</span>
+stores the name of the graphical edit part to use by GEF with the
+syntax of <span style="font-style: italic;">pluginName/qualifiedClassName</span>.
+For this tutorial the edit part created is called <span
+ style="font-family: monospace;">org.eclipse.ve.example.CustomWidgetGraphicalEditPart</span>
+and in the plugin name <span style="font-style: italic;">org.eclipse.ve.example.,customwidget</span>.</p>
+<p>The method responsible for creating the draw2D figure shown on the
+GEF canvas is <span style="font-family: monospace;">createFigure()</span>
+and this is overriden to place a draw2L label on top of the inherited
+behavior (an image of the live visual).&nbsp; The method is shown below
+and the full class list is available at <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/src/org/eclipse/ve/example/customwidget/CustomWidgetGraphicalEditPart.java">
+CustomWidgetGraphicalEditPart.java</a>.</p>
+<pre><span style="color: rgb(153, 0, 0);">public class</span> CustomWidgetGraphicalEditPart <span
+ style="color: rgb(153, 0, 0);">extends</span> <span
+ style="color: rgb(153, 0, 0);"><img style="width: 24px; height: 13px;"
+ alt="" src="../images/tag_1.gif"></span> ControlGraphicalEditPart {<br><br> <span
+ style="color: rgb(153, 0, 0);">protected</span> IFigure createFigure() {<br><br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> IFigure figure = super.createFigure();<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"> Label customFigure = <span
+ style="color: rgb(153, 0, 0);">new</span> Label(<span
+ style="color: rgb(51, 51, 255);">"VE Rules"</span>,CustomwidgetPlugin.getCustomImage());<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif"> customFigure.setForegroundColor(ColorConstants.red);<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif"> customFigure.setTextPlacement(PositionConstants.SOUTH);<br> <span
+ style="color: rgb(0, 153, 0);">// ImageFigure has no layout, so we will have to explicitly set the size().</span><br
+ style="color: rgb(0, 153, 0);"><br> <span
+ style="color: rgb(0, 153, 0);"> // To get a prefered size (before we look up the hierarchy), Label will need a Font</span>
+<img style="width: 24px; height: 13px;" alt="" src="../images/tag_6.gif"> customFigure.setFont(((GraphicalEditPart)getParent()).getFigure().getFont());<br> customFigure.setSize(customFigure.getPreferredSize());<br><br> figure.add(customFigure);<br><br> <span
+ style="color: rgb(153, 0, 0);">return</span> figure;<br> }<br> }<br></pre>
+<p>Although <span style="font-family: monospace;">MyCustomPrompter</span>
+extends <span style="font-family: monospace;">Composite</span> and the
+Visual Editor uses the class <span style="font-family: monospace;">CompositeGraphicalEditPart</span>
+for visually edited composites, the <span
+ style="font-family: monospace;">CustomWidgetGraphicalEditPart</span>
+is defined as extending <img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_1.gif"> <span style="font-family: monospace;">ControlGraphicalEditPart</span>.&nbsp;
+This is because <span style="font-family: monospace;">CompositeGraphicalEditPart</span>
+contains all of the GEF behavior to allow dropping of child controls
+and dealing with layout management, and while <span
+ style="font-family: monospace;">MyCustomPrompter</span> physically
+extends <span style="font-family: monospace;">Composite</span> to
+enable it to have child controls our usage of it is as a closed black
+box that can't accept more child controls and logically extends <span
+ style="font-family: monospace;">Control</span>'s behavior.&nbsp;</p>
+<p>The inherited implementation from <span
+ style="font-family: monospace;">ControlGraphicalEditPart</span>
+returns the class<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_2.gif"> <span style="font-family: monospace;">ImageFigure</span>.&nbsp;
+This has the logic required to render a picture of the live
+control.&nbsp; To this figure we add a draw2D Label that has an icon <img
+ style="width: 16px; height: 16px;" alt="" src="images/custom.gif">
+and the text <span style="color: rgb(255, 0, 0);">VE Rules</span>
+drawn in red.&nbsp; The Label is <img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif">
+created with the text and image and its&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif">
+foreground color and details about how to <img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif">
+place the text (below the icon) are specified.&nbsp; The size of the
+figure is set to its preferred size, and because this involves
+calculating using the fontMetrics to determine the width of the label's
+text the font must be&nbsp;<img style="width: 24px; height: 13px;"
+ alt="" src="../images/tag_6.gif"> explicitly set to the value it will
+acquire when it is added to the parent.&nbsp; Having completed the
+creation of the Label it is added as a child of the <span
+ style="font-family: monospace;">ImageFigure</span>.</p>
+<p>To test the CustomWidgetGraphicalEditPart launch the Eclipse
+workbench target and verify that the image of a MyCustomPrompter class
+now renders itself with an image of the live visual covered with the <span
+ style="color: rgb(255, 0, 0);">VE R</span><span
+ style="color: rgb(255, 0, 0);">ules</span> text and icon <img
+ style="width: 16px; height: 16px;" alt="" src="images/custom.gif">.&nbsp;</p>
+<img style="border: 1px solid ; width: 341px; height: 171px;" alt=""
+ src="images/GraphicalEditPart.png"><br>
+<br>
+<p><img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;">
+The original default behavior for MyCustomPrompter in the absence of
+its specific graphical edit part was to render the live visual with a
+border drawn around it. however the figure above shows that there is no
+border drawn.&nbsp; The border is not part of the natural behavior of
+an SWT composite (although one can be specified with the style bit of
+SWT.BORDER) and it drawn by the Visual Editor around a
+CompositeGraphicalEditPart so that an empty Composite with no children
+isn't otherwise invisible (as if it were the same color as its
+background it'd blend in and be hard to see on the design
+canvas).&nbsp; The behavior to render a design time border around a GEF
+figure is done by ConttrolGraphicalEditPart (which
+CustomWidgetGraphicalEditPart extends) by having initializationData
+supplied as part of its definition.&nbsp; InitializationData is used by
+the Visual Editor as a way of supplying parameters to a class so that
+different usages can supply custom implementations.&nbsp; It occurs by
+having the class defined in the .override file implement the interface <span
+ style="font-family: monospace;">org.eclipse.core.runtime.IExecutableExtension</span>.&nbsp;
+This has a single method <span style="font-family: monospace;">setInitializationData(IConfigurationElement
+config, String propertyName, Object data).&nbsp;</span><br>
+<br>
+When the Visual Editor parses a class name defined in a .override file
+if there is a colon symbol <span style="font-weight: bold;">:</span>
+after the class name then anything following this is parsed and passed
+into the setInitializationDataMethod(....).&nbsp; An example of this is
+the class ControlGraphicalEditPart implements the IExecutableExtension
+interface and uses the initData to determine whether a border should be
+drawn around the figure or not as follows:</p>
+<pre><span style="color: rgb(153, 0, 0);">public void</span> setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {<br> <span
+ style="color: rgb(153, 0, 0);">if</span> (data <span
+ style="color: rgb(153, 0, 0);">instanceof</span> String)<br> border = Boolean.<span
+ style="font-style: italic;">valueOf</span>((String) data).booleanValue();<br>}<br></pre>
+<p>and in the <span style="font-style: italic;">Composite.override</span>
+file in <span style="font-style: italic;">org.eclipse.ve.swt/overrides/org/eclipse/swt/widgets</span></p>
+<pre> &lt;addedEObjects xsi:type="org.eclipse.ve.internal.cde.decorators:ClassDescriptorDecorator"<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> graphViewClassname="org.eclipse.ve.swt/org.eclipse.ve.internal.swt.CompositeGraphicalEditPart:<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif">true" <br> &lt;/addedEObjects&gt;<br></pre>
+<p>The&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_1.gif"> graphViewClassname is defined as
+pluginName/qualifiedClassNane:initData and the value of <img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> <span
+ style="font-style: italic;">true</span> specifies that an SWT
+composite is drawn by the Visual Editor with the border.&nbsp; Because <span
+ style="font-style: italic;">MyCustomPrompter.override</span> does not
+specify the initData of <span style="font-style: italic;">true</span>
+it is drawn with the live widget as is.<br>
+<br>
+The next step in the tutorial is to look at how to affect the code
+generation subsystem of the Visual Editor.</p>
+<h2><a name="Overriding_an_Expression_Decoder">Custom code generation
+for the <span style="font-style: italic;">text</span> property</a></h2>
+<p>The code generation subsystem is responsible for parsing a .java
+file when it is opened by the Visual Editor and building up the graph
+of IJavaInstance objects that represent the model of the visual
+class.&nbsp; It does this by working with the JDT's Abstract Syntax
+Tree (AST) that represents a set of fine grained nodes for every
+compilable fragment of Java source.&nbsp; For every AST expression that
+is modeled by the Visual Editor (not all source represents code
+constructs that the Visual Editor is interested in showing to the user
+or collecting in its model) there is an expression decoder.&nbsp;&nbsp;
+The decoder has two helper classes; a feature mapper and a decoder
+helper.</p>
+<p>The feature mapper is responsible for tying together a source code
+expression in the actual Java source to a modeled feature in the Visual
+Editor's EMF model and vice-versa.</p>
+<p>The decoder helper has the knowledge of how to parse AST expressions
+and build up the Visual Editor model portion related to a specific
+expression type, as well as how to generate specific expression source
+code from the model.&nbsp;</p>
+<p>The task of the decoder class is largely a delegate to determine
+which feature mapper and decoder helper to use for a given source code
+expression</p>
+<p><img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;">
+Decoders do not generate AST nodes directly because in many cases the Java
+source is created instead by using JavaJet templates.&nbsp; These
+templates can be modified by users and recognized by the Visual
+Editor&nbsp; and will be covered in more detail in a specific tutorial
+covering the code generation subsystem.</p>
+<p>This tutorial will create a decoder helper that adds a comment <span
+ style="font-family: monospace; color: rgb(0, 153, 0);">// Prompter
+Text Property</span> to the line of Java code generated for the
+setText(String aString) method of the <span style="font-style: italic;">text</span>
+property.</p>
+<pre><span style="font-family: monospace;"><span
+ style="color: rgb(153, 0, 0);">private void</span> createMyCustomPrompter() {</span><br
+ style="font-family: monospace;"> <span style="font-family: monospace;">myCustomPrompter = <span
+ style="color: rgb(153, 0, 0);">new</span> MyCustomPrompter(sShell, SWT.<span
+ style="font-style: italic; color: rgb(51, 51, 255);">NONE</span>);</span> <br> <span
+ style="font-family: monospace;">myCustomPrompter.setText(<span
+ style="color: rgb(51, 51, 255);">"Text value"</span>); <span
+ style="color: rgb(0, 153, 0);">// Prompter Text Property</span></span><br><span
+ style="font-family: monospace;">}<br></span><br>The class created to do this is <span
+ style="font-family: monospace;">org.eclipse.ve.examples.customwidget.CustomPrompterDecoderHelper</span>.&nbsp; This is declared in the <span
+ style="font-style: italic;">MyCustomPrompter.override</span> file as annotating the <span
+ style="font-family: monospace;">JavaClass</span> definition for <span
+ style="font-family: monospace;">MyCustomPrompter</span> so the Visual Editor uses it.</pre>
+<pre><span style="color: rgb(192, 192, 192);"><span
+ style="color: rgb(153, 153, 153);"> &lt;?xml version="1.0" encoding="UTF-8"?&gt;</span></span><br> <span
+ style="color: rgb(153, 153, 153);">&lt;xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br> <span
+ style="color: rgb(153, 153, 153);">xmlns:org.eclipse.ve.internal.cde.decorators="http:///org/eclipse/ve/internal/cde/decorators.ecore"<br></span><span
+ style="color: rgb(153, 153, 153);"><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif"></span> xmlns:codeGenHelpers="platform:/plugin/org.eclipse.ve.java.core/overrides/codegenHelpers.ecore"<br> <span
+ style="color: rgb(153, 153, 153);">xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"<br> xmlns:event="event.xmi"&gt;</span><br><br><span
+ style="color: rgb(153, 153, 153);"><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"></span> &lt;event:AddMany featureName="eAnnotations"&gt;<br> <span
+ style="color: rgb(153, 153, 153);">&lt;addedEObjects xsi:type="org.eclipse.ve.internal.cde.decorators:ClassDescriptorDecorator"</span><br> <span
+ style="color: rgb(153, 153, 153);">graphViewClassname="org.eclipse.ve.example.customwidget/org.eclipse.ve.example.customwidget.CustomWidgetGraphicalEditPart"&gt;</span><br> <span
+ style="color: rgb(153, 153, 153);">&lt;/addedEObjects&gt;</span>
+<img style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> &lt;addedEObjects xsi:type="codeGenHelpers:CodeGenHelperClass"<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_4.gif">source="codegen.CodeGenHelperClass"<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif"> expDecoder="org.eclipse.ve.example.customwidget/org.eclipse.ve.example.customwidget.CustomPrompterDecoder"/&gt;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_6.gif"> &lt;/event:AddMany&gt;<br><br> <span
+ style="color: rgb(153, 153, 153);">&lt;event:Add featureName="eStructuralFeatures"&gt;</span><br> <span
+ style="color: rgb(153, 153, 153);">&lt;addedEObjects xsi:type="ecore:EReference" name="text" unsettable="true"&gt;</span><br> <span
+ style="color: rgb(153, 153, 153);">&lt;eAnnotations xsi:type="org.eclipse.ve.internal.cde.decorators:BasePropertyDecorator"<br></span> <span
+ style="color: rgb(153, 153, 153);">cellEditorClassname="org.eclipse.ve.example.customwidget/org.eclipse.ve.example.customwidget.CustomLabelEditor"/&gt;</span><br> <span
+ style="color: rgb(153, 153, 153);">&lt;/addedEObjects&gt;</span><br> <span
+ style="color: rgb(153, 153, 153);">&lt;/event:Add&gt;<br></span><span
+ style="color: rgb(153, 153, 153);"> &lt;/xmi:XMI&gt;</span>
+</pre>
+<p>Earlier when just the single ClassDecriptorDecorator was added as an
+annotation to MyCustomPrompter the XMI tag used in the .override file
+was <span style="font-style: italic;">&lt;event:Add&gt;</span>.&nbsp;
+This is the syntax to add a single object, however because a second
+annotation now needs to be added the file is changed to use the&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> <span
+ style="font-style: italic;"><span style="font-style: italic;"><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_6.gif"></span></span><span
+ style="font-style: italic;">&lt;event:AddMany&gt;</span> element for
+the two decorators.&nbsp; The decorator added is a CodeGenHelperClass
+and this is done through adding&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_3.gif">
+the namespace for codeGenHelper in the XMI package declarations and an
+xsi:type of <span style="font-style: italic;">namespace:CodeGenHelperClass</span>
+with syntax&nbsp;<img style="width: 24px; height: 13px;" alt=""
+ src="../images/tag_4.gif"> <span style="font-style: italic;">source="codegen.CodeGenHelperClass</span>".&nbsp;
+The expression decoder is stored in the expDecoder feature of the
+CodeGenHelperClass and defined with the syntax of&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_5.gif">
+pluginName/qualifiedClassName.</p>
+<p><font face="Arial">The <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/src/org/eclipse/ve/example/customwidget/CustomPrompterDecoder.java">CustomPrompterDecoder.java</a>.
+is responsible for determining which decoder helper is associated with
+which property.&nbsp; The superclass
+~org.eclipse.ve.internal.swt.codegen.SWTControlDecoder is used as this
+contains behavior such as dealing with the SWT code patterns required
+for constructor style bits, and the method initialDecoderHelper() is
+specialized to associate a decoder helper with the <span
+ style="font-style: italic;">text</span> property</font></p>
+<pre> <span style="color: rgb(153, 0, 0);">public class</span> CustomPrompterDecoder <span
+ style="color: rgb(153, 0, 0);">extends</span> SWTControlDecoder {<br><br> <span
+ style="color: rgb(153, 0, 0);">protected void</span> initialDecoderHelper() {<br> <span
+ style="color: rgb(0, 153, 0);"> // if it is the text property that this decoder is decoding, use a custom helper</span><br> <span
+ style="color: rgb(153, 0, 0);">if</span> (fFeatureMapper.getFeature(<span
+ style="color: rgb(153, 0, 0);">null</span>).getName().equals(<font
+ color="#0000ff">"text"</font>)) {<br> fhelper = <span
+ style="color: rgb(153, 0, 0);">new</span> CustomPrompterDecoderHelper(fbeanPart, fExpr, fFeatureMapper, this);<br> } <span
+ style="color: rgb(153, 0, 0);">else</span> {<br> <span
+ style="color: rgb(153, 0, 0);">super</span>.initialDecoderHelper();<br> }<br> }<br> }<br></pre>
+<p>The CustomPrompterDecoderHelper will extend the Visual Editor class
+org.eclipse.ve.internal.java.codegen.java.SimpleAttributeDecoderHelper.&nbsp;
+The method responsible for generating the code is generate(Object[])
+and this is specialized as below.&nbsp; The full source file can be
+viewed in CVS <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/src/org/eclipse/ve/example/customwidget/CustomPrompterDecoderHelper.java">
+CustomPrompterDecoderHelper.java</a>.</p>
+<pre> <span style="color: rgb(153, 0, 0);">public class</span> CustomPrompterDecoderHelper <span
+ style="color: rgb(153, 0, 0);">extends</span> SimpleAttributeDecoderHelper {<br><br> <span
+ style="color: rgb(153, 0, 0);">public</span> String generate(Object[] noArgs) <span
+ style="color: rgb(153, 0, 0);">throws</span> CodeGenException {<br> String result = <span
+ style="color: rgb(153, 0, 0);">super</span>.generate(noArgs);<br> <span
+ style="color: rgb(0, 153, 0);"> // Add a comment at the end of the expression</span><br> <span
+ style="color: rgb(153, 0, 0);">int</span> idx = result.lastIndexOf(<span
+ style="color: rgb(51, 51, 255);">';'</span>) + 1;<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> <span
+ style="color: rgb(153, 0, 0);">return</span> result.substring(0, idx) + <span
+ style="color: rgb(51, 51, 255);">" // Prompter Text Property "</span> + result.substring(idx, result.length());<br> }<br><br> }<br></pre>
+<p>The <span style="font-family: monospace;">generate(Object[])</span>
+method returns the String that is used for the code fragment generated
+and the <span style="font-family: monospace;">CustomPrompterDecoderHelper</span>
+adds a hard coded literal to the end of the inherited behavior (that
+creates the full expression for the setType(...) method invocation).</p>
+<p><img src="../images/note.gif" alt="Note:"
+ style="width: 62px; height: 13px;">
+Instead of having CustomPrompterDecoderHelper and CustomPrompterDecoder
+as two separate classes it would have been possible to have the decoder
+helper as an anonymous inner class of the decoder itself.&nbsp; By
+separating the decoder and the decoder helper into separate classes
+however enables for re-use, as other properties that wished to share
+the same rules as the <span style="font-style: italic;">text</span>
+property can have their own decoders that use the same decoder helper.</p>
+<p>You can test the decoder and decoder helper for the <span
+ style="font-style: italic;">text</span> property by launching the
+Eclipse target workbench.&nbsp; Use the Properties view to set the <span
+ style="font-style: italic;">text</span> property and ensure that the
+line is generated with the new comment.&nbsp; If it fails follow the
+same steps as for the custom property editor which
+involves looking in the .log file for any XMI syntax errors, using the
+BeanInfoClassAdapter to ensure the .override is being detected, and
+then finally debugging the decoder helper itself.&nbsp;</p>
+<p>The final step of the tutorial is to promote the <span
+ style="font-style: italic;">buttonSelection</span> event to the list
+of preferred events used by the Visual Editor when a list of events to
+be added is displayed to the user.</p>
+<h2><a name="Preferred_Event">Specifying a preferred event</a></h2>
+<p><span style="font-family: monospace;">MyCustomPrompter class</span>
+has the methods <span style="font-family: monospace;">addButtonSelectionEvent(ButtonSelectionEvent
+anEvent)</span> and <span style="font-family: monospace;">removeButtonSelectionEvent(ButtonSelectionEvent
+anEvent).</span>&nbsp; This allows anyone developing a class that uses
+the custom prompter to be able to get called back anytime the user
+presses its button.&nbsp; This is the button on the right hand side of
+the prompter that is labelled ..., <span style="font-style: italic;">Open
+or More </span>based on the <span style="font-style: italic;">type </span>property
+setting.&nbsp; If a button listener is added to the custom prompter the
+code generated is as below, and can be used for example to launch an
+additional dialog or perform user logic.<br>
+</p>
+<p><span style="font-family: monospace;"><span
+ style="color: rgb(153, 0, 0);">private void </span>createCustomPrompter()
+{</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; customPrompter
+= <span style="color: rgb(153, 0, 0);">new </span>MyCustomPrompter(sShell,
+SWT.NONE);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </span><span
+ style="font-family: monospace;"></span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
+customPrompter.addButtonSelectionListener(<span
+ style="color: rgb(153, 0, 0);">new </span>ButtonSelectionListener() {
+</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+<span style="color: rgb(153, 0, 0);">public void</span>
+buttonSelected(org.eclipse.swt.events.SelectionEvent e)
+{&nbsp;&nbsp;&nbsp; </span><br style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(<span
+ style="color: rgb(51, 51, 255);">"buttonSelected()"</span>); <span
+ style="color: rgb(0, 153, 0);">// TODO Auto-generated Event stub
+buttonSelected()</span></span><br style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp; }</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; });</span><span
+ style="font-family: monospace;"></span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">}</span><br>
+</p>
+<p>The purpose of this section is to show how to make it such that the <span
+ style="font-style: italic;">buttonSelected </span>event is the
+preferred event offered to the user because it is the one that will be
+most commonly used.<br>
+</p>
+<p>In the absence of any specific customization
+rules the Visual Editor will by default use JavaBeans reflection and
+associate these together with an event named <span
+ style="font-style: italic;">buttonSelection</span>.&nbsp; This will be
+available for the user to add events to from the <span
+ style="font-style: italic;">Add Event</span> wizard that is launched
+from the <span style="font-weight: bold;">Events &gt; Add Event ..</span>.
+pop-up menu option.</p>
+<p>The desired effect though is to override the behavior of the Visual
+Editor
+such as the buttonSelected event appears on the first level of the <span
+ style="font-weight: bold;">Events</span> cascaded menu, as shown in
+the figure below.&nbsp; The result of this would be that the usability
+of the MyCustomPrompter class has been improved because the user is
+more aware of its preferred API usage.</p>
+<p><img style="border: 1px solid ; width: 501px; height: 411px;" alt=""
+ src="images/EventsMenuAfter.png"></p>
+<p>Preferred events are defined according to the JavaBeans
+specification with a custom BeanInfo class.&nbsp; Earlier the tutorial
+created a specialized <a
+ href="http://dev.eclipse.org/viewcvs/indextools.cgi/%7Echeckout%7E/org.eclipse.ve.examples/org.eclipse.ve.example.customwidget/src/org/eclipse/ve/example/customwidget/prompter/MyCustomPrompterBeanInfo.java">
+MyCustomPrompterBeanInfo.java</a> to define the <span
+ style="font-style: italic;">enumerationValues</span> for the <span
+ style="font-style: italic;">type</span> property.&nbsp; This was done
+by specializing the <span style="font-family: monospace;">getPropertyDescriptors()</span>
+method.&nbsp; As well as defining the list of available properties and
+how they should be edited, a BeanInfo class defines the list of
+available events in the method <span style="font-family: monospace;">getEventSetDescriptors()</span>.&nbsp;
+This returns an array of <span style="font-family: monospace;">java.beans.EventSetDescriptor</span>
+objects and for <span style="font-family: monospace;">MyCustomPrompterBeanInfo</span>
+is written as below</p>
+<pre> <span style="color: rgb(153, 0, 0);">public</span> EventSetDescriptor[] getEventSetDescriptors() {<br><br> <span
+ style="color: rgb(153, 0, 0);">try</span> {<br> MethodDescriptor addButtonSelectionMD = <span
+ style="color: rgb(153, 0, 0);">new</span> MethodDescriptor(<br> ButtonSelectionListener.class.getMethod(<span
+ style="color: rgb(51, 51, 255);">"buttonSelected"</span>,<br> <span
+ style="color: rgb(153, 0, 0);">new</span> Class[]{SelectionEvent.<span
+ style="color: rgb(153, 0, 0);">class</span>})<br> );<br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif"> addButtonSelectionMD.setPreferred(<span
+ style="color: rgb(153, 0, 0);">true</span>);<br> <br> EventSetDescriptor addButtonSelectionED = new EventSetDescriptor(<br> <span
+ style="color: rgb(51, 51, 255);">"buttonSelection"</span>,<br> ButtonSelectionListener.<span
+ style="color: rgb(153, 0, 0);">class</span>,<br> <span
+ style="color: rgb(153, 0, 0);">new</span> MethodDescriptor[] {addButtonSelectionMD},<br> MyCustomPrompter.<span
+ style="color: rgb(153, 0, 0);">class</span>.getMethod(<span
+ style="color: rgb(51, 51, 255);">"addButtonSelectionListener"</span>,<span
+ style="color: rgb(153, 0, 0);">new</span> Class[]{ButtonSelectionListener.class}),<br> MyCustomPrompter.<span
+ style="color: rgb(153, 0, 0);">class</span>.getMethod(<span
+ style="color: rgb(51, 51, 255);">"removeButtonSelectionListener"</span>,<span
+ style="color: rgb(153, 0, 0);">new</span> Class[]{ButtonSelectionListener.<span
+ style="color: rgb(153, 0, 0);">class</span>})<br> );<br><br><img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif"> addButtonSelectionED.setPreferred(<span
+ style="color: rgb(153, 0, 0);">true</span>);<br> <br> return <span
+ style="color: rgb(153, 0, 0);">new</span> EventSetDescriptor[] {addButtonSelectionED};<br><br> } <span
+ style="color: rgb(153, 0, 0);">catch</span> (Exception e){<br> e.printStackTrace();<br> } <br> <span
+ style="color: rgb(153, 0, 0);">return null</span>;<br> }<br></pre>
+<p>To prompt a method to be preferred requies both the&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_1.gif">
+MethodDescriptor being set to preferred and also the&nbsp;<img
+ style="width: 24px; height: 13px;" alt="" src="../images/tag_2.gif">
+EventSetDescriptor.</p>
+<p>To test the preferred event launch the Eclipse workbench target
+environment and verify that the <span style="font-weight: bold;">Events</span>
+pop-up menu displays an item for <span style="font-style: italic;">buttonSelected</span>.</p>
+<h1><a name="A_complete_example"></a>A complete example</h1>
+<p>This tutorial has gone through the steps required to create the
+plugin <span style="font-style: italic;">org.eclipse.ve.example.customwidget</span>.&nbsp;
+The completed plugin is available <a href="customwidgetexample.zip">
+here</a> or can be obtained directly from CVS.<br>
+<br>
+To install the plugin from CVS into an Eclipse development environment
+attach to the host <span style="font-style: italic;">dev.eclipse.org</span>
+and repository path <span style="font-style: italic;">/home/tools</span>
+using a user id of <span style="font-style: italic;">anonymous</span>
+with no password required.&nbsp; The figure below illustrates the CVS
+perspective in Eclipse with the CVS Repositories view showing the
+repository correctly attached to.&nbsp; To create the new repository
+open the pop-up menu on the CVS Repositories view and select <span
+ style="font-style: italic; font-weight: bold;">New &gt; Repository
+Location.<br>
+<br>
+</span> Attach to the repository name<span style="font-style: italic;">/home/tools</span>
+on the host name<span style="font-style: italic;">dev.eclipse.org</span>.&nbsp;
+Specify a user name of anonymous which allows the code to be checked
+out.<span style="font-style: italic; font-weight: bold;"><br>
+</span> <span style="font-style: italic; font-weight: bold;"><br>
+<br>
+</span> <span style="font-weight: bold;"><img
+ src="images/RepositoriesView.png" alt="CVSRepositoriesView"
+ style="border: 1px solid ; width: 399px; height: 144px;"><br>
+<br>
+</span> The CVS Repositories view showing the correct
+repository for the tutorial's finished pugin<br>
+<br>
+Having attached to the repository expand the <span
+ style="font-style: italic;">Head</span> tree item and search for the
+plugin <span style="font-style: italic;">org.eclipse.ve.examples.&nbsp;</span>
+Expand this and select <span style="font-style: italic;">org.eclipse.ve.example.customwidget.</span>&nbsp;
+This is the complete plugin and to install it onto your workbench use
+the pop-up menu option <span style="font-weight: bold;">Check Out</span>
+as shown below<br>
+<br>
+<img style="border: 1px solid ; width: 395px; height: 272px;" alt=""
+ src="images/CheckOutAsProject.png">&nbsp;</p>
+<h2><a name="Conclusion">Conclusion</a></h2>
+<p>In&nbsp; this tutorial, we looked at a high level where to start and
+extend the Visual Editor and use specialized property cell editors,
+BeanInfo, GEF edit parts, palette, and CodeGen decoders.&nbsp; To do
+this required understanding how to use Java build path containers as
+the trigger point for Visual Editor custom behavior, and how to inject
+specialized code through the user of BeanInfo classes (for cross IDE
+extensions) and .override files (for Visual Editor only specific
+logic).&nbsp; An XMI file for a new palette category was created, and
+also the concept of the target VM was discussed.&nbsp;</p>
+<p>The software supplied with this article is for illustrative purposes
+only and should be used accordingly. The software is provided as is and
+with all faults, and hereby disclaims all other warranties and
+conditions, either expressed, implied or statutory, including, but not
+limited to, any (if any) implied warranties, duties or conditions of
+merchantability, of fitness for a particular purpose, of accuracy or
+completeness of responses, of results, of workmanlike effort, of lack
+of viruses, and of lack of negligence, all with regard to the software.</p>
+<p>Further tutorials will cover some of the topics introduced in more
+depth and we welcome all feedback.</p>
+
+<p><small>ref: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=88801">bug
+88801</a></small></p>
+
+<p><small>IBM is trademark of International Business Machines
+Corporation in the United States, other countries, or both. Java and
+all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other
+countries, or both. Microsoft and Windows are trademarks of Microsoft
+Corporation in the United States, other countries, or both. Other
+company, product, and service names may be trademarks or service marks
+of others.</small></p>
+</body>
+</html>
diff --git a/Article-VE-Custom-Widget/customwidgetexample.zip b/Article-VE-Custom-Widget/customwidgetexample.zip
new file mode 100644
index 0000000..54a312a
--- /dev/null
+++ b/Article-VE-Custom-Widget/customwidgetexample.zip
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/CheckOutAsProject.png b/Article-VE-Custom-Widget/images/CheckOutAsProject.png
new file mode 100644
index 0000000..751d6dd
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/CheckOutAsProject.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/CreatePluginWizard.png b/Article-VE-Custom-Widget/images/CreatePluginWizard.png
new file mode 100644
index 0000000..6c8c98b
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/CreatePluginWizard.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/CustomPalette.png b/Article-VE-Custom-Widget/images/CustomPalette.png
new file mode 100644
index 0000000..2ec0661
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/CustomPalette.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/CustomPrompterContainer.png b/Article-VE-Custom-Widget/images/CustomPrompterContainer.png
new file mode 100644
index 0000000..efac42d
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/CustomPrompterContainer.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/CustomTextEditorDialog.png b/Article-VE-Custom-Widget/images/CustomTextEditorDialog.png
new file mode 100644
index 0000000..eb9865c
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/CustomTextEditorDialog.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/CustomWidget.png b/Article-VE-Custom-Widget/images/CustomWidget.png
new file mode 100644
index 0000000..0b3b121
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/CustomWidget.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/CustomWidgetPackage.png b/Article-VE-Custom-Widget/images/CustomWidgetPackage.png
new file mode 100644
index 0000000..788f41f
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/CustomWidgetPackage.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/EventsMenuAfter.png b/Article-VE-Custom-Widget/images/EventsMenuAfter.png
new file mode 100644
index 0000000..632a10d
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/EventsMenuAfter.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/GraphicalEditPart.png b/Article-VE-Custom-Widget/images/GraphicalEditPart.png
new file mode 100644
index 0000000..2130b07
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/GraphicalEditPart.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/IconsFolder.png b/Article-VE-Custom-Widget/images/IconsFolder.png
new file mode 100644
index 0000000..af15555
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/IconsFolder.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/JARExport.png b/Article-VE-Custom-Widget/images/JARExport.png
new file mode 100644
index 0000000..6ec5ddd
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/JARExport.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/JARdiagram.png b/Article-VE-Custom-Widget/images/JARdiagram.png
new file mode 100644
index 0000000..1257a6a
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/JARdiagram.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/LaunchConfig.png b/Article-VE-Custom-Widget/images/LaunchConfig.png
new file mode 100644
index 0000000..9d3abd6
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/LaunchConfig.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/NewPalette.png b/Article-VE-Custom-Widget/images/NewPalette.png
new file mode 100644
index 0000000..4215512
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/NewPalette.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/OriginalEventsMenu.png b/Article-VE-Custom-Widget/images/OriginalEventsMenu.png
new file mode 100644
index 0000000..071b93c
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/OriginalEventsMenu.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/OriginalGraphicalEditPart.png b/Article-VE-Custom-Widget/images/OriginalGraphicalEditPart.png
new file mode 100644
index 0000000..75e73c3
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/OriginalGraphicalEditPart.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/OriginalPalette.png b/Article-VE-Custom-Widget/images/OriginalPalette.png
new file mode 100644
index 0000000..17ff671
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/OriginalPalette.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/OriginalTextProperty.png b/Article-VE-Custom-Widget/images/OriginalTextProperty.png
new file mode 100644
index 0000000..85730bf
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/OriginalTextProperty.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/OriginalTypeProperty.png b/Article-VE-Custom-Widget/images/OriginalTypeProperty.png
new file mode 100644
index 0000000..4841745
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/OriginalTypeProperty.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/OverrideFileStructure.png b/Article-VE-Custom-Widget/images/OverrideFileStructure.png
new file mode 100644
index 0000000..780524c
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/OverrideFileStructure.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/PreReqPlugins.png b/Article-VE-Custom-Widget/images/PreReqPlugins.png
new file mode 100644
index 0000000..f3d3d20
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/PreReqPlugins.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/RepositoriesView.png b/Article-VE-Custom-Widget/images/RepositoriesView.png
new file mode 100644
index 0000000..d87c169
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/RepositoriesView.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/RuintimeLibraryPluginName.png b/Article-VE-Custom-Widget/images/RuintimeLibraryPluginName.png
new file mode 100644
index 0000000..36b95fe
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/RuintimeLibraryPluginName.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/RuntimeLibraryPluginName.jpg b/Article-VE-Custom-Widget/images/RuntimeLibraryPluginName.jpg
new file mode 100644
index 0000000..ba95b9b
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/RuntimeLibraryPluginName.jpg
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/TestProjectBuildPath.png b/Article-VE-Custom-Widget/images/TestProjectBuildPath.png
new file mode 100644
index 0000000..d61307c
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/TestProjectBuildPath.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/TextCurrentValue.png b/Article-VE-Custom-Widget/images/TextCurrentValue.png
new file mode 100644
index 0000000..a92eaa9
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/TextCurrentValue.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/TextPropertyCellEditor.png b/Article-VE-Custom-Widget/images/TextPropertyCellEditor.png
new file mode 100644
index 0000000..77333bd
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/TextPropertyCellEditor.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/TextPropertyDisplayed.png b/Article-VE-Custom-Widget/images/TextPropertyDisplayed.png
new file mode 100644
index 0000000..6136b04
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/TextPropertyDisplayed.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/TypeCodeGeneration.png b/Article-VE-Custom-Widget/images/TypeCodeGeneration.png
new file mode 100644
index 0000000..c18f41c
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/TypeCodeGeneration.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/TypePropertyCellEditor.png b/Article-VE-Custom-Widget/images/TypePropertyCellEditor.png
new file mode 100644
index 0000000..e8f1cbe
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/TypePropertyCellEditor.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/TypePropertyLabelProvider.png b/Article-VE-Custom-Widget/images/TypePropertyLabelProvider.png
new file mode 100644
index 0000000..d7de847
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/TypePropertyLabelProvider.png
Binary files differ
diff --git a/Article-VE-Custom-Widget/images/custom.gif b/Article-VE-Custom-Widget/images/custom.gif
new file mode 100644
index 0000000..0c1282b
--- /dev/null
+++ b/Article-VE-Custom-Widget/images/custom.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/Idea.jpg b/Article-WTP-Persisting-EMF/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/Idea.jpg
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/editor_extension.jpg b/Article-WTP-Persisting-EMF/images/editor_extension.jpg
new file mode 100644
index 0000000..5d026b9
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/editor_extension.jpg
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/linux_only.gif b/Article-WTP-Persisting-EMF/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/linux_only.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/struts-config_1_0.png b/Article-WTP-Persisting-EMF/images/struts-config_1_0.png
new file mode 100644
index 0000000..3961f23
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/struts-config_1_0.png
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/struts-config_1_1.png b/Article-WTP-Persisting-EMF/images/struts-config_1_1.png
new file mode 100644
index 0000000..8d32749
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/struts-config_1_1.png
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/struts-config_1_2.png b/Article-WTP-Persisting-EMF/images/struts-config_1_2.png
new file mode 100644
index 0000000..7ae8692
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/struts-config_1_2.png
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/strutsconfig.png b/Article-WTP-Persisting-EMF/images/strutsconfig.png
new file mode 100644
index 0000000..b2143d2
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/strutsconfig.png
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/tag_1.gif b/Article-WTP-Persisting-EMF/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/tag_1.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/tag_2.gif b/Article-WTP-Persisting-EMF/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/tag_2.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/tag_3.gif b/Article-WTP-Persisting-EMF/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/tag_3.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/tag_4.gif b/Article-WTP-Persisting-EMF/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/tag_4.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/tag_5.gif b/Article-WTP-Persisting-EMF/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/tag_5.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/tag_6.gif b/Article-WTP-Persisting-EMF/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/tag_6.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/tag_7.gif b/Article-WTP-Persisting-EMF/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/tag_7.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/thumb-editor_extension.jpg b/Article-WTP-Persisting-EMF/images/thumb-editor_extension.jpg
new file mode 100644
index 0000000..4db7d5c
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/thumb-editor_extension.jpg
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/thumb-struts-config_1_0.png b/Article-WTP-Persisting-EMF/images/thumb-struts-config_1_0.png
new file mode 100644
index 0000000..443f222
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/thumb-struts-config_1_0.png
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/thumb-struts-config_1_1.png b/Article-WTP-Persisting-EMF/images/thumb-struts-config_1_1.png
new file mode 100644
index 0000000..bbe702f
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/thumb-struts-config_1_1.png
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/thumb-struts-config_1_2.png b/Article-WTP-Persisting-EMF/images/thumb-struts-config_1_2.png
new file mode 100644
index 0000000..c449833
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/thumb-struts-config_1_2.png
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/thumb-strutsconfig.png b/Article-WTP-Persisting-EMF/images/thumb-strutsconfig.png
new file mode 100644
index 0000000..e675f8d
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/thumb-strutsconfig.png
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/tip.gif b/Article-WTP-Persisting-EMF/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/tip.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/tryit.gif b/Article-WTP-Persisting-EMF/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/tryit.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/images/win_only.gif b/Article-WTP-Persisting-EMF/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/images/win_only.gif
Binary files differ
diff --git a/Article-WTP-Persisting-EMF/persisting.html b/Article-WTP-Persisting-EMF/persisting.html
new file mode 100644
index 0000000..6574035
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/persisting.html
@@ -0,0 +1,475 @@
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type"
+ CONTENT="text/html; charset=windows-1252">
+<title>Persisting EMF models with WTP</title>
+<link rel="stylesheet" href="../default_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif"
+ size="2">Copyright &copy; 2005 Daniel Rohe</font>
+<table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP" colspan="2" bgcolor="#0080C0"><b><font
+ face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse Corner
+ Article</font></font></b></td>
+ </tr>
+</table>
+</div>
+<div align="left">
+<h1><img src="images/Idea.jpg" height="86" width="120" align="CENTER"
+ alt=""></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">Persisting EMF models with WTP</h1>
+
+<blockquote><b>Summary</b> <br>
+This article will guide you through an example where an EMF model is
+created without serialization and the serialization is done with the
+framework from the WTP plugin <em>org.eclipse.wst.common.emf</em>.
+<p><b>Daniel Rohe</b><br>
+<font size="-1">October 10, 2005</font></p>
+</blockquote>
+
+<hr width="100%">
+<h2>Introduction</h2>
+<p>The WTP project provides a huge collection of plug-ins for developing
+web applications. For developing J2EE applications, the developers of
+the WTP have created EMF models for the deployment descriptors like
+ejb-jar.xml or web.xml. These EMF models work with different versions of
+these deployment descriptors and provide a single API to access and edit
+the descriptors. Using this API, several tools that work with these
+descriptors have been developed.</p>
+<p>WTP includes a framework to serialize the EMF model, but
+unfortunately it is not very well documented. It provides a facility to
+load and store EMF models into XML documents that have slightly
+different document type definitions. In this article I will explain the
+use of this framework for serialization of an EMF model based on
+different versions of an XML document. I hope my article helps you to
+understand the framework so you can use it with your own model.</p>
+<h2>EMF model</h2>
+<p>The EMF model used in this article is created from the latest version
+of the Document Type Definition (DTD) of the Apache Struts configuration
+file. The EMF model contains classes that reflect the main DOM elements
+from the DTD. The following pictures illustrate the different DTDs and
+the single EMF model. The first three pictures contain a graphical
+notation of the three DTDs, whereas the last picture contains a class
+diagram with classes and data types from the EMF model.</p>
+<table width="100%" border="0">
+ <tr align="center" valign="middle">
+ <td><a href="images/struts-config_1_0.png"><img
+ src="images/thumb-struts-config_1_0.png" width="160" height="141"
+ border="0" alt="" /></a></td>
+ <td><a href="images/struts-config_1_1.png"><img
+ src="images/thumb-struts-config_1_1.png" width="160" height="241"
+ border="0" alt="" /></a></td>
+ <td><a href="images/struts-config_1_2.png"><img
+ src="images/thumb-struts-config_1_2.png" width="160" height="252"
+ border="0" alt="" /></a></td>
+ </tr>
+</table>
+<p><a href="images/strutsconfig.png"><img
+ src="images/thumb-strutsconfig.png" width="640" height="417" border="0"
+ alt="" /></a></p>
+<p>As you can see in the first three pictures, each version differs
+slightly from the others. The EMF model reflects the latest version by
+containing the elements from all previous DTD versions. In the EMF model
+I've extracted some base functionality in abstract classes. So the
+Configurable class contains only a reference to the SetPropertyType
+class which represents a set-property element. The other change is the
+introduction of the class Visualizable that contains the properties
+necessary for displaying the element in a graphical editor. Another
+important object to note here is the class StrutsConfigType. This class
+represents the struts-config element from the configuration file. The
+StrutsConfigType class is the root element in the containment hierarchy
+like the struts-config element in the DOM-tree.</p>
+<p>There are two alternatives to create the EMF model from the DTDs. The
+first one is to convert the DTD into an XML Schema Definition (XSD)
+which is the input for the EMF import wizard. The wizard creates the EMF
+model based on the XSD. It also creates constraints used for validation
+based on the constraints defined in the XSD. The other alternative is
+the handcrafted way. Here you create the model with an editor by hand.
+The next step is to create the generator model (GenModel). This model
+contains the information for transforming the EMF model into Java. In
+this model it is important to set the resource type property of the root
+package to &quot;None&quot;. Otherwise the handwritten classes will be
+overwritten by regeneration. After setting the property a right mouse
+click on the root element in this model and choosing generate model code
+from the context menu generates the Java code from the model.</p>
+<h2>Mapping of EMF classes to DOM elements</h2>
+<p>This section describes the mapping framework introduced with the WTP
+project in the plug-in org.eclipse.wst.common.emf. The framework helps
+to translate EMF models into XML documents and vice-versa. To translate
+an EMF model into a XML document you need some mapping definitions and a
+renderer capable of reading from and writing to the XML document using
+the mapping definitions. The plug-in provides two renderers. The first
+one (EMF2SAXRenderer) uses SAX to load and a Transformer to store the
+EMF model. The second renderer (EMF2DOMRenderer) uses DOM for
+serialization of the EMF model. This renderer also creates an adapter
+that synchronizes the DOM tree and the model after any change is made
+either one. These classes can all be used as provided. All that you have
+to do is to implement the mappings for serialization. This is done by
+means of the Translator class and its subclasses.</p>
+<p>The Translator class stores information about a model object and its
+representation in the DOM tree of the XML document. The style integer in
+the Translator class contains the mapping information. It contains Bits
+that represent different mapping styles that affect how the model object
+is stored and how it is read from XML. Not all style bits are
+documented, therefore I will give a short description of each bit in the
+following table.</p>
+<table width="100%" border="0">
+ <tr>
+ <td valign="top">DOM_ATTRIBUTE</td>
+ <td>indicates that the EMF model object is rendered as attribute of a
+ XML element</td>
+ </tr>
+ <tr>
+ <td valign="top">EMPTY_TAG</td>
+ <td>indicates that the attribute or reference is rendered as empty tag</td>
+ </tr>
+ <tr>
+ <td valign="top">CDATA_CONTENT</td>
+ <td>indicates that the EMF model object is rendered as CDATA in XML</td>
+ </tr>
+ <tr>
+ <td valign="top">END_TAG_NO_INDENT</td>
+ <td>indicates that the end tag should not be indented</td>
+ </tr>
+ <tr>
+ <td valign="top">BOOLEAN_LOWERCASE</td>
+ <td>indicates that the boolean attribute of a model object is rendered
+ with a lowercase string and not with "True" or "False"</td>
+ </tr>
+ <tr>
+ <td valign="top">ENUM_FEATURE_WITH_HYPHENS</td>
+ <td>indicates that the model object is an enum that contains hyphens;
+ the hyphens are converted to underscores</td>
+ </tr>
+ <tr>
+ <td valign="top">EMPTY_CONTENT_IS_SIGNIFICANT</td>
+ <td>just as the name says, indicates that empty content is significant</td>
+ </tr>
+ <tr>
+ <td valign="top">COMMENT_FEATURE</td>
+ <td>indicates that the content of the EMF feature is in the first XML
+ comment node in front of the XML element of the EMF model object</td>
+ </tr>
+ <tr>
+ <td valign="top">UNSET_IF_NULL</td>
+ <td>unsets the model object if the value is null</td>
+ </tr>
+</table>
+<p>To map an EMF class to a XML element you have to define a translator.
+The renderer uses the translator for mapping the EMF object into an XML
+element. For simplicity the next code listing shows the definition of a
+translator for an attribute of an EMF class mapped to an attribute of an
+XML element.</p>
+<pre>new Translator(&quot;property&quot;,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STRUTS_CONFIG_PACKAGE.getSetPropertyType_Property(),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Translator.DOM_ATTRIBUTE)</pre>
+<p>This listing defines a single translator that maps the attribute
+property of an XML element to the EMF attribute property of the EMF
+class SetPropertyType. This mapping is the simplest one because it does
+not define any containment hierarchy. The mapping says nothing about
+what XML element contains the attribute property or which EMF class
+contains the instance of the EMF class SetPropertyType. The plug-in
+provides a very generic implementation for the mapping with the class
+GenericTranslator. This translator should be used for mapping EMF
+classes to XML elements. The next listing shows an example that uses an
+instance of GenericTranslator to map an XML element with attributes to
+an EMF class.</p>
+<pre>GenericTranslator translator = new GenericTranslator(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;set-property&quot;,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STRUTS_CONFIG_PACKAGE.getConfigurable_SetProperty());
+
+translator.setChildren(new Translator[] { IDTranslator.INSTANCE,
+&nbsp;&nbsp;&nbsp; new Translator(&quot;property&quot;,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STRUTS_CONFIG_PACKAGE.getSetPropertyType_Property(),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Translator.DOM_ATTRIBUTE),
+&nbsp;&nbsp;&nbsp; new Translator(&quot;value&quot;,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STRUTS_CONFIG_PACKAGE.getSetPropertyType_Value(),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Translator.DOM_ATTRIBUTE) });</pre>
+<p>The first three lines define the generic translator for the EMF class
+SetPropertyType. The first parameter (set-property) of the constructor
+defines the name of the XML element that is mapped to the EMF class. The
+second parameter defines the reference containing an object of the
+SetPropertyType class. The rest of the listing shows the creation of the
+mappings for the EMF attributes. These mappings are added as children to
+the translator for mapping the SetPropertyType class. This translator
+can then be used as a child translator elsewhere. In the example the
+translator is used for each Configurable subclass.</p>
+<p>An important aspect is the possibility of using paths for referencing
+XML elements. In the Visualizable class are two paths used for the EMF
+attribute smallIcon and largeIcon. They both are mapped to the XML
+element small-icon and large-icon which are children of the XML element
+icon. The next listing shows the mapping of the EMF attribute largeIcon
+to a XML element large-icon.</p>
+<pre>protected static Translator LARGE_ICON_TRANSLATOR = new Translator(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;icon/large-icon&quot;,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STRUTS_CONFIG_PACKAGE.getVisualizable_LargeIcon());</pre>
+<p>Another important aspect is extension of the RootTranslator class.
+This abstract class is used for mapping the root XML element to an EMF
+class. The constructor of the class RootTranslator takes two arguments.
+The first defines the root XML element and the second the EMF class. In
+the listing below the XML element struts-config is mapped to the EMF
+class StrutsConfigType, the root in the containment hierarchy in our
+model.</p>
+<pre>public StrutsConfigTranslator() {
+&nbsp;&nbsp;&nbsp; super(&quot;struts-config&quot;, STRUTS_CONFIG_PACKAGE.getStrutsConfigType());
+}</pre>
+<p>This class has a method getChildren() which returns the children of
+the root translator. The method has two arguments. The first contains
+the element to be mapped into XML and the second is a version identifier
+for the XML document. The method must be overriden to provide the child
+mappings of the root translator. The next listing shows the overridden
+method. It returns the child translators based on the version
+identifier.</p>
+<pre>public Translator[] getChildren(Object target, int versionID) {
+&nbsp;&nbsp;&nbsp; switch (versionID) {
+&nbsp;&nbsp;&nbsp; case StrutsConfigConstants.VERSION_1_0_ID:
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (children10 == null) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; children10 = create10Children();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return children10;
+&nbsp;&nbsp;&nbsp; case StrutsConfigConstants.VERSION_1_1_ID:
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (children11 == null) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; children11 = create11Children();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return children11;
+&nbsp;&nbsp;&nbsp; case StrutsConfigConstants.VERSION_1_2_ID:
+&nbsp;&nbsp;&nbsp; default:
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (children12 == null) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; children12 = create12Children();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return children12;
+&nbsp;&nbsp;&nbsp; }
+}</pre>
+<p>The listing shows a switch statement for creation of the child
+mappings. The create methods creates the mappings starting from the root
+mapping. The first parameter of the getChildren method could also be
+used to create mappings for specific elements. The next listing shows
+the create method for the version 1.2 which returns an array of
+translators for each child XML element of the root element.</p>
+<pre>protected Translator[] create12Children() {
+&nbsp;&nbsp;&nbsp; return new Translator[] { IDTranslator.INSTANCE,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Translator(StrutsConfigXmlMapping.DISPLAY_NAME,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STRUTS_CONFIG_PACKAGE.getStrutsConfigType_DisplayName()),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Translator(StrutsConfigXmlMapping.DESCRIPTION,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STRUTS_CONFIG_PACKAGE.getStrutsConfigType_Description()),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createDataSourcesTranslator(StrutsConfigConstants.VERSION_1_2_ID),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createFormBeansTranslator(StrutsConfigConstants.VERSION_1_2_ID),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createGlobalExceptionsTranslator(),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createGlobalForwardsTranslator(StrutsConfigConstants.VERSION_1_2_ID),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createActionMappingsTranslator(StrutsConfigConstants.VERSION_1_2_ID),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createControllerTranslator(),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createMessageResourcesTranslator(),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createPlugInTranslator() };
+}</pre>
+<p>For more mapping examples or the complete root translator look at the
+source code of the StrutsBox project.</p>
+<h2>Integrating Translators into EMF Resource</h2>
+<p>In this section I will show how the mappings should be integrated into
+EMF resource handling. For this purpose, an abstract EMF resource
+<pre>public StrutsConfigResourceImpl(Renderer renderer) {
+&nbsp;&nbsp;&nbsp; super(renderer);
+}
+
+public StrutsConfigResourceImpl(URI uri, Renderer renderer) {
+&nbsp;&nbsp;&nbsp; super(uri, renderer);
+}</pre>
+<p>These two constructors are used to create the resource. The original
+resource constructor is deprecated because the given renderer is used
+for the translation of the XML document to the EMF model.</p>
+<pre>protected String getDefaultSystemId() {
+&nbsp;&nbsp;&nbsp; return StrutsConfigConstants.STRUTS_CONFIG_SYSTEM_ID_1_2;
+}
+
+protected String getDefaultPublicId() {
+&nbsp;&nbsp;&nbsp; return StrutsConfigConstants.STRUTS_CONFIG_PUBLIC_ID_1_2;
+}
+
+protected int getDefaultVersionID() {
+&nbsp;&nbsp;&nbsp; return StrutsConfigConstants.VERSION_1_2_ID;
+}</pre>
+<p>These three methods return the default properties after the resource
+is loaded. The first two methods are for the XML document type
+definition and the last one is used for retrieving the version
+identifier used by the translator to create the mappings.</p>
+<pre>public Translator getRootTranslator() {
+&nbsp;&nbsp;&nbsp; return StrutsConfigTranslator.getInstance();
+}</pre>
+<p>This method connects the resource with the translator. To retrieve
+the correct mappings, this method is called from the renderer during
+serialization.</p>
+<pre>public String getDoctype() {
+&nbsp;&nbsp;&nbsp; return StrutsConfigXmlMapping.STRUTS_CONFIG;
+}</pre>
+<p>The method returns the name of the root XML element in the document.</p>
+<pre>public void setDoctypeValues(String publicId, String systemId) {
+&nbsp;&nbsp;&nbsp; super.setDoctypeValues(publicId, systemId);
+&nbsp;&nbsp;&nbsp; // here we decide based on the given public id which
+&nbsp;&nbsp;&nbsp; // struts-config version gets loaded
+&nbsp;&nbsp;&nbsp; int version = StrutsConfigConstants.VERSION_1_2_ID;
+&nbsp;&nbsp;&nbsp; if (StrutsConfigConstants.STRUTS_CONFIG_PUBLIC_ID_1_0.equals(publicId)) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; version = StrutsConfigConstants.VERSION_1_0_ID;
+&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp; if (StrutsConfigConstants.STRUTS_CONFIG_PUBLIC_ID_1_1.equals(publicId)) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; version = StrutsConfigConstants.VERSION_1_1_ID;
+&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp; setVersionID(version);
+}</pre>
+<p>This method is called after the XML document type definition is read
+from the XML document. It determines the version identifier used to
+retrieve the correct mappings from the root translator.</p>
+<p>There is also an adapter which sets the version attribute of the root
+object in the EMF model. The version attribute is taken from the version
+identifier determined from the document type definition. The code for
+this adapter is shown in the following listing.</p>
+<pre>private class RootVersionAdapter extends AdapterImpl {
+
+&nbsp;&nbsp;&nbsp; public boolean isAdapterForType(Object type) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return super.isAdapterForType(type);
+&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp; public void notifyChanged(Notification msg) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (msg.getFeatureID(null) == RESOURCE__CONTENTS
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; msg.getEventType() == Notification.ADD) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((StrutsConfigResourceImpl) msg.getNotifier()).syncVersionOfRootObject();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((Notifier) msg.getNotifier()).eAdapters().remove(this);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp; }
+
+}
+
+public String getVersionString() {
+&nbsp;&nbsp;&nbsp; switch (getVersionID()) {
+&nbsp;&nbsp;&nbsp; case StrutsConfigConstants.VERSION_1_0_ID:
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return StrutsConfigConstants.VERSION_1_0_TEXT;
+&nbsp;&nbsp;&nbsp; case StrutsConfigConstants.VERSION_1_1_ID:
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return StrutsConfigConstants.VERSION_1_1_TEXT;
+&nbsp;&nbsp;&nbsp; case StrutsConfigConstants.VERSION_1_2_ID:
+&nbsp;&nbsp;&nbsp; default:
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return StrutsConfigConstants.VERSION_1_2_TEXT;
+&nbsp;&nbsp;&nbsp; }
+}
+
+protected void syncVersionOfRootObject() {
+&nbsp;&nbsp;&nbsp; StrutsConfigType strutsConfig = (StrutsConfigType) getRootObject();
+&nbsp;&nbsp;&nbsp; if (strutsConfig != null) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String version = strutsConfig.getVersion();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String newVersion = getVersionString();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!newVersion.equals(version)) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strutsConfig.setVersion(newVersion);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp; }
+}
+
+protected void initializeContents() {
+&nbsp;&nbsp;&nbsp; super.initializeContents();
+&nbsp;&nbsp;&nbsp; eAdapters().add(new RootVersionAdapter());
+}</pre>
+<p>The adapter class synchronizes the version attribute of the root
+object after it is added to the resource. To synchronize the version
+attribute during initialization, the class is added to the adapters of
+the resource in the method initializeContents. After the root object is
+added to the resource the adapter is notified. Then it calls the method
+syncVersionOfRootObject, where the version string is determined by the
+version identifier. The version string is then set as version attribute
+of the root object.</p>
+<p>Normally a resource factory creates a resource in the EMF framework.
+So the next step is to create the resource factory. The factory class is
+very simple. It extends TranslatorResourceFactory and implements a
+single method for resource creation. The following listing shows the
+resource factory from the example.</p>
+<pre>public class StrutsConfigResourceFactoryImpl extends TranslatorResourceFactory {
+
+&nbsp;&nbsp;&nbsp; public StrutsConfigResourceFactoryImpl() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(EMF2DOMRendererFactoryDefaultHandler.INSTANCE
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .getDefaultRendererFactory());
+&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp; protected TranslatorResource createResource(URI uri, Renderer aRenderer) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new StrutsConfigResourceImpl(uri, aRenderer);
+&nbsp;&nbsp;&nbsp; }
+
+}</pre>
+<h2>Using the model in an editor</h2>
+<p>The model editor can be generated from the GenModel. After the editor
+has been generated, the constructor must be changed. The resource
+factory must be added to the resource set of the editing domain for a
+specific file extension.</p>
+<pre>public StrutsConfigEditor() {
+&nbsp;&nbsp;&nbsp; super();
+
+&nbsp;&nbsp;&nbsp; ...
+
+&nbsp;&nbsp;&nbsp; // Create the editing domain with a special command stack.
+&nbsp;&nbsp;&nbsp; //
+&nbsp;&nbsp;&nbsp; editingDomain = new AdapterFactoryEditingDomain(adapterFactory,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; commandStack, new HashMap());
+&nbsp;&nbsp;&nbsp; editingDomain.getResourceSet()
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .getResourceFactoryRegistry().getExtensionToFactoryMap()
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .put(&quot;xml&quot;, new StrutsConfigResourceFactoryImpl());
+}</pre>
+<p>After changing, the editing domain creates our resource factory for
+files with the extension xml. Now the editor must be registered for this
+file extension in the Eclipse extension registry. To achieve this goal,
+you have to set the extensions attribute of the editor extension to
+&quot;xml&quot;.</p>
+<p><a href="images/editor_extension.jpg"><img
+ src="images/thumb-editor_extension.jpg" width="640" height="542"
+ border="0" alt="" /></a></p>
+<h2>References</h2>
+<ul>
+ <li>StrutsBox &ndash; Professional Struts Development Toolkit for
+ Eclipse (<a href="http://www.strutsbox.de">www.strutsbox.de</a>)
+ <ul>
+ <li>Source code from plug-ins:
+ <ul>
+ <li>de.strutsbox.strutsconfig</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>EMF (<a href="http://www.eclipse.org/emf">www.eclipse.org/emf</a>)
+ <ul>
+ <li>The Eclipse Modeling Framework Overview</li>
+ </ul>
+ </li>
+ <li>WTP (<a href="http://www.eclipse.org/webtools">www.eclipse.org/webtools)</a>
+ <ul>
+ <li>The J2EE Deployment Descriptor Models</li>
+ <li>J2EE Module Operations (module creation, import wizards) API</li>
+ <li>Source code from plug-ins:
+ <ul>
+ <li>org.eclipse.wst.common.emf</li>
+ <li>org.eclipse.jst.j2ee.core</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+</ul>
+<p>The executable plug-ins with source code could be downloaded from <a
+ href="strutsbox.strutsconfig.zip">here</a>.</p>
+
+
+<p>To discuss or report problems in this article see <a
+ href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=100762">bug 100762</a>.</p>
+
+<p><small>IBM is trademark of International Business Machines
+Corporation in the United States, other countries, or both.</small></p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or
+registered trademarks of Sun Microsystems, Inc. in the United States,
+other countries, or both.</small></p>
+<p><small>Microsoft and Windows are trademarks of Microsoft Corporation
+in the United States, other countries, or both.</small></p>
+<p><small>Other company, product, and service names may be trademarks or
+service marks of others.</small></p>
+
+
+</body>
+</html>
diff --git a/Article-WTP-Persisting-EMF/strutsbox.strutsconfig.zip b/Article-WTP-Persisting-EMF/strutsbox.strutsconfig.zip
new file mode 100644
index 0000000..a26a2b8
--- /dev/null
+++ b/Article-WTP-Persisting-EMF/strutsbox.strutsconfig.zip
Binary files differ
diff --git a/Article-Workbench-DND/drag_drop.html b/Article-Workbench-DND/drag_drop.html
new file mode 100644
index 0000000..cd30d2d
--- /dev/null
+++ b/Article-Workbench-DND/drag_drop.html
@@ -0,0 +1,620 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+ <title>Drag and Drop in the Eclipse UI</title>
+ <meta name="Author" content="John Arthorne">
+ <link rel="stylesheet" href="../default_style.css"></head>
+
+<body link="#0000ff" vlink="#800080" bgcolor="#ffffff">
+
+<div align="right"><font size="-2">Copyright © 2003 International Business Machines Corp.</font>
+<table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tbody>
+ <tr>
+ <td align="left" valign="top" colspan="2" bgcolor="#0080c0"><b>
+ <font face="Arial,Helvetica" color="#ffffff"> Eclipse Corner Article</font></b></td>
+ </tr>
+ </tbody>
+</table>
+ </div>
+
+<div align="left">
+<h1><img src="images/Idea.jpg" height="86" width="120" align="middle">
+</h1>
+ </div>
+
+<p> </p>
+
+<h1 align="center">Drag and Drop in the Eclipse UI</h1>
+
+<blockquote> <b>Summary</b> <br>
+ In this article, we discuss the drag and drop facilities provided by JFace and
+ the Eclipse platform UI. After reading this, you will know how to add drag and
+ drop support to your own Eclipse views, and how that support will interact with
+ the standard views in the Eclipse platform. Along the way, we'll also discuss
+ that keyboard relative of drag and drop: cut and paste. You'll learn that putting
+ your own custom objects on the clipboard is easy once you've figured out the
+ basics of drag and drop. This article is intended to be read as a companion
+ to the <a href="../Article-SWT-DND/DND-in-SWT.html">SWT
+ drag and drop article</a>.<br>
+ <p><b> By John Arthorne, IBM OTI Labs</b><br>
+ <font size="-1">August 25, 2003</font></p>
+ </blockquote>
+
+<hr width="100%"> <a name="1"> </a>
+<h2>
+Doing the drag and drop</h2>
+
+<div align="right"><a name="1"><i>Never keep up with the Joneses. Drag them down to your level.</i> <br>
+– Quentin Crisp</a></div>
+
+<p>In keeping with the general philosophy of JFace, the JFace drag and drop
+adds a layer of functionality on top of the SWT drag and drop support. This layer
+allows the developer to deal directly with domain objects (such as resources,
+tasks, etc), without having to worry too much about the underlying window
+controls. Rather than concealing or replacing the drag and drop support in SWT,
+the JFace drag and drop support works as an extension to the same concepts
+found in SWT drag and drop.
+</p>
+<h3>Transfer types</h3>
+As you'll know from the <a href="../Article-SWT-DND/DND-in-SWT.html">SWT drag and drop article</a>,
+the notion of transfer types is central to the drag and drop support in Eclipse-based UIs.
+To recap, transfer types allow drag sources to specify what kinds of object they allow to be
+dragged out of their widget, and they allow drop targets to specify what kinds of
+objects they are willing to receive. For each transfer type, there is a subclass of
+<code>org.eclipse.swt.dnd.Transfer</code>. These subclasses implement the marshaling
+behavior that converts between objects and bytes, allowing drag and drop
+transfers between applications. The following table summarizes the transfer types
+provided by the basic Eclipse platform, along with the object they are capable of transferring:
+</p>
+<p>
+<table BORDER COLS=2 WIDTH="90%" >
+<tr>
+<td><b>Transfer class</b></td>
+<td><b>Object it transfers</b></td>
+</tr>
+<tr>
+<td><code>org.eclipse.swt.dnd.FileTransfer</code></td>
+<td><code>java.lang.String[]</code> (list of absolute file paths)</td>
+</tr>
+<tr>
+<td><code>org.eclipse.swt.dnd.RTFTransfer</code></td>
+<td><code>java.lang.String</code> (may contain RTF formatting characters)</td>
+</tr>
+<tr>
+<td><code>org.eclipse.swt.dnd.TextTransfer</code></td>
+<td><code>java.lang.String</code></td>
+</tr>
+<tr>
+<td><code>org.eclipse.ui.part.MarkerTransfer</code></td>
+<td><code>org.eclipse.core.resources.IMarker[]</code></td>
+</tr>
+<tr>
+<td><code>org.eclipse.ui.part.ResourceTransfer</code></td>
+<td><code>org.eclipse.core.resources.IResource[]</code></td>
+</tr>
+<tr>
+<td><code>org.eclipse.ui.part.EditorInputTransfer</code></td>
+<td><code>org.eclipse.ui.part.EditorInputTransfer.EditorInputData[]</code></td>
+</tr>
+<tr>
+<td><code>org.eclipse.ui.part.PluginTransfer</code></td>
+<td><code>org.eclipse.ui.part.PluginTransferData</code></td>
+</tr>
+</table>
+</p>
+<p>
+The set of transfer types is open ended, because third party
+tool writers can implement their own transfer types for their domain objects.
+To implement your own transfer type, it is recommended that you subclass
+<code>org.eclipse.swt.dnd.ByteArrayTransfer</code>.
+See the <a href="../Article-SWT-DND/DND-in-SWT.html">SWT drag and drop article</a> for more information
+on defining your own transfer types.
+</p>
+<p>
+<p><img src="images/tip.gif">
+An important point about transfer types is that they don't necessarily need to store
+the entire object as serialized bytes. In most cases it is simpler and more
+efficient to just store enough information about where the object is found. For
+example, <code>FileTransfer</code> simply encodes a string which represents the
+absolute path of the file in the file system. It does not store the entire file in the
+transfer object.
+</p>
+<h3>Transfer types supported by the standard views</h3>
+<p>
+Many of the basic views you see in Eclipse already support various
+transfer types. It is important to understand what transfer types are supported by
+each view, because this dictates how the drag and drop support in your view will
+interact with other basic views found in the Eclipse platform UI.
+</p>
+<p>
+The Navigator view supports dragging and dropping files (<code>FileTransfer</code>),
+and resources (<code>ResourceTransfer</code>). For example, you can drag a file
+from the Navigator view into Windows Explorer or the Windows Desktop. Similarly,
+you can import resources into Eclipse simply by dragging them from Windows into
+the Navigator view of your workbench. You can also drag files between two instances
+of Eclipse, or drag within a single Navigator to copy and move files within
+your workspace. If your view supports either <code>FileTransfer</code> or
+<code>ResourceTransfer</code>, then users will be able to transfer resources between
+your view and the Navigator view.
+</p>
+<p>
+The Tasks and Bookmarks views support dragging of markers (<code>MarkerTransfer</code>).
+Dragging a selection of tasks from the Tasks view into an application such as MS
+Word will generate a textual marker report (<code>TextTransfer</code>). You can also drag markers
+out of the Tasks and Bookmarks views into other parts of the workbench, such as
+the editor area. Dragging a marker to the editor area will open the associated
+resource in the editor and jump to that marker location in the editor.
+</p>
+<p>
+Finally, the editor area supports dropping of editor inputs (<code>EditorInputTransfer</code>),
+resources, or markers. Dragging these objects to the editor will cause it to locate and
+open an appropriate editor for the given resource, editor input or marker. In the case
+of markers, it will also jump to that marker location in the editor.
+</p>
+<h3>A running example: go go gadgets!</h3>
+<div align="right"><a name="1"><i>"Gosh, Scotland is beautiful, Uncle Gadget."<br>
+"It certainly is, Penny. This is where they make Scotch tape, ya know."</i> <br>
+– Inspector Gadget</a></div>
+
+<p>
+For the remainder of this article, we'll make use of a running example. This example
+is an Eclipse plug-in for manipulating a simple object model of <i>gadgets</i>. Gadgets
+are simply named objects that can be formed into trees. Each gadget knows its parent
+and its children. The example includes two views, one containing a table viewer, and
+the other containing a tree viewer. Drag and drop can be used to copy or move
+gadgets between these views, and to rearrange the order or hierarchy of gadgets
+within a view. There is a <code>GadgetTransfer</code> class for encoding an array
+of gadgets to and from a byte array. Complete source code for the example is found
+<a href="gadgetsrc.zip">here</a>.
+</p>
+<h3>Adding JFace viewer drag support</h3>
+Adding drag support to a viewer means that it enables the user to select
+any item in the viewer with the mouse, and drag it into another viewer
+or another application. Drag support can be added to any subclass of
+<code>org.eclipse.jface.viewers.StructuredViewer</code>
+using the <code>addDragSupport(int, Transfer[], DragSourceListener)</code>
+method. From our gadget example, here is the code for associating a drag listener
+with a tree viewer:
+</p>
+<font color="#4444cc">
+<pre>
+ TreeViewer gadgetViewer = new TreeViewer(...);
+ int ops = DND.DROP_COPY | DND.DROP_MOVE;
+ Transfer[] transfers = new Transfer[] { GadgetTransfer.getInstance()};
+ viewer.addDragSupport(ops, transfers, new GadgetDragListener(viewer));
+</pre>
+</font>
+<br>
+<p>
+<code>GadgetDragListener</code> is an implementation of the SWT interface
+<code>org.eclipse.swt.dnd.DragSourceListener</code>. There is nothing specific
+to JFace about the implementation of <code>DragSourceListener</code>, so you
+can learn more about its implementation in the <a href="../Article-SWT-DND/DND-in-SWT.html">SWT drag and drop article</a>.
+</p>
+
+<h3>Adding viewer drop support</h3>
+<p>
+Drop support can be added to viewers using the <code>StructuredViewer.addDropSupport(int,
+Transfer[], DropTargetListener)</code> method. This allows your viewer to
+be the target of a drop operation. The code for adding drop support is almost the
+same as for adding drag support:
+</p>
+<p>
+<font color="#4444cc">
+<pre>
+ TreeViewer gadgetViewer = new TreeViewer(...);
+ int ops = DND.DROP_COPY | DND.DROP_MOVE;
+ Transfer[] transfers = new Transfer[] { GadgetTransfer.getInstance()};
+ viewer.addDropSupport(ops, transfers, new GadgetTreeDropAdapter(viewer));
+</pre>
+</font>
+</p>
+<p>
+JFace provides a standard implementation of <code>DropTargetListener</code>
+called <code>org.eclipse.jface.viewers.ViewerDropAdapter</code>.
+This adapter makes it easy to add drop support for simple cases. If you have more
+complex requirements, you can always override the SWT <code>DropTargetListener</code>
+interface directly for ultimate flexibility.
+When sub-classing <code>ViewerDropAdapter</code>, simply implement its two
+abstract methods: <code>validateDrop(Object target, int operation, TransferData transferType)</code>,
+and <code>performDrop(Object data)</code>.
+</p>
+<p>
+<code>validateDrop</code> is called whenever the user moves over a new item
+in your viewer, or changes the drop type with one of the modifier keys.
+The method provides the current drop target, operation, and transfer type.
+The return value of this method indicates whether a drop at the current location is
+valid or not. A return value of false will change the drag icon to indicate
+to the user that it is illegal to drop what they are dragging at the current
+location. In our gadget example, it is always legal to drop a gadget, so the
+<code>validateDrop</code> implementation simply looks like this:
+<font color="#4444cc">
+<pre>
+ public boolean validateDrop(Object target, int op, TransferData type) {
+ return GadgetTransfer.getInstance().isSupportedType(type);
+ }
+</pre>
+</font>
+<p>
+This code just makes sure that the user is indeed dropping a gadget, and not
+some other object such as a resource or marker. If you have more complex
+validation requirements based on the target object, you can do that here. For example,
+in a file navigator, you may want to allow dropping on top of directories, but not on top of
+files.
+</p>
+<p>
+<code>performDrop</code> is called when the user lets go of the mouse button,
+indicating that they want the drop to occur. Your implementation should
+accordingly perform the expected behavior for that drop. Context for the
+drop is provided by the methods <code>getCurrentTarget</code>, <code>getCurrentOperation</code>,
+and <code>getCurrentLocation</code> on <code>ViewerDropAdapter</code>. Most
+importantly, at the time when <code>performDrop </code>is called, <code>getCurrentTarget</code>
+will provide the object in your viewer that is currently under the mouse. Here is the
+<code>performDrop</code> method from our gadget example:
+</p>
+<p>
+<font color="#4444cc">
+<pre>
+ public boolean performDrop(Object data) {
+1 Gadget target = (Gadget)getCurrentTarget();
+2 if (target == null)
+3 target = (Gadget)getViewer().getInput();
+4 Gadget[] toDrop = (Gadget[])data;
+5 TreeViewer viewer = (TreeViewer)getViewer();
+6 //cannot drop a gadget onto itself or a child
+7 for (int i = 0; i < toDrop.length; i++)
+8 if (toDrop[i].equals(target) || target.hasParent(toDrop[i]))
+9 return false;
+10 for (int i = 0; i < toDrop.length; i++) {
+11 toDrop[i].setParent(target);
+12 viewer.add(target, toDrop[i]);
+13 viewer.reveal(toDrop[i]);
+14 }
+15 return true;
+ }
+</pre>
+</font>
+</p>
+<p>
+In lines 1-3, it is determining what the target gadget is. The target is the item that
+is currently under the mouse when the drop occurs. If there is no item under the mouse, it
+takes the viewer's input element as the target. On lines 7-9, it is making sure
+that the user is not dropping an item onto itself, or onto a child of itself. You may
+be wondering why this validation was not done in the <code>validateDrop</code>
+method. In SWT, the transfer of data from the source to the target is done lazily
+when the drop is initiated. So, as the user is dragging, the destination has no
+way of finding out what source object is being dragged until the drop is performed.
+Returning <code>false</code> from the <code>performDrop</code> method will
+cancel the drop. On lines 10-13, it is performing the actual drop. This involves updating
+the gadget with its new parent (line 11), and then adding and revealing the new item
+in the viewer (lines 12-13). Finally, the method returns true on line 15 to indicate
+that the drop was successful.
+</p>
+<p>
+<code>ViewerDropAdapter</code> has two more interesting methods for controlling
+drag feedback effects. The method <code>setFeedbackEnabled</code> is used to turn
+insertion feedback on or off. If insertion feedback is on, the cursor will change when
+the mouse is hovering between two items to indicate where the insertion will occur.
+Using this effect, you can allow the user to sort items in a tree using drag and drop.
+In your drop adapter, use the method <code>getCurrentLocation</code> to determine
+if the cursor is currently directly on, before, or after the current target object. Here
+is how the gadget drop example can be updated to make use of this location
+information:
+<p>
+<font color="#4444cc">
+<pre>
+ public boolean performDrop(Object data) {
+ //set the target gadget according to current cursor location
+ Gadget target = (Gadget)getCurrentTarget();
+ if (target != null) {
+ int loc = getCurrentLocation();
+ if (loc == LOCATION_BEFORE || loc == LOCATION_AFTER)
+ target = target.getParent();
+ }
+ if (target == null)
+ target = (Gadget)getViewer().getInput();
+ Gadget[] toDrop = (Gadget[])data;
+ TreeViewer viewer = (TreeViewer)getViewer();
+ // ... remainder of method is the same as previous example ...
+</pre>
+</font>
+</p>
+<p>
+In this snippet, it looks at the cursor location to see if it is before or after an
+item in the tree. When a gadget is dropped between other gadgets, it sets the
+parent to be the parent of the neighboring gadget. Said another way, the
+dropped gadget will become a sibling of the gadget it is dropped next to.
+</p>
+<p>
+The method <code>ViewerDropAdapter.setScrollExpandEnabled</code> is used to
+turn scroll and expansion effects on or off. When this is turned on, hovering
+near the bottom of a tree or table will cause the widget to automatically scroll in
+that direction. Hovering over a collapsed tree item for a sufficient amount of time
+will cause the item to be expanded. In most cases you should leave these effects
+on, otherwise users will not able to use drag and drop effectively when your tree
+or table contains many items.
+</p>
+
+<h3>Plugin drop handling</h3>
+<div align="right"><a name="1"><i>When I can't handle events, I let them handle themselves.</i> <br>
+– Henry Ford</a></div>
+<p>
+Due to the UI layering imposed by the plug-in mechanism, viewers are often
+not aware of the content and nature of other viewers. This can make drag
+and drop operations between plug-ins difficult. For example, our gadget
+plug-in may want to allow the user to drop gadget objects into the Navigator
+view. Since the Navigator view doesn't know anything about gadget objects
+(the Navigator only displays <code>org.eclipse.core.resources.IResource</code>
+objects), it would not be able to support this. Similarly, another plug-in may want
+to drop some other kind of objects into the views from the gadget example.
+To address this problem, a plug-in drop support mechanism
+is provided by the workbench. This mechanism essentially delegates the
+drop behavior back to the originator of the drag operation. In the gadget example,
+we use this extension point to drop gadgets into the Navigator view, and create
+files containing descriptions of the gadgets that were dropped. Here are the
+steps required to add drag and drop behavior using this mechanism:
+<p>
+Step 1) In your plugin.xml, define an extension on the "org.eclipse.ui.dropActions"
+extension point. Here is an example XML declaration:
+<p>
+<font color="#4444cc">
+<pre>
+ &lt;extension
+ id=&quot;gadgetDrop&quot;
+ name=&quot;Gadget Resource Drop&quot;
+ point=&quot;org.eclipse.ui.dropActions&quot;&gt;
+ &lt;action
+ class=&quot;org.eclipse.ui.examples.gdt.dnd.GadgetPluginDropAdapter&quot;
+ id=&quot;org.eclipse.ui.examples.gdt.gadgetDrop&quot;&gt;
+ &lt;/action&gt;
+ &lt;/extension&gt;
+</pre>
+</font>
+</p>
+<p>
+Step 2) Implement the code that will perform the drop. This work is done by
+the class defined in the extension markup above, which must implement
+<code>org.eclipse.ui.part.IDropActionDelegate</code>.
+This interface defines a single run() method that gets called when the
+drop occurs. The run method is supplied with the object being dragged, as well as the
+object under the cursor when the drop occurs. Here is an example implementation of
+the drop delegate from the gadget example:
+</p>
+<p>
+<font color="#4444cc">
+<pre>
+ public boolean run(Object source, Object target) {
+1 if (target instanceof IContainer) {
+2 GadgetTransfer transfer = GadgetTransfer.getInstance();
+3 Gadget[] gadgets = transfer.fromByteArray((byte[])source);
+4 IContainer parent = (IContainer)target;
+5 for (int i = 0; i < gadgets.length; i++) {
+6 writeGadgetFile(parent, gadgets[i]);
+7 }
+8 return true;
+9 }
+10 //drop was not successful so return false
+11 return false;
+ }
+</pre>
+</font>
+</p>
+<p>
+On line 1, it ensures that the gadget is being dropped on some kind of container.
+In practice, your drop delegate may support being dropped on several different
+types of objects, with different behavior for each type. On lines 2-3, it makes use
+of a convenience method to extract the transferred gadgets from the byte array in the
+transfer data. Since the plug-in transfer data contains a byte array, this is the exact
+same code that typically exists in your custom <code>Transfer</code> subclass.
+It then iterates over the transferred gadgets, and creates a file in the target container
+for that gadget. Finally, it returns true if the drop was successful (line 8), or false if the drop
+occurred on a target object that was not supported (line 11).
+</p>
+
+<p>
+Step 3) In the viewer that will be the source of the drag and drop,
+add drag support using the <code>StructuredViewer.addDragSupport()</code> method
+described earlier. In the array of supported transfer types, include the
+singleton instance of <code>org.eclipse.ui.part.PluginTransfer</code>. In your
+implementation of <code>DragSourceListener</code>, the <code>dragSetData</code>
+method must set the data to be an instance of <code>org.eclipse.ui.part.PluginTransferData</code>.
+This object consists of the id of your drop action,
+along with the data being transferred. Here is the code in the drag listener from the
+gadget example:
+</p>
+<p>
+<font color="#4444cc">
+<pre>
+ public void dragSetData(DragSourceEvent event) {
+1 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+2 Gadget[] gadgets = (Gadget[])selection.toList().toArray(new Gadget[selection.size()]);
+3 if (GadgetTransfer.getInstance().isSupportedType(event.dataType)) {
+4 event.data = gadgets;
+5 } else if (PluginTransfer.getInstance().isSupportedType(event.dataType)) {
+6 byte[] data = GadgetTransfer.getInstance().toByteArray(gadgets);
+7 event.data = new PluginTransferData("org.eclipse.ui.examples.gdt.gadgetDrop", data);
+8 }
+9 }
+ }
+</pre>
+</font>
+</p>
+<p>
+Lines 1-2 are the familiar code for creating an array of gadgets from the viewer's
+selection. Line 4 handles the old case of a gadget transfer by simply setting the
+event data to be the correct type for <code>GadgetTransfer</code>. Lines 6-7
+are the interesting new code for handling a plug-in drag event. First, it uses a convenience
+method on the <code>GadgetTransfer</code> class for converting the array of gadgets
+into a byte array. Next, it creates a <code>PluginTransferData</code> object, passing
+in the id of the plug-in drop action that was declared in the plugin.xml in step 1), along
+with the serialized gadget array.
+</p>
+
+<p>Step 4) In the viewer that will receive the drop, the drop listener
+for that viewer must subclass <code>org.eclipse.ui.part.PluginDropAdapter</code>,
+which in turn subclasses <code>ViewerDropAdapter</code> as described earlier.
+Be sure to invoke the super methods for validateDrop and performDrop in
+cases where your adapter does not understand the transfer type. Following
+from our earlier example, the viewer’s declaration would look
+like this:
+</p>
+<p>
+<font color="#4444cc">
+<pre>
+ TreeViewer gadgetViewer = new TreeViewer(...);
+ int ops = DND.DROP_COPY | DND.DROP_MOVE;
+ Transfer[] transfers = new Transfer[] {
+ GadgetTransfer.getInstance(), PluginTransfer.getInstance()};
+ viewer.addDropSupport(ops, transfers, new GadgetTreeDropAdapter(viewer));
+</pre>
+</font>
+</p>
+<p>
+The basic Workbench views such as the Navigator view
+already have this support added. It is recommended that anyone defining
+their own views should add the plug-in support, in anticipation of future
+third party plug-ins wanting to drop content into their views. For more information
+about this advanced drag and drop mechanism, refer to the documentation
+for the <code>org.eclipse.ui.dropActions</code> extension point.
+</p>
+<h2>Cut, copy and paste</h2>
+<div align="right"><a name="1"><i>"I'll get you next time Gadget... Next time!" </i> <br>
+– Dr. Claw </a></div>
+<p>
+Cut and paste can be thought of as the keyboard equivalent of drag and drop. Once you've
+mastered drag and drop support, you'll find that cut and paste is a snap. Once
+again, the gadgets example provides a complete implementation of cut and paste
+support. Here is code for adding cut and paste support from within an Eclipse view
+(this code goes in the view's <code>createPartControl</code> method):
+</p>
+<p>
+<font color="#4444cc">
+<pre>
+ public void createPartControl(Composite parent) {
+ viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+
+ //... initialize viewer's content and label providers ...
+
+ clipboard = new Clipboard(getSite().getShell().getDisplay());
+ IActionBars bars = getViewSite().getActionBars();
+ bars.setGlobalActionHandler(
+ IWorkbenchActionConstants.CUT,
+ new CutGadgetAction(viewer, clipboard));
+ bars.setGlobalActionHandler(
+ IWorkbenchActionConstants.COPY,
+ new CopyGadgetAction(viewer, clipboard));
+ bars.setGlobalActionHandler(
+ IWorkbenchActionConstants.PASTE,
+ new PasteTreeGadgetAction(viewer, clipboard));
+ }
+</pre>
+</font>
+</p>
+<p>
+This code simply creates a new SWT clipboard, and then defines global actions
+for cut, copy, and paste using that clipboard. The <code>IActionBars</code>
+interface is used for hooking into global actions. <b>Note:</b> SWT clipboard
+objects are operating system resources that must be disposed when no longer
+needed. In the gadget example, we <code>dispose()</code> the clipboard
+when the view is disposed. Disposing of an SWT clipboard instance does not remove
+the data from the operating system's clipboard.
+</p>
+<p>
+The actions that are provided as global action handlers should be subclasses of the
+<code>org.eclipse.jface.action.Action</code> class. The code for these actions is
+similar to the drag and drop code, except that they use the clipboard as the transfer
+mechanism, rather than the drag and drop event handlers. Here is the code for the
+run method of the cut action:
+</p>
+<p>
+<font color="#4444cc">
+<pre>
+ public void run() {
+1 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+2 Gadget[] gadgets = (Gadget[])selection.toList().toArray(new Gadget[selection.size()]);
+3 clipboard.setContents(
+4 new Object[] { gadgets },
+5 new Transfer[] { GadgetTransfer.getInstance()});
+6 for (int i = 0; i < gadgets.length; i++) {
+7 gadgets[i].setParent(null);
+8 }
+9 viewer.refresh();
+ }
+</pre>
+</font>
+</p>
+<p>
+On lines 3-5, the gadgets are placed on the clipboard, along with the <code>
+Transfer</code> object that will be used for serializing them. Lines 6-8 remove
+the gadgets from the source view (since they are being cut, not copied), and line 9
+refreshes the view to update it with the new contents. The copy action is almost
+identical, except lines 6-9 are removed, since we don't want to remove the gadgets
+from the source view on copy. The paste action for pasting into a tree looks like this:
+</p>
+<p>
+<font color="#4444cc">
+<pre>
+ public void run() {
+1 IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();
+2 Gadget parent = (Gadget)sel.getFirstElement();
+3 if (parent == null)
+4 parent = (Gadget)viewer.getInput();
+5 Gadget[] gadgets = (Gadget[])clipboard.getContents(GadgetTransfer.getInstance());
+6 if (gadgets == null)
+7 return;
+8 //cannot drop a gadget onto itself or a child
+9 for (int i = 0; i < gadgets.length; i++)
+10 if (gadgets[i].equals(parent) || parent.hasParent(gadgets[i]))
+11 return;
+12 for (int i = 0; i < gadgets.length; i++) {
+13 gadgets[i].setParent(parent);
+14 }
+15 viewer.refresh();
+ }
+</pre>
+</font>
+</p>
+<p>
+Lines 1-4 compute the parent gadget for the gadgets that are about to be pasted.
+If there is a gadget currently selected, it will become the new parent, otherwise the root
+gadget is used. Line 5 is the crucial step that takes the gadget objects off the clipboard.
+You should always check that the returned value is not null, since there may not be
+an object of the requested type on the clipboard. Lines 9-15 are the familiar code
+that we had in the drop event handler, first ensuring that we're not dropping a gadget
+onto itself or a child of itself, and then setting the parent elements for the dropped
+gadgets.
+
+<p><img src="images/tip.gif">
+In your implementation, you will probably want to factor out the paste and drop
+code into a common place, since they both do the same thing. Likewise, the code for
+the cut action is similar to the code in <code>dragFinished</code> in the drag action
+handler. For clarity, the gadget example duplicates the code in both places, but you'll
+make your code easier to maintain if you keep it all in one place.
+</p>
+
+<h3>Summary and further information</h3>
+<p>
+You now have all the information you need for adding drag/drop and cut/paste support
+in your own JFace viewers. You should also know all about the standard transfer types
+supplied by the platform, and what transfers are supported by the standard views
+in the platform.
+</p>
+<p>
+For more information, browse through the complete source from the
+<a href="gadgetsrc.zip">gadgets example</a>. The UI readme
+example, available from the eclipse.org
+<a href="http://www.eclipse.org/downloads/index.php">downloads page</a>,
+also implements some drag and drop support. For more in depth examples, you
+can look at the drag and drop support implemented within the UI plug-in itself. For
+example, see <code>org.eclipse.ui.views.navigator.ResourceNavigator </code>to
+see how the Navigator view implements its drag and drop behavior. The Navigator
+uses two helper classes, <code>NavigatorDragAdapter</code> and
+<code>NavigatorDropAdapter</code>, which are also instructive to look at.
+</p>
+<h3>Acknowledgements</h3>
+<p> Thanks to Knut Radloff from the Eclipse Platform UI Team and Jim des Rivi&egrave;res
+ at OTI Labs for proof reading and providing feedback for this article. </p>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the United States, other countries, or both.</small></p>
+</body>
+</html> \ No newline at end of file
diff --git a/Article-Workbench-DND/gadgetsrc.zip b/Article-Workbench-DND/gadgetsrc.zip
new file mode 100644
index 0000000..63f87c6
--- /dev/null
+++ b/Article-Workbench-DND/gadgetsrc.zip
Binary files differ
diff --git a/Article-Workbench-DND/images/Idea.jpg b/Article-Workbench-DND/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Workbench-DND/images/Idea.jpg
Binary files differ
diff --git a/Article-Workbench-DND/images/tip.gif b/Article-Workbench-DND/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-Workbench-DND/images/tip.gif
Binary files differ
diff --git a/Article-Workbench-DND/images/tryit.gif b/Article-Workbench-DND/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-Workbench-DND/images/tryit.gif
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget.htm b/Article-Writing Your Own Widget/Writing Your Own Widget.htm
new file mode 100644
index 0000000..f09e8e8
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget.htm
@@ -0,0 +1,6632 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml"
+xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List href="./Writing%20Your%20Own%20Widget_files/filelist.xml">
+<link rel=OLE-Object-Data
+href="./Writing%20Your%20Own%20Widget_files/oledata.mso">
+<!--[if !mso]>
+<style>
+v\:* {behavior:url(#default#VML);}
+o\:* {behavior:url(#default#VML);}
+w\:* {behavior:url(#default#VML);}
+.shape {behavior:url(#default#VML);}
+</style>
+<![endif]-->
+<title>Writing Your Own Widget</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Author>OTI EMPLOYEE</o:Author>
+ <o:LastAuthor>Dave Thomson</o:LastAuthor>
+ <o:Revision>12</o:Revision>
+ <o:TotalTime>2064</o:TotalTime>
+ <o:LastPrinted>2001-02-09T19:31:00Z</o:LastPrinted>
+ <o:Created>2001-06-04T02:12:00Z</o:Created>
+ <o:LastSaved>2001-06-04T18:05:00Z</o:LastSaved>
+ <o:Pages>30</o:Pages>
+ <o:Words>8616</o:Words>
+ <o:Characters>49116</o:Characters>
+ <o:Company>OBJECT TECHNOLOGY INTL</o:Company>
+ <o:Lines>409</o:Lines>
+ <o:Paragraphs>98</o:Paragraphs>
+ <o:CharactersWithSpaces>60317</o:CharactersWithSpaces>
+ <o:Version>9.2720</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:HideSpellingErrors/>
+ <w:DoNotHyphenateCaps/>
+ <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
+ <w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>
+ <w:UseMarginsForDrawingGridOrigin/>
+ <w:Compatibility>
+ <w:UsePrinterMetrics/>
+ <w:WW6BorderRules/>
+ <w:FootnoteLayoutLikeWW8/>
+ <w:ShapeLayoutLikeWW8/>
+ <w:AlignTablesRowByRow/>
+ <w:ForgetLastTabAlignment/>
+ <w:LayoutRawTableWidth/>
+ <w:LayoutTableRowsApart/>
+ </w:Compatibility>
+ <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
+ </w:WordDocument>
+</xml><![endif]-->
+<link rel=Stylesheet type="text/css" media=all
+href="Writing%20Your%20Own%20Widget_files/default_style.css">
+<style>
+<!--
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+h1
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:21.0pt;
+ font-family:Arial;
+ color:windowtext;
+ mso-font-kerning:14.0pt;
+ font-weight:bold;}
+h2
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-line-height-alt:10.5pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:2;
+ font-size:18.0pt;
+ font-family:Arial;
+ color:windowtext;
+ font-weight:bold;}
+h3
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:3;
+ font-size:14.0pt;
+ font-family:Arial;
+ color:windowtext;
+ font-weight:bold;}
+h4
+ {mso-style-next:Normal;
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:4;
+ tab-stops:24.0pt 48.0pt 1.0in 96.0pt 120.0pt 2.0in 168.0pt 192.0pt 3.0in 240.0pt 264.0pt 4.0in 312.0pt 336.0pt 5.0in 384.0pt 408.0pt 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt;
+ layout-grid-mode:char;
+ font-size:18.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:normal;}
+p.MsoToc1, li.MsoToc1, div.MsoToc1
+ {mso-style-next:Normal;
+ margin-top:.25in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ text-transform:uppercase;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc2, li.MsoToc2, div.MsoToc2
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc3, li.MsoToc3, div.MsoToc3
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:10.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc4, li.MsoToc4, div.MsoToc4
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:20.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc5, li.MsoToc5, div.MsoToc5
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:30.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc6, li.MsoToc6, div.MsoToc6
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:40.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc7, li.MsoToc7, div.MsoToc7
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:50.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc8, li.MsoToc8, div.MsoToc8
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:60.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc9, li.MsoToc9, div.MsoToc9
+ {mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:70.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoHeader, li.MsoHeader, div.MsoHeader
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoFooter, li.MsoFooter, div.MsoFooter
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoBodyText, li.MsoBodyText, div.MsoBodyText
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:red;}
+p.MsoBodyText2, li.MsoBodyText2, div.MsoBodyText2
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in;
+ layout-grid-mode:char;
+ font-size:9.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:black;}
+a:link, span.MsoHyperlink
+ {color:blue;
+ text-decoration:underline;
+ text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+ {color:purple;
+ text-decoration:underline;
+ text-underline:single;}
+strong
+ {mso-bidi-font-weight:normal;}
+em
+ {mso-bidi-font-style:normal;}
+p
+ {margin-top:5.0pt;
+ margin-right:0in;
+ margin-bottom:5.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:Arial;
+ mso-fareast-font-family:"Times New Roman";
+ color:black;}
+code
+ {mso-ansi-font-size:8.5pt;
+ mso-bidi-font-size:8.5pt;
+ mso-ascii-font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-hansi-font-family:"Courier New";
+ mso-bidi-font-family:"Courier New";}
+pre
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;
+ font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Courier New";
+ color:windowtext;}
+p.Code, li.Code, div.Code
+ {mso-style-name:Code;
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in 2.25in 2.5in 2.75in 3.0in 3.25in 3.5in 3.75in 4.0in 4.25in 4.5in 4.75in 5.0in 5.25in 5.5in 5.75in;
+ layout-grid-mode:char;
+ font-size:9.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:windowtext;}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-title-page:yes;
+ mso-even-footer:url("./Writing%20Your%20Own%20Widget_files/header.htm") ef1;
+ mso-footer:url("./Writing%20Your%20Own%20Widget_files/header.htm") f1;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+ /* List Definitions */
+@list l0
+ {mso-list-id:-2;
+ mso-list-type:simple;
+ mso-list-template-ids:-1;}
+@list l0:level1
+ {mso-level-start-at:0;
+ mso-level-text:*;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:0in;
+ text-indent:0in;}
+@list l1
+ {mso-list-id:174617761;
+ mso-list-type:simple;
+ mso-list-template-ids:67698689;}
+@list l1:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.25in;
+ mso-level-number-position:left;
+ margin-left:.25in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l2
+ {mso-list-id:1592273852;
+ mso-list-type:simple;
+ mso-list-template-ids:67698689;}
+@list l2:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.25in;
+ mso-level-number-position:left;
+ margin-left:.25in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l0:level1 lfo2
+ {mso-level-number-format:bullet;
+ mso-level-numbering:continue;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ mso-level-legacy:yes;
+ mso-level-legacy-indent:.25in;
+ mso-level-legacy-space:0in;
+ margin-left:.25in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+ol
+ {margin-bottom:0in;}
+ul
+ {margin-bottom:0in;}
+-->
+</style>
+<!--[if gte mso 9]><xml>
+ <o:shapedefaults v:ext="edit" spidmax="1050"/>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <o:shapelayout v:ext="edit">
+ <o:idmap v:ext="edit" data="1"/>
+ </o:shapelayout></xml><![endif]-->
+</head>
+
+<body lang=EN-US link=blue vlink=purple style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p class=MsoNormal align=right style='margin-top:14.2pt;margin-right:0in;
+margin-bottom:0in;margin-left:25.5pt;margin-bottom:.0001pt;text-align:right'><a
+name="_Toc496069418"></a><a name="_Toc506634621"><span style='mso-bookmark:
+_Toc496069418'><span style='font-size:8.0pt;mso-bidi-font-size:10.0pt'>Copyright
+© 2001 Object Technology International, Inc.<o:p></o:p></span></span></a></p>
+
+<table border=0 cellspacing=0 cellpadding=0 width="100%" style='width:100.0%;
+ mso-cellspacing:0in;margin-left:25.5pt;mso-padding-alt:1.5pt 1.5pt 1.5pt 1.5pt'>
+ <tr>
+ <td valign=top style='background:#0080C0;padding:1.5pt 1.5pt 1.5pt 1.5pt'>
+ <p class=MsoNormal><span style='mso-bookmark:_Toc506634621'><span
+ style='mso-bookmark:_Toc496069418'><b><span style='font-family:Arial;
+ color:white'>&nbsp;Eclipse Corner Article</span></b></span></span><span
+ style='mso-bookmark:_Toc506634621'><span style='mso-bookmark:_Toc496069418'><span
+ style='mso-bidi-font-size:12.0pt'><o:p></o:p></span></span></span></p>
+ </td>
+ <span style='mso-bookmark:_Toc506634621'><span style='mso-bookmark:_Toc496069418'></span></span>
+ </tr>
+</table>
+
+<h1 style='margin-left:25.5pt'><span style='mso-bookmark:_Toc506634621'><span
+style='mso-bookmark:_Toc496069418'><img width=120 height=86 id="_x0000_i1043"
+src="Writing%20Your%20Own%20Widget_files/Idea.jpg" align=CENTER></span></span><span
+style='mso-bookmark:_Toc506634621'><span style='mso-bookmark:_Toc496069418'><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt'><o:p></o:p></span></span></span></h1>
+
+<h1 align=center style='margin-left:25.5pt;text-align:center'><span
+style='mso-bookmark:_Toc506634621'><span style='mso-bookmark:_Toc496069418'>Creating
+Your Own Widgets using SWT</span></span></h1>
+
+<p class=MsoNormal style='margin-left:25.5pt;text-indent:.5in'><span
+style='mso-bookmark:_Toc506634621'><span style='mso-bookmark:_Toc496069418'><b><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></span></span></p>
+
+<p class=MsoNormal style='margin-top:0in;margin-right:.5in;margin-bottom:0in;
+margin-left:61.5pt;margin-bottom:.0001pt'><span style='mso-bookmark:_Toc506634621'><span
+style='mso-bookmark:_Toc496069418'><b>Summary</b> <br>
+When writing applications, you typically use the standard widgets provided by
+SWT. On occasion, you will need to create your own custom widgets. For example,
+you might want to add a new type of widget not provided by the standard
+widgets, or extend the functionality of an existing widget.<span
+style="mso-spacerun: yes">  </span>This article explains the different SWT
+extension strategies and shows you how to use them. </span></span></p>
+
+<p class=MsoNormal style='margin-top:0in;margin-right:.5in;margin-bottom:0in;
+margin-left:61.5pt;margin-bottom:.0001pt'><span style='mso-bookmark:_Toc506634621'><span
+style='mso-bookmark:_Toc496069418'><b><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></span></span></p>
+
+<p class=MsoNormal style='margin-top:0in;margin-right:.5in;margin-bottom:0in;
+margin-left:61.5pt;margin-bottom:.0001pt'><span style='mso-bookmark:_Toc506634621'><span
+style='mso-bookmark:_Toc496069418'><b>By Steve Northover &amp; Carolyn MacLeod,
+OTI<br>
+</b></span></span><span style='mso-bookmark:_Toc506634621'><span
+style='mso-bookmark:_Toc496069418'><span style='font-size:10.0pt'>March 22,
+2001</span><b><o:p></o:p></b></span></span></p>
+
+<p class=MsoNormal style='margin-top:0in;margin-right:.5in;margin-bottom:0in;
+margin-left:61.5pt;margin-bottom:.0001pt'><span style='mso-bookmark:_Toc506634621'><span
+style='mso-bookmark:_Toc496069418'><b><span style='font-size:8.0pt;mso-bidi-font-size:
+10.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></b></span></span></p>
+
+
+<div class=MsoNormal align=center style='margin-left:25.5pt;text-align:center'><span
+style='mso-bookmark:_Toc506634621'><span style='mso-bookmark:_Toc496069418'>
+
+<hr size=2 width="100%" align=center>
+
+</span></span></div>
+
+<b><span style='font-size:21.0pt;font-family:Arial;mso-fareast-font-family:
+"Times New Roman";mso-font-kerning:14.0pt;mso-ansi-language:EN-US;mso-fareast-language:
+EN-US;mso-bidi-language:AR-SA'><br clear=all style='page-break-before:always'>
+</span></b>
+
+<h1 style='margin-left:25.5pt'><span style='mso-bookmark:_Toc506634621'><span
+style='mso-bookmark:_Toc496069418'>Creating Your Own Widgets</span></span></h1>
+
+<h2 style='margin-left:25.5pt'><a name="_Toc496069419"></a><a
+name="_Toc496069776"></a><a name="_Toc506634622"><span style='mso-bookmark:
+_Toc496069776'><span style='mso-bookmark:_Toc496069419'>Overview</span></span></a></h2>
+
+<p class=MsoNormal style='margin-left:25.5pt'>When writing applications, you
+typically use the standard widgets provided by SWT. On occasion, you will need
+to create your own custom widgets. There are several reasons that you might
+want to do this:</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>To add a new type of widget not provided by the
+standard widgets</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>To extend the functionality of an existing widget</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Custom widgets are
+created by subclassing in the existing widget class hierarchy.</p>
+
+<h2 style='margin-left:25.5pt'><a name="_Toc506634623">Portability Issues</a></h2>
+
+<p class=MsoNormal style='margin-left:25.5pt'>It is very important to think
+about portability before writing a custom widget. SWT can be extended in the
+following ways:</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Write a new widget that is 100% Java&trade; portable</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Extend an existing widget in a 100% Java portable
+manner</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Write a new widget that wraps an existing native widget
+– not portable</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Extend an existing widget by calling natives – not
+portable</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>In addition, a combination of
+these can be used on different platforms:</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Write a new widget that wraps an existing native widget
+on one platform, but is 100% Java portable on other platforms</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Extend an existing widget by calling natives on one
+platform, but call 100% Java portable code on other platforms</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>This of course involves
+implementing the widget twice – using native calls on the one platform and
+portable code on the others – while maintaining the same API for both.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>Each SWT platform is shipped with
+both a shared library (for example, a DLL on Windows&reg;) and a jar (for the Java
+class files). The shared library contains all of the native function required
+for SWT, but it was not meant to be a complete set of the functions available
+on the platform. Thus to expose native function or native widgets that were not
+exposed by SWT, you need to write your own shared library. If you are using a
+combination of native code on one platform and portable code on another, make
+sure you call your shared library on the platform with the native widget, and
+your jar on the platform with the portable widget.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>One final note: SWT’s interface
+to its shared libraries is internal SWT code. It was not meant to provide a framework
+for applications to access all possible native function on all platforms – that
+would be a daunting task. One of the purposes of this document is to show how
+you can integrate C code with SWT, not model the operating system. As such, the
+approach taken to writing natives in this document is different from the
+approach taken by SWT.<br clear=all style='mso-special-character:line-break;
+page-break-before:always'>
+</p>
+
+<h2 style='margin-left:25.5pt;mso-list:skip'><a name="_Toc496069420"></a><a
+name="_Toc496069777"></a><a name="_Toc506634624"><span style='mso-bookmark:
+_Toc496069777'><span style='mso-bookmark:_Toc496069420'>Writing Portable
+Widgets</span></span></a></h2>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>The SWT library
+provides two widget classes that are typically used as the basis for a custom
+100% Java portable widget:</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]><i style='mso-bidi-font-style:normal'>Canvas</i> - to
+create basic widgets</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]><i style='mso-bidi-font-style:normal'>Composite</i> -
+to create compound widgets</p>
+
+<h3 style='margin-left:25.5pt'><a name="_Toc496069421"></a><a
+name="_Toc496069778"></a><a name="_Toc506634625"><span style='mso-bookmark:
+_Toc496069778'><span style='mso-bookmark:_Toc496069421'>Basic Widgets</span></span></a></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Basic widgets do
+not contain any other widgets, and are not built from any other widgets. Basic
+widgets draw themselves. An example of a basic widget is <i style='mso-bidi-font-style:
+normal'>Button</i>. Another example is <i style='mso-bidi-font-style:normal'>Text</i>.
+To create a custom basic widget, subclass <i style='mso-bidi-font-style:normal'>Canvas</i>.</p>
+
+<h3 style='margin-left:25.5pt;mso-list:skip'><a name="_Toc496069422"></a><a
+name="_Toc496069779"></a><a name="_Toc506634626"><span style='mso-bookmark:
+_Toc496069779'><span style='mso-bookmark:_Toc496069422'>Compound Widgets</span></span></a></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Compound widgets
+contain other widgets, and/or are composed of other widgets. An example of a
+compound widget is <i style='mso-bidi-font-style:normal'>Combo</i>. It contains
+a <i style='mso-bidi-font-style:normal'>Text</i>, a <i style='mso-bidi-font-style:
+normal'>Button</i> and a <i style='mso-bidi-font-style:normal'>List</i>.
+Another example is <i style='mso-bidi-font-style:normal'>Group</i>. It can contain
+any number of children. To create a custom compound widget, subclass <i
+style='mso-bidi-font-style:normal'>Composite</i>.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>The astute reader may have
+noticed that <i style='mso-bidi-font-style:normal'>Canvas</i> is actually a
+subclass of <i style='mso-bidi-font-style:normal'>Composite</i>. This is an
+artifact of the underlying implementation. We treat <i style='mso-bidi-font-style:
+normal'>Canvas</i> as something you draw on and <i style='mso-bidi-font-style:
+normal'>Composite</i> as something that has children. Therefore the rule for
+deciding which class to subclass is this: If your widget has or will have
+children, subclass <i style='mso-bidi-font-style:normal'>Composite</i>. If your
+widget does not have and never will have children, subclass <i
+style='mso-bidi-font-style:normal'>Canvas</i>.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>Note also that we do not
+distinguish between a compound widget that is intended to contain and lay out
+children, and one that is merely composed of other widgets. Both will be a
+subclass of <i style='mso-bidi-font-style:normal'>Composite</i>, and as such we
+are describing implementation, rather than type, inheritance. When writing 100%
+Java portable widgets, we can think of <i style='mso-bidi-font-style:normal'>Composite
+</i>as the portable entry point into the SWT class hierarchy for all compound
+widgets, and <i style='mso-bidi-font-style:normal'>Canvas </i>as the portable
+entry point into the SWT class hierarchy for all basic widgets, regardless of
+widget type.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<b><span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:
+"Times New Roman";mso-ansi-language:EN-US;mso-fareast-language:EN-US;
+mso-bidi-language:AR-SA'><br clear=all style='page-break-before:always'>
+</span></b>
+
+<h2 style='margin-left:25.5pt'><a name="_Toc496069423"></a><a
+name="_Toc496069780"><span style='mso-bookmark:_Toc496069423'>Basic Widget
+Example</span></a><span style='mso-bookmark:_Toc496069423'></span><span
+style='mso-bookmark:_Toc496069780'></span><span style='font-size:12.0pt;
+mso-bidi-font-size:18.0pt;font-family:"Times New Roman";font-weight:normal'><o:p></o:p></span></h2>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Imagine we are
+building an application where we need a widget that displays an image with a
+line of text to the right, something like this:</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><!--[if gte vml 1]><o:wrapblock><v:shapetype
+ id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"
+ path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
+ <v:stroke joinstyle="miter"/>
+ <v:formulas>
+ <v:f eqn="if lineDrawn pixelLineWidth 0"/>
+ <v:f eqn="sum @0 1 0"/>
+ <v:f eqn="sum 0 0 @1"/>
+ <v:f eqn="prod @2 1 2"/>
+ <v:f eqn="prod @3 21600 pixelWidth"/>
+ <v:f eqn="prod @3 21600 pixelHeight"/>
+ <v:f eqn="sum @0 0 1"/>
+ <v:f eqn="prod @6 1 2"/>
+ <v:f eqn="prod @7 21600 pixelWidth"/>
+ <v:f eqn="sum @8 21600 0"/>
+ <v:f eqn="prod @7 21600 pixelHeight"/>
+ <v:f eqn="sum @10 21600 0"/>
+ </v:formulas>
+ <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
+ <o:lock v:ext="edit" aspectratio="t"/>
+ </v:shapetype><v:shape id="_x0000_s1033" type="#_x0000_t75" style='position:absolute;
+ left:0;text-align:left;margin-left:154.8pt;margin-top:-14.25pt;width:51.75pt;
+ height:17.25pt;z-index:3;mso-position-horizontal-relative:text;
+ mso-position-vertical-relative:text' o:allowincell="f">
+ <v:imagedata src="./Writing%20Your%20Own%20Widget_files/image001.png"
+ o:title=""/>
+ <w:wrap type="topAndBottom" anchorx="page"/>
+ </v:shape><![if gte mso 9]><o:OLEObject Type="Embed" ProgID="PBrush"
+ ShapeID="_x0000_s1033" DrawAspect="Content" ObjectID="_1053168690">
+ </o:OLEObject>
+ <![endif]><![endif]--><![if !vml]><span style='mso-ignore:vglayout'>
+ <table cellpadding=0 cellspacing=0 align=left>
+ <tr>
+ <td width=206 height=0></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img width=69 height=23
+ src="./Writing%20Your%20Own%20Widget_files/image002.jpg" v:shapes="_x0000_s1033"></td>
+ </tr>
+ </table>
+ </span><![endif]><!--[if gte vml 1]></o:wrapblock><![endif]--><br
+style='mso-ignore:vglayout' clear=ALL>
+<![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p><p></p>
+
+<br style='mso-ignore:vglayout' clear=ALL>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Since we plan to
+draw both the image and the text, we subclass <i style='mso-bidi-font-style:
+normal'>Canvas</i>.</p>
+
+<p style='margin-top:0in;margin-right:0in;margin-bottom:0in;margin-left:25.5pt;
+margin-bottom:.0001pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> org.eclipse.swt.*;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+org.eclipse.swt.graphics.*;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> org.eclipse.swt.widgets.*;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> org.eclipse.swt.events.*;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>class</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> PictureLabel </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>extends</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Canvas {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>Image image;<span style='mso-tab-count:1'>  </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>String text;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Our widget needs to
+be created. To do this, we must write at least one constructor. Because widgets
+in SWT cannot be created without a parent, the constructor must take at least
+one argument that is the parent. The convention in SWT is to have a constructor
+with two arguments, <b style='mso-bidi-font-weight:normal'>parent</b> and <b
+style='mso-bidi-font-weight:normal'>style</b>. Style bits are used to control
+the look of widgets. Neither the parent nor the style bits can be changed after
+the widget is created. Your widget can use style bits too.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>PictureLabel(Composite parent, </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>int</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+style) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>super</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>(parent, style);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<span style='mso-tab-count:1'>  </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>The parent of any
+widget must be a <i style='mso-bidi-font-style:normal'>Composite</i>. The style
+is an integer, where some bits are already used by the system. For example, <b
+style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt'>SWT.BORDER</span></b>
+will cause a <i style='mso-bidi-font-style:normal'>Canvas</i> to have a border.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Next we need to
+initialize our widget. The convention in SWT is to do all initialization in the
+constructor. Certainly, any initialization that requires the parent or the
+style bits must be done here. We have decided that our <i style='mso-bidi-font-style:
+normal'>PictureLabel</i> widget will default to a white background, so we need
+to add a <i style='mso-bidi-font-style:normal'>Color</i> field, allocate a <i
+style='mso-bidi-font-style:normal'>Color</i>, and initialize the background.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>class</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> PictureLabel </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>extends</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Canvas {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>Image image;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>String text;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>Color white;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>PictureLabel(Composite parent, </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>int</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+style) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>super</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>(parent, style);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>white = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Color(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, 255, 255, 255);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>setBackground(white);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Colors are graphics
+resources that must be disposed. How can we dispose of the white color that we
+allocated? We add a dispose listener. Every widget provides notification when
+it is destroyed. We add the dispose listener in the constructor.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>addDisposeListener(</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+DisposeListener() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+widgetDisposed(DisposeEvent e) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+4'>                </span>white.dispose();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>});<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><b
+style='mso-bidi-font-weight:normal'>Note:</b> Do not just override dispose() to
+release the color. This only works in the case where dispose is actually sent
+to the widget. When the shell is disposed this does not happen, so overriding
+dispose will leak the color. To ensure that your widget is informed of an event
+no matter how it was generated, add an event listener instead of overriding
+methods that generate events. </p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Our widget is
+created and initialized, and it can be destroyed without leaking graphics
+resources. Now it needs some functionality. We need to draw the image and the
+text, and this will require another listener: the paint listener. Implementing
+a widget often requires adding many listeners. We could implement the listener
+interfaces as part of our new widget class, but that would make the interface
+methods public in our class. Instead, the SWT convention is to use anonymous inner
+classes to forward the functionality to non-public methods of the same name.
+For consistency, we will rewrite the dispose listener to follow this
+convention, moving the color dispose code into the <b style='mso-bidi-font-weight:
+normal'>widgetDisposed</b> method. We write the paint listener the same way.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>addDisposeListener(</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+DisposeListener() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+widgetDisposed(DisposeEvent e) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+4'>            </span>PictureLabel.</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>this</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>.widgetDisposed(e);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>});<span style='mso-tab-count:1'> </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>addPaintListener(</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+PaintListener() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> paintControl(PaintEvent e)
+{<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+4'>            </span>PictureLabel.</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>this</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>.paintControl(e);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>});<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>By choosing the
+same names, we have the option of easily implementing the interfaces if we
+decide to do so later. Here is the <b style='mso-bidi-font-weight:normal'>paintControl</b>
+method to draw the widget.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> paintControl(PaintEvent e)
+{<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>GC gc = e.gc;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> x = 1;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (image != </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>gc.drawImage(image, x, 1); <o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>x = image.getBounds().width + 5;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (text != </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>gc.drawString(text, x, 1);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>}<span style='mso-tab-count:1'>  </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p style='margin-top:0in;margin-right:0in;margin-bottom:0in;margin-left:25.5pt;
+margin-bottom:.0001pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Now we can draw the
+image and the text, but we need to let the user set them. So we write set and
+get methods for each of them.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Image getImage() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> image;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> setImage(Image image) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>.image = image;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>redraw();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> String getText() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> text;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> setText(String text) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>.text = text;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>redraw();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>The get methods are
+trivial. They simply answer the fields. The set methods set the fields and then
+redraw the widget to show the change. The easiest way to do this is to damage
+the widget by calling <b style='mso-bidi-font-weight:normal'>redraw()</b>,
+which queues a paint event for the widget. This approach has the advantage that
+setting both the image and the text will cause only one paint event because
+multiple paints are collapsed in the event queue.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>We are not done
+yet. Our widget does not know its preferred size. This information is needed in
+order to lay out the widget. In our case, the best size is simply the size of
+the text plus the size of the image, plus a little bit of space in between.
+Also, we will add a 1 pixel margin all the way around.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>To return the
+preferred size of the widget, we must implement the <b style='mso-bidi-font-weight:
+normal'>computeSize</b> method. The <b style='mso-bidi-font-weight:normal'>computeSize</b>
+method can be quite complicated. Its job is to calculate the preferred size of
+the widget based on the current contents. The simplest implementation ignores
+the arguments and just computes the size.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Point computeSize(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> wHint, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> hHint, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>boolean</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> changed) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> width = 0, height = 0;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (image != </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>Rectangle bounds = image.getBounds();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>width = bounds.width + 5;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>height = bounds.height;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (text != </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>GC gc = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+GC(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>Point extent = gc.stringExtent(text);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>gc.dispose();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>width += extent.x;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>height = Math.max(height, extent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Point(width + 2, height +
+2);<span style='mso-tab-count:1'>     </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>What are <b
+style='mso-bidi-font-weight:normal'>wHint</b>, <b style='mso-bidi-font-weight:
+normal'>hHint</b>, and <b style='mso-bidi-font-weight:normal'>changed</b>? The
+hint arguments allow you to ask a widget questions such as “Given a particular
+width, how high does the widget need to be to show all of the contents”? For
+example, a word-wrapping <i style='mso-bidi-font-style:normal'>Label</i> widget
+might be asked this. To indicate that the client does not care about a
+particular hint, the special value <b style='mso-bidi-font-weight:normal'><span
+style='font-size:10.0pt'>SWT.DEFAULT</span></b> is used. The following example
+asks a label for its preferred size given a width of 100 pixels: </p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>Point extent = label.computeSize(100, </span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>For our <i
+style='mso-bidi-font-style:normal'>PictureLabel</i> widget, we could be fancy
+and stack the image over the text when the width is too small, and/or wrap the text
+in order to meet a width request, but for simplicity we have decided not to do
+so. Still, we need to honour the hints. So, our widget will clip. The easiest
+way to do this is to perform the calculation and then filter the results.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Point computeSize(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> wHint, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> hHint, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>boolean</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> changed) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> width = 0, height = 0;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (image != </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>Rectangle bounds = image.getBounds();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>width = bounds.width + 5;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>height = bounds.height;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (text != </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>GC gc = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+GC(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>Point extent = gc.stringExtent(text);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>gc.dispose();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>width += extent.x;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>height = Math.max(height, extent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (wHint != </span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) width = wHint;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (hHint != </span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) height = hHint;<span
+style='mso-tab-count:2'>          </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Point(width + 2, height +
+2);<span style='mso-tab-count:1'>     </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Notice that we do
+not return the hint sizes exactly as specified. We have added the 1-pixel
+border. Why do we do this? All widgets have a <i style='mso-bidi-font-style:
+normal'>client area</i> and <i style='mso-bidi-font-style:normal'>trim</i>. The
+hint parameters specify the desired size of the client area. We must set the
+size of the widget so that the size of the client area is the same as the hint,
+so the size we return from <b style='mso-bidi-font-weight:normal'>computeSize</b>
+must include the trim.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>What about the <b
+style='mso-bidi-font-weight:normal'>changed</b> flag? This is used in
+conjunction with SWT layout managers and is ignored for basic widgets. This
+will be discussed when we talk about compound widgets.</p>
+
+<span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;
+mso-bidi-font-weight:bold'><br clear=all style='page-break-before:always'>
+</span>
+
+<h2 style='margin-left:25.5pt;mso-list:skip'><a name="_Toc496069424"></a><a
+name="_Toc496069781"></a><a name="_Ref506190201"></a><a name="_Toc506634627"><span
+style='mso-bookmark:_Ref506190201'><span style='mso-bookmark:_Toc496069781'><span
+style='mso-bookmark:_Toc496069424'>Compound Widget Example</span></span></span></a></h2>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Now we will recode
+the <i style='mso-bidi-font-style:normal'>PictureLabel</i> widget as a compound
+widget. Note that this section assumes that you have read the basic widget
+example section. This time the widget will be implemented using two <i
+style='mso-bidi-font-style:normal'>Label</i> children: one to display the
+image, and one to display the text. Since we are using other widgets to
+implement our widget, we subclass <i style='mso-bidi-font-style:normal'>Composite</i>.</p>
+
+<p class=Code style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>class</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> PictureLabel </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>extends</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Composite {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>Label image, text;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>Color white;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>PictureLabel(Composite parent, </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>int</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+style) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>super</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>(parent, style);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>white = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Color(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, 255, 255, 255);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>image = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Label(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, 0);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>text = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Label(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, 0);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>setBackground(white);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>image.setBackground(white);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>text.setBackground(white);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>addDisposeListener(</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+DisposeListener() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+widgetDisposed(DisposeEvent e) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+4'>            </span>PictureLabel.</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>this</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>.widgetDisposed(e);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>});<span style='mso-tab-count:1'> </span><o:p></o:p></span></p>
+
+<p class=Code style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>As well as
+initializing the graphics resources in the constructor, we need to create the child
+widgets and set their background color. A common mistake is to create the child
+widgets as children of the parent. This would make them peers of our widget.
+Instead, make sure to create them as children of <b style='mso-bidi-font-weight:
+normal'>this</b>. The dispose listener frees the color, as before.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Now that we have
+handled creation and destruction, we need to lay out the children. There are
+two possibilities:</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>position the children when the widget is resized</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>use a layout manager</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>We will implement
+both here for comparison.</p>
+
+<h3 style='margin-left:25.5pt;mso-list:skip'><a name="_Toc496069425"></a><a
+name="_Toc496069782"></a><a name="_Toc506634628"><span style='mso-bookmark:
+_Toc496069782'><span style='mso-bookmark:_Toc496069425'>Positioning Children on
+Resize</span></span></a></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>First, we will
+position the children when the widget is resized. We need to add a resize
+listener.</p>
+
+<p class=Code style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>addControlListener(</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+ControlAdapter() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+controlResized(ControlEvent e) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+4'>            </span>PictureLabel.</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>this</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>.controlResized(e);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>});<span style='mso-tab-count:1'> </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman"'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+controlResized(ControlEvent e) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Point iExtent = image.computeSize(</span><span style='font-size:
+8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:black'>SWT.DEFAULT</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black'>, </span><span style='font-size:8.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Point tExtent = text.computeSize(</span><span style='font-size:
+8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:black'>SWT.DEFAULT</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black'>, </span><span style='font-size:8.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>image.setBounds(1, 1, iExtent.x, iExtent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>text.setBounds(iExtent.x + 5, 1, tExtent.x, tExtent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=Code style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>When the widget is
+resized, we compute the size of each of our children, and then use their
+extents and our 5-pixel spacing and 1-pixel margin to position the children
+using <b style='mso-bidi-font-weight:normal'>setBounds</b>.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Now we will write
+the set and get methods. Because we are not drawing the image and text,
+damaging the widget will not cause the correct behavior. The children must be
+resized to show their new contents. To do this, we will take the code from the
+resize listener and move it into a helper method called <b style='mso-bidi-font-weight:
+normal'>resize</b>.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+controlResized(ControlEvent e) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>resize();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> resize() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Point iExtent = image.computeSize(</span><span style='font-size:
+8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:black'>SWT.DEFAULT</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black'>, </span><span style='font-size:8.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Point tExtent = text.computeSize(</span><span style='font-size:
+8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:black'>SWT.DEFAULT</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black'>, </span><span style='font-size:8.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>image.setBounds(1, 1, iExtent.x, iExtent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>text.setBounds(iExtent.x + 5, 1, tExtent.x, tExtent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Here are the set
+and get methods.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Image getImage() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> image.getImage();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> setImage(Image image) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>.image.setImage(image);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>resize();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> String getText() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> text.getText();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> setText(String text) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>.text.setText(text);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>resize();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p style='margin-top:0in;margin-right:0in;margin-bottom:0in;margin-left:25.5pt;
+margin-bottom:.0001pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Now we have to
+implement the <b style='mso-bidi-font-weight:normal'>computeSize</b> method. This
+is a simple matter of asking the children for their preferred sizes.</p>
+
+<p style='margin-top:0in;margin-right:0in;margin-bottom:0in;margin-left:25.5pt;
+margin-bottom:.0001pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Point computeSize(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> wHint, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> hHint, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>boolean</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> changed) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Point iExtent = image.computeSize(</span><span style='font-size:
+8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:black'>SWT.DEFAULT</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black'>, </span><span style='font-size:8.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Point tExtent = text.computeSize(</span><span style='font-size:
+8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:black'>SWT.DEFAULT</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black'>, </span><span style='font-size:8.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> width = iExtent.x + 5 +
+tExtent.x;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> height =
+Math.max(iExtent.y, tExtent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (wHint != </span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) width = wHint;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (hHint != </span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) height = hHint;<span
+style='mso-tab-count:2'>          </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Point(width + 2, height +
+2);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<h3 style='margin-left:25.5pt;mso-list:skip'><a name="_Toc496069426"></a><a
+name="_Toc496069783"></a><a name="_Toc506634629"><span style='mso-bookmark:
+_Toc496069783'><span style='mso-bookmark:_Toc496069426'>Positioning Children
+With a Layout Manager</span></span></a></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Now we will rewrite
+our compound widget example using a layout manager to position our widget’s
+children. We could just use an existing SWT layout manager - <i
+style='mso-bidi-font-style:normal'>RowLayout</i> - to position the children,
+but we promised to explain the <b style='mso-bidi-font-weight:normal'>changed</b>
+parameter in the <b style='mso-bidi-font-weight:normal'>computeSize</b> method.
+This also gives an example of how this might be done for more complicated
+layout requirements. In the code that follows, the class <i style='mso-bidi-font-style:
+normal'>PictureLabelLayout</i> extends <i style='mso-bidi-font-style:normal'>Layout</i>,
+and the rewritten <i style='mso-bidi-font-style:normal'>PictureLabel</i> class
+is listed in its entirety.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>The layout manager
+is set into the widget with the following line of code in the widget
+constructor:</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>setLayout(</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+PictureLabelLayout());<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>We will call the
+layout manager in the widget’s two <b style='mso-bidi-font-weight:normal'>set</b>
+methods, with the following line of code:</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>layout(</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>true</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>The parameter to
+the <b style='mso-bidi-font-weight:normal'>layout</b> method is the <b
+style='mso-bidi-font-weight:normal'>changed</b> flag. If <b style='mso-bidi-font-weight:
+normal'>true</b>, it indicates that the widget contents have changed (as is the
+case in the two <b style='mso-bidi-font-weight:normal'>set </b>methods),
+therefore any caches that the layout manager may have been keeping need to be
+flushed. When the widget is resized, the SWT system sends <b style='mso-bidi-font-weight:
+normal'>layout(false)</b> to the layout manager, so caches do not need to be
+flushed. This lets the layout manager perform any expensive calculations only
+when necessary.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>In class <i
+style='mso-bidi-font-style:normal'>PictureLabelLayout</i>, we know that <b
+style='mso-bidi-font-weight:normal'>composite.getChildren()</b> will always
+return exactly two children. In general, a layout manager will have to handle
+any number of children, so if you are implementing a widget that can have an
+arbitrary number of children you will need to loop through them to do your
+calculations. Note that it is in this class that we check the value of the <b
+style='mso-bidi-font-weight:normal'>changed</b> flag and optionally flush our
+two “extent” caches.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Notice that the <i
+style='mso-bidi-font-style:normal'>PictureLabel</i> class has been simplified
+by using a layout manager. The code in <b style='mso-bidi-font-weight:normal'>computeSize</b>
+and <b style='mso-bidi-font-weight:normal'>resize</b> has been moved to the <i
+style='mso-bidi-font-style:normal'>PictureLabelLayout</i> class, and the resize
+listener is no longer needed.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> org.eclipse.swt.*;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+org.eclipse.swt.graphics.*;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> org.eclipse.swt.widgets.*;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> org.eclipse.swt.events.*;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>class</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> PictureLabelLayout </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>extends</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Layout {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>Point iExtent, tExtent; </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:maroon;layout-grid-mode:line'>// the cached sizes</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>protected</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Point
+computeSize(Composite composite, </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>int</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+wHint, </span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> hHint,<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>boolean</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> changed) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Control [] children = composite.getChildren();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (changed || iExtent == </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> || tExtent == </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>iExtent = children[0].computeSize(</span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>tExtent = children[1].computeSize(</span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> width = iExtent.x + 5 +
+tExtent.x;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> height = Math.max(iExtent.y,
+tExtent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Point(width + 2, height +
+2);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>protected</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> layout(Composite
+composite, </span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>boolean</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> changed) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Control [] children = composite.getChildren();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (changed || iExtent == </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> || tExtent == </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>iExtent = children[0].computeSize(</span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>tExtent = children[1].computeSize(</span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:8.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>SWT.DEFAULT</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>false</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>children[0].setBounds(1, 1, iExtent.x, iExtent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>children[1].setBounds(iExtent.x + 5, 1, tExtent.x, tExtent.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>class</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> PictureLabel </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>extends</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Composite {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>Label image, text;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>Color white;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>PictureLabel(Composite parent, </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>int</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+style) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>super</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>(parent, style);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>white = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Color(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, 255, 255, 255);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>image = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Label(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, 0);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>text = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Label(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, 0);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>setBackground(white);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>text.setBackground(white);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>image.setBackground(white);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>addDisposeListener(</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+DisposeListener() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+widgetDisposed(DisposeEvent e) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+4'>            </span>PictureLabel.</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>this</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>.widgetDisposed(e);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>});<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>setLayout(</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'> PictureLabelLayout());<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+widgetDisposed(DisposeEvent e) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>white.dispose();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> Image getImage() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> image.getImage();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> setImage(Image image) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>.image.setImage(image);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>layout(</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>true</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> String getText() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>return</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> text.getText();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> setText(String text) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>.text.setText(text);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>layout(</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>true</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>}<o:p></o:p></span></p>
+
+<span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;
+mso-bidi-font-weight:bold'><br clear=all style='page-break-before:always'>
+</span>
+
+<h2 style='margin-left:25.5pt;mso-list:skip'><a name="_Toc506634630">Events and
+Listeners</a></h2>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Often, you will
+want a new widget to support an event. For example, you may want your widget to
+notify listeners when the user selects it. Or you may have an editable widget
+that should notify listeners when its value has changed.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>The details to
+implement an event called <i style='mso-bidi-font-style:normal'>AnEvent</i> are
+<b style='mso-bidi-font-weight:normal'><i style='mso-bidi-font-style:normal'>exactly</i></b>
+the same as implementing a Java Bean listener:</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>create a class called <i style='mso-bidi-font-style:
+normal'>AnEvent </i>which extends <i style='mso-bidi-font-style:normal'>java.util.EventObject</i>
+and may have additional fields related to the event. Usually you want to
+provide get methods for event fields, but you do not always want to provide set
+methods. Fields are typically set in the constructor.</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>create a class called <i style='mso-bidi-font-style:
+normal'>AnEventListener </i>which implements the <i style='mso-bidi-font-style:
+normal'>java.util.EventListener </i>interface and provides a method called,
+say, <b style='mso-bidi-font-weight:normal'>anEventHappened(AnEvent event)</b></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>keep a <i style='mso-bidi-font-style:normal'>Vector</i>
+(or some other collection) of <i style='mso-bidi-font-style:normal'>AnEventListener</i>’s
+in your widget class</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>implement <b style='mso-bidi-font-weight:normal'>addAnEventListener</b>
+which adds the specified listener to the <i style='mso-bidi-font-style:normal'>Vector</i></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>implement <b style='mso-bidi-font-weight:normal'>removeAnEventListener</b>
+to remove the specified listener from the <i style='mso-bidi-font-style:normal'>Vector</i></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>determine when the event happens in your widget
+(possibly by adding listeners to your widget) and when it does:</p>
+
+<p class=MsoNormal style='margin-left:61.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>create an instance of <i style='mso-bidi-font-style:
+normal'>AnEvent</i> called <b style='mso-bidi-font-weight:normal'>event</b>,
+initialized as appropriate</p>
+
+<p class=MsoNormal style='margin-left:61.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>send <b style='mso-bidi-font-weight:normal'>anEventHappened(event)</b>
+to each of the <i style='mso-bidi-font-style:normal'>AnEventListener</i>’s in
+the <i style='mso-bidi-font-style:normal'>Vector</i></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><b style='mso-bidi-font-weight:
+normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Say we want <i
+style='mso-bidi-font-style:normal'>PictureLabel</i> widgets to notify listeners
+when the user clicks the left mouse button in the image. We create class <i
+style='mso-bidi-font-style:normal'>ImageClickedEvent</i> with <b
+style='mso-bidi-font-weight:normal'>x</b> and <b style='mso-bidi-font-weight:
+normal'>y</b> fields, and interface <i style='mso-bidi-font-style:normal'>ImageClickedListener</i>
+with method <b style='mso-bidi-font-weight:normal'>imageClicked(ImageClickedEvent
+event)</b>. </p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>class</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+ImageClickedEvent </span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy;
+layout-grid-mode:line'>extends</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> java.util.EventObject {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>public</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>int</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> x, y;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>public</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> ImageClickedEvent(Object source, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> x, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>int</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> y) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>super</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'>(source);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>this</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'>.x = x;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>this</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'>.y = y;<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>interface</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+ImageClickedListener </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>extends</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> java.util.EventListener {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>public</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>void</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> imageClicked(ImageClickedEvent event);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>We add a <i
+style='mso-bidi-font-style:normal'>Vector</i> to <i style='mso-bidi-font-style:
+normal'>PictureLabel</i> to store the listeners:</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>Vector imageClickedListeners = </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+Vector();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman"'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>public</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>void</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'>
+addImageClickedListener(ImageClickedListener listener) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>imageClickedListeners.addElement(listener);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>public</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>void</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> removeImageClickedListener(ImageClickedListener
+listener) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>imageClickedListeners.removeElement(listener);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Finally, in <i
+style='mso-bidi-font-style:normal'>PictureLabel</i>’s constructor, we add a
+mouse listener to the image <i style='mso-bidi-font-style:normal'>Label</i>
+widget, which does the work of notifying the listeners when the left mouse
+button is clicked over the image.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>…<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>addMouseListener(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+MouseAdapter() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>public</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>void</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> mouseDown(MouseEvent event) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>if</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (event.button == 1) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:5'>                </span>PictureLabel.</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>this</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>.mouseDown(event);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>});<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>public</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>void</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> mouseDown(MouseEvent event) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>ImageClickedEvent e = </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+ImageClickedEvent(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy;
+layout-grid-mode:line'>this</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'>, event.x, event.y);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>int</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> size = imageClickedListeners.size();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>for</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>int</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> i = 0; i &lt; size; i++) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span>ImageClickedListener listener =<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span>(ImageClickedListener) imageClickedListeners.elementAt(i);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span>listener.imageClicked(e);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></p>
+
+<span style='font-size:18.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;
+mso-bidi-font-weight:bold'><br clear=all style='page-break-before:always'>
+</span>
+
+<h2 style='margin-left:25.5pt;mso-list:skip'><a name="_Toc496069427"></a><a
+name="_Toc496069784"></a><a name="_Toc506634631"><span style='mso-bookmark:
+_Toc496069784'><span style='mso-bookmark:_Toc496069427'>Sample Application</span></span></a></h2>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Now we will use the
+new widget in an example application. The application simply creates a shell
+with a <i style='mso-bidi-font-style:normal'>PictureLabel</i> child. Then it
+sets the <i style='mso-bidi-font-style:normal'>PictureLabel</i>’s image to a
+little red square, and text to “Hi there!”. There is no <i style='mso-bidi-font-style:
+normal'>Layout</i> manager for the shell, so we will set the <i
+style='mso-bidi-font-style:normal'>PictureLabel</i>’s size. When the image is
+clicked, we change the text to “Red!”.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Here is the
+application code:</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> org.eclipse.swt.graphics.*;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:maroon'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>import</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> org.eclipse.swt.widgets.*;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:maroon'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>class</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> PictureLabelExample {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>static</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> main(String [] args) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Image image = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Image(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, 20, 20);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Color red = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Color(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>null</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>, 255, 0, 0);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>GC gc = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+GC(image);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>gc.setBackground(red);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>gc.fillRectangle(image.getBounds());<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>gc.dispose();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>red.dispose();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Shell shell = </span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+Shell();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>PictureLabel label = </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy'>new</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black'>
+PictureLabel(shell, 0);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>label.setImage(image);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>label.setText(</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:teal'>&quot;Hi there!&quot;</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Point size = label.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>label.setSize(size);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>label.addImageClickedListener(new ImageClickedListener() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy;
+layout-grid-mode:line'>public</span><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>void</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> imageClicked(ImageClickedEvent event) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span>((PictureLabel) event.getSource()).</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>setText(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal'>&quot;Red!&quot;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>);<span style='layout-grid-mode:
+line'><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>});</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>shell.open();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>Display display = shell.getDisplay();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>while</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'> (!shell.isDisposed()) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+3'>         </span></span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:navy'>if</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>
+(!display.readAndDispatch()) display.sleep();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+2'>     </span>image.dispose();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'><span style='mso-tab-count:
+1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black'>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>And here is what
+you see when you run it:</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-wrap:
+auto;mso-element-anchor-vertical:paragraph;mso-element-anchor-horizontal:column;
+mso-element-top:.05pt;mso-height-rule:exactly'>
+
+<table cellspacing=0 cellpadding=0 hspace=0 vspace=0>
+ <tr>
+ <td valign=top align=left style='padding-top:0in;padding-right:9.0pt;
+ padding-bottom:0in;padding-left:9.0pt'>
+ <p class=MsoNormal align=center style='margin-left:25.5pt;text-align:center;
+ mso-list:skip;mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-wrap:
+ auto;mso-element-anchor-vertical:paragraph;mso-element-anchor-horizontal:
+ column;mso-element-top:.05pt;mso-height-rule:exactly'><span style='font-size:
+ 10.0pt'><!--[if gte vml 1]><v:shape id="_x0000_i1046" type="#_x0000_t75"
+ style='width:99.75pt;height:82.5pt' fillcolor="window">
+ <v:imagedata src="./Writing%20Your%20Own%20Widget_files/image003.png"
+ o:title=""/>
+ </v:shape><![endif]--><![if !vml]><img width=133 height=110
+ src="./Writing%20Your%20Own%20Widget_files/image004.jpg" v:shapes="_x0000_i1046"><![endif]></span></p>
+ </td>
+ </tr>
+</table>
+
+</div>
+
+<p class=MsoNormal align=center style='margin-left:25.5pt;text-align:center;
+mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal align=center style='margin-left:25.5pt;text-align:center;
+mso-list:skip'><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><b
+style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+
+<p class=MsoNormal align=center style='margin-left:25.5pt;text-align:center;
+mso-list:skip'><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+
+<p class=MsoNormal align=center style='margin-left:25.5pt;text-align:center;
+mso-list:skip'><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+
+<p class=MsoNormal align=center style='margin-left:25.5pt;text-align:center;
+mso-list:skip'><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+
+<p class=MsoNormal align=center style='margin-left:25.5pt;text-align:center;
+mso-list:skip'><b style='mso-bidi-font-weight:normal'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></b></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><b
+style='mso-bidi-font-weight:normal'>A PictureLabel in a Shell<o:p></o:p></b></p>
+
+<h2 style='margin-left:25.5pt;mso-list:skip'><a name="_Ref498250831"></a><a
+name="_Toc506634632"><span style='mso-bookmark:_Ref498250831'>Advanced Issues</span></a></h2>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>We have discussed
+the basics of creating a custom widget: subclassing <i style='mso-bidi-font-style:
+normal'>Canvas</i> or <i style='mso-bidi-font-style:normal'>Composite</i>,
+creating and initializing, setting and getting the widget’s resources, drawing,
+disposing graphics resources, size and layout, and providing events and listeners.
+There are some advanced issues that you may need to deal with when you
+implement a new widget.</p>
+
+<h3 style='margin-left:25.5pt;mso-list:skip'><a name="_Toc506634633">SWT Event
+Mechanism</a></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt'>SWT provides a low-level listener
+mechanism as well as the usual Java ‘typed’ listeners. Every SWT widget
+understands <b style='mso-bidi-font-weight:normal'>addListener(int eventType,
+Listener listener)</b> and <b style='mso-bidi-font-weight:normal'>notifyListeners(int
+eventType, Event event)</b>. The <b style='mso-bidi-font-weight:normal'>eventType</b>
+constants are defined in class <i style='mso-bidi-font-style:normal'>SWT</i>.
+When an event occurs, the widget creates an SWT <i style='mso-bidi-font-style:
+normal'>Event</i> object containing the appropriate type constant. The <b
+style='mso-bidi-font-weight:normal'>notifyListeners </b>method<b
+style='mso-bidi-font-weight:normal'> </b>calls <b style='mso-bidi-font-weight:
+normal'>handleEvent(Event event)</b> for the <i style='mso-bidi-font-style:
+normal'>Listener</i>. If you need to reuse an existing SWT event, you would
+typically use this mechanism.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>For example, if your widget
+implements a selection event, you could implement your ‘typed’ add and remove
+methods as follows:</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+addSelectionListener(SelectionListener listener) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>addListener(SWT.Selection, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+TypedListener(listener));<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+removeSelectionListener(SelectionListener listener) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>removeListener(SWT.Selection, listener);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><br>
+When the ‘selection event’ occurs in your widget (say, when <b
+style='mso-bidi-font-weight:normal'>child1</b> is selected), you notify the
+application’s selection listeners using <b style='mso-bidi-font-weight:normal'>notifyListeners</b>.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>child1.addListener(SWT.Selection, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+Listener() {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>public</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>void</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> handleEvent(Event e) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span>notifyListeners(SWT.Selection, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+Event());<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>});<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>Note that when we add the
+listener we first wrap it in a <i style='mso-bidi-font-style:normal'>TypedListener</i>.
+This is because<i style='mso-bidi-font-style:normal'> TypedListener</i>’s <b
+style='mso-bidi-font-weight:normal'>handleEvent(Event event)</b> method creates
+the appropriate <i style='mso-bidi-font-style:normal'>TypedEvent</i> subclass
+based on the type in the <i style='mso-bidi-font-style:normal'>Event</i>, and
+then calls the appropriate method for the typed event. In this way,
+applications can add Java typed listeners to widgets, but widget
+implementations can use the more efficient low-level listener mechanism. Make
+sure that your widget implementation provides a typed listener API, however.
+Applications should not be calling low-level listener methods. The typed
+listener methods prevent accidental programming errors such as assuming that
+all widgets can handle all types of event, or that all fields in the <i
+style='mso-bidi-font-style:normal'>Event</i> class are valid for all events.</p>
+
+<span style='font-size:14.0pt;font-family:Arial;mso-fareast-font-family:"Times New Roman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;
+mso-bidi-font-weight:bold'><br clear=all style='page-break-before:always'>
+</span>
+
+<h3 style='margin-left:25.5pt;mso-list:skip'><a name="_Toc506634634"><span
+style="mso-spacerun: yes"> </span>Wrapping an SWT Widget</a></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Occasionally, you
+may find that the best way to implement a new widget is by wrapping an existing
+SWT widget. For example, to implement a <i style='mso-bidi-font-style:normal'>TableTree</i>,
+you might want to use a <i style='mso-bidi-font-style:normal'>Table</i>. To do
+this, create <i style='mso-bidi-font-style:normal'>TableTree</i> as a subclass
+of <i style='mso-bidi-font-style:normal'>Composite</i>, and then in the <i
+style='mso-bidi-font-style:normal'>TableTree</i> constructor create a <i
+style='mso-bidi-font-style:normal'>Table</i> child. The resulting widget will
+be 100% Java portable because you call the wrapped widget’s API.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>Here are some
+guidelines for wrapping SWT widgets:</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Forward as few methods and events as possible. Do not
+fall into the trap of automatically reimplementing the complete API of the
+wrapped widget. This will cause lots of boilerplate code and leave you playing
+catch up when new API is added to the wrapped widget. If you find that you are
+automatically forwarding every method, then it <i style='mso-bidi-font-style:
+normal'>might</i> make more sense to implement your code as an ‘adaptor’ (i.e.
+as a set of listeners that are added to the unwrapped widget when the widget is
+created).</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Typically the methods you forward will be <b
+style='mso-bidi-font-weight:normal'>setFont</b>, <b style='mso-bidi-font-weight:
+normal'>setForeground</b>, <b style='mso-bidi-font-weight:normal'>setBackground</b>,
+<b style='mso-bidi-font-weight:normal'>setCursor</b>,<b style='mso-bidi-font-weight:
+normal'> setEnabled</b>, <b style='mso-bidi-font-weight:normal'>setMenu</b>,
+and<b style='mso-bidi-font-weight:normal'> setToolTipText</b>. A typical
+forwarding method calls super to set the value for the parent, and then sets
+the value for the wrapped widget. You do not usually need to reimplement the
+corresponding get methods – these return the value from the parent.</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Do not reimplement <b style='mso-bidi-font-weight:normal'>setData</b>
+or <b style='mso-bidi-font-weight:normal'>getData</b> – your widget users can
+use the data field in the parent.</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Consider exposing the wrapped widget – it does not
+necessarily need to be hidden.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>A complete example
+of a <i style='mso-bidi-font-style:normal'>TableTree</i> widget that was
+implemented by wrapping a <i style='mso-bidi-font-style:normal'>Table</i> is
+provided in <a href="Writing%20Your%20Own%20Widget_files/AppendixA.htm">Appendix
+A: TableTree and TableTreeItem</a>. This example also shows how <i
+style='mso-bidi-font-style:normal'>TableTreeItem</i> was implemented by
+subclassing <i style='mso-bidi-font-style:normal'>Item</i> and wrapping a <i
+style='mso-bidi-font-style:normal'>TableItem</i>. Some of the design decisions
+that were made are:</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l2 level1 lfo4;
+tab-stops:list .25in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]>Wrap
+a <i style='mso-bidi-font-style:normal'>Table</i> widget</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l2 level1 lfo4;
+tab-stops:list .25in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]>Column
+0 of the <i style='mso-bidi-font-style:normal'>Table</i> widget will contain
+the ‘tree’ representation</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l2 level1 lfo4;
+tab-stops:list .25in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]>The
+image in column 0 will contain a [+] or [-] to show the expanded state of the
+tree</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l2 level1 lfo4;
+tab-stops:list .25in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]>Because
+we are using a <i style='mso-bidi-font-style:normal'>Table</i>, we need to use <i
+style='mso-bidi-font-style:normal'>TableColumn</i> and <i style='mso-bidi-font-style:
+normal'>TableItem</i> classes</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l2 level1 lfo4;
+tab-stops:list .25in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]>Use <i
+style='mso-bidi-font-style:normal'>TableColumn</i> class directly – we do not
+need to wrap it</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l2 level1 lfo4;
+tab-stops:list .25in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]>Wrap <i
+style='mso-bidi-font-style:normal'>TableItem</i> to store the expanded state
+and to enforce the column 0 restrictions</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l2 level1 lfo4;
+tab-stops:list .25in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]>Implement
+some of the <i style='mso-bidi-font-style:normal'>Tree</i> and <i
+style='mso-bidi-font-style:normal'>TreeItem</i> API methods that make sense for
+<i style='mso-bidi-font-style:normal'>TableTree</i> and <i style='mso-bidi-font-style:
+normal'>TableTreeItem</i></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l2 level1 lfo4;
+tab-stops:list .25in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]>Expose
+the fact that we are wrapping a <i style='mso-bidi-font-style:normal'>Table</i>
+by providing a <b style='mso-bidi-font-weight:normal'>getTable()</b> method on <i
+style='mso-bidi-font-style:normal'>TableTree</i>. This simplifies our
+implementation significantly because the user can create columns and show
+headers and grid lines by going directly to the <i style='mso-bidi-font-style:
+normal'>Table</i>.</p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l2 level1 lfo4;
+tab-stops:list .25in'><![if !supportLists]><span style='font-family:Symbol'>·<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]>Reimplement
+common API methods like <b style='mso-bidi-font-weight:normal'>setFont</b> for
+convenience</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'>The following page
+shows an example three-column <i style='mso-bidi-font-style:normal'>TableTree</i>,
+and the application code that created it. The full source listing for <i
+style='mso-bidi-font-style:normal'>TableTree</i> and <i style='mso-bidi-font-style:
+normal'>TableTreeItem</i> is in <a
+href="Writing%20Your%20Own%20Widget_files/AppendixA.htm">Appendix A: TableTree
+and TableTreeItem</a>.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><!--[if gte vml 1]><o:wrapblock><v:shape
+ id="_x0000_s1027" type="#_x0000_t75" style='position:absolute;left:0;
+ text-align:left;margin-left:0;margin-top:0;width:246pt;height:170.25pt;
+ z-index:1;mso-position-horizontal-relative:text;
+ mso-position-vertical-relative:text' o:allowincell="f">
+ <v:imagedata src="./Writing%20Your%20Own%20Widget_files/image005.png"
+ o:title=""/>
+ <w:wrap type="topAndBottom" anchorx="page"/>
+ </v:shape><![endif]--><![if !vml]><img width=328 height=227
+ src="./Writing%20Your%20Own%20Widget_files/image006.jpg" v:shapes="_x0000_s1027"><![endif]><!--[if gte vml 1]></o:wrapblock><![endif]--><br
+style='mso-ignore:vglayout' clear=ALL>
+<![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<br style='mso-ignore:vglayout' clear=ALL>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><b
+style='mso-bidi-font-weight:normal'>A TableTree in a Shell<o:p></o:p></b></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>public</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>static</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>void</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+main(String [] args) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>Shell shell = </span><span style='font-size:
+9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+Shell();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>Image image = </span><span style='font-size:
+9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+Image(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:
+line'>null</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black;
+layout-grid-mode:line'>, 20, 20);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>Color red = </span><span style='font-size:
+9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+Color(</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:
+line'>null</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;
+font-family:"Courier New";mso-bidi-font-family:"Times New Roman";color:black;
+layout-grid-mode:line'>, 255, 0, 0);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>GC gc = </span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>new</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> GC(image);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>gc.setBackground(red);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>gc.fillRectangle(image.getBounds());<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>gc.dispose();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>red.dispose();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>TableTree tableTree = </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+TableTree(shell, SWT.BORDER);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>tableTree.setSize(320, 200);</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:maroon;layout-grid-mode:line'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>Table table = tableTree.getTable();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>table.setHeaderVisible(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>true</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>table.setLinesVisible(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>true</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>for</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>int</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> col = 0; col &lt; 3; col++) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>TableColumn column = </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> TableColumn(table,
+SWT.NONE, col);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>column.setText(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>&quot;Column
+&quot;</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:
+line'> + col);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>column.setWidth(100);</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:maroon;layout-grid-mode:line'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>for</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>int</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> iRoot = 0; iRoot &lt; 8; iRoot++) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>TableTreeItem root = </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+TableTreeItem(tableTree, SWT.NONE);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>root.setText(</span><span style='font-size:
+9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:
+"Times New Roman";color:teal;layout-grid-mode:line'>&quot;Root &quot;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> +
+iRoot);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>for</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>int</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> iBranch = 0; iBranch &lt; 4; iBranch++) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span>TableTreeItem branch = </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+TableTreeItem(root, SWT.NONE);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span>branch.setText(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>&quot;Branch
+&quot;</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:
+line'> + iBranch);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>for</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>int</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> col = 1; col &lt; 3; col++) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span>branch.setImage(col, image);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span>branch.setText(col, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>&quot;R&quot;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>+iRoot+</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>&quot;B&quot;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>+iBranch+</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>&quot;C&quot;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>+col);</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>for</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>int</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> iLeaf = 0; iLeaf &lt; 4; iLeaf++) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span>TableTreeItem leaf = </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+TableTreeItem(branch, SWT.NONE);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span>leaf.setText(</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>&quot;Leaf
+&quot;</span><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
+"Courier New";mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:
+line'> + iLeaf);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>for</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>int</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> col = 1; col &lt; 3; col++) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:5'>                </span>leaf.setImage(col, image);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:5'>                </span>leaf.setText(col, </span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>&quot;R&quot;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>+iRoot+</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>&quot;B&quot;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>+iBranch+</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>&quot;L&quot;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>+iLeaf+</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:teal;layout-grid-mode:line'>C&quot;</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>+col);<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:4'>            </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:3'>         </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>shell.pack(); shell.open();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>Display display = shell.getDisplay();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>while</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (!shell.isDisposed()) {<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:2'>     </span></span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>if</span><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'> (!display.readAndDispatch())
+display.sleep();<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>}<o:p></o:p></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<h3 style='margin-left:25.5pt'><a name="_Toc506634635"></a><a
+name="_Toc496069428"></a><a name="_Toc496069785"><span style='mso-bookmark:
+_Toc496069428'><span style='mso-bookmark:_Toc506634635'>Subclassing Widgets
+Directly</span></span></a></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt;mso-list:skip'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>In extreme
+circumstances, you may need to subclass a widget other than <i
+style='mso-bidi-font-style:normal'>Canvas</i> or <i style='mso-bidi-font-style:
+normal'>Composite</i>. We recommend against doing this unless all other avenues
+have been explored and exhausted. Try to wrap the widget first, before
+subclassing it. Here is why:</span></span></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Subclasses may inherit a lot of API that makes no
+sense, and must be overridden. In Java, you cannot override a method and change
+the return type; therefore you cannot reimplement some methods.</span></span></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Subclassing is typically not the safest way to extend a
+class that you do not own. For a simplified list of the common arguments, see
+the article by <strong><span style='font-weight:normal'>Bill Venners </span></strong>in
+the Nov '98 issue of <i style='mso-bidi-font-style:normal'>Java World</i>
+called <i style='mso-bidi-font-style:normal'>“Inheritance versus composition:
+Which one should you choose?”</i> at: </span></span><a
+href="http://www.javaworld.com/javaworld/jw-11-1998/jw-11-techniques.html"><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>http://www.javaworld.com/javaworld/jw-11-1998/jw-11-techniques.html</span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'></span></span></a><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'></span></span></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Widget subclasses are almost certainly guaranteed to be
+platform-specific unless great care is taken to ensure that they work on all
+platforms.</span></span></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Subclassed widgets can be affected by changes in the
+non-API implementation of the superclass.</span></span></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Subclassing may cause bad system-level bugs, and runs
+the risk of leaking resources. For example, if a subclass reimplements a method
+without making certain that dispose code from the superclass method is still
+called, then the new method will leak system resources.</span></span></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>Binary incompatibility across releases becomes
+possible. If a method signature or field name changes, or new methods or fields
+are added, there may be a name conflict in the widget subclass. Only <i
+style='mso-bidi-font-style:normal'>Canvas</i> and <i style='mso-bidi-font-style:
+normal'>Composite </i>are guaranteed not to have name conflicts in future
+releases.</span></span></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l0 level1 lfo2'><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportLists]><span
+style='font-family:Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span><![endif]>See any paper by Leonid <span style='color:black'>Mikhajlov
+on the <i style='mso-bidi-font-style:normal'>“Fragile Base Class Problem”</i>.
+He has a summary of this problem on his web page at: </span></span></span><a
+href="http://www.abo.fi/~lmikhajl/"><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>http://www.abo.fi/~lmikhajl/</span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'></span></span></a><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Consider the example of <i style='mso-bidi-font-style:
+normal'>TableTree</i>. We chose to wrap <i style='mso-bidi-font-style:normal'>Table</i>
+rather than subclass it. The best test is to ask whether a <i style='mso-bidi-font-style:
+normal'>TableTree</i> ‘is-a’ <i style='mso-bidi-font-style:normal'>Table</i>.
+The answer is definitely not – we have simply chosen to implement <i
+style='mso-bidi-font-style:normal'>TableTree</i> using <i style='mso-bidi-font-style:
+normal'>Table</i>. We cannot talk about the ‘rows’ of a <i style='mso-bidi-font-style:
+normal'>TableTree</i>, or index into a <i style='mso-bidi-font-style:normal'>TableTree</i>;
+and the first column of the <i style='mso-bidi-font-style:normal'>Table</i> is
+reserved for the ‘tree’. Many of the operations for a <i style='mso-bidi-font-style:
+normal'>Table</i> do not make sense for a <i style='mso-bidi-font-style:normal'>TableTree</i>,
+for example <b style='mso-bidi-font-weight:normal'>getSelectionIndex()</b> and <b
+style='mso-bidi-font-weight:normal'>getTopIndex()</b>.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Subclassing <i style='mso-bidi-font-style:
+normal'>Canvas</i> or <i style='mso-bidi-font-style:normal'>Composite</i> is
+the best way to ensure that your widget works on all SWT platforms. The ‘is-a’
+test in this case tests whether your widget is-a basic or compound widget.
+Subclassing anything else requires asking if the new widget<b style='mso-bidi-font-weight:
+normal'> is-an SWT native widget of the type being subclassed</b>. For example,
+a 100% Java portable <i style='mso-bidi-font-style:normal'>PictureLabel</i> is
+not an SWT native <i style='mso-bidi-font-style:normal'>Label</i>.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>When subclassing anything other than <i
+style='mso-bidi-font-style:normal'>Composite</i> or <i style='mso-bidi-font-style:
+normal'>Canvas</i> you must override the method <b style='mso-bidi-font-weight:
+normal'>protected void checkSubclass()</b> to do nothing. Make sure you read
+the method comment before overriding it.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><b style='mso-bidi-font-weight:normal'><span
+style='font-size:14.0pt;mso-bidi-font-size:10.0pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></b></span></span></p>
+
+<h3 style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><a name="_Toc506634636">Wrapping a Native
+Widget</a></span></span></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Sometimes, an application requires a native
+widget that is not provided by SWT. This may be a platform widget, or a third
+party widget, or any other widget in a shared library. In this section, we will
+describe how to interface to a native widget on the Windows and Motif
+platforms. This section assumes that you have some understanding of the <i
+style='mso-bidi-font-style:normal'>Java Native Interface</i>, or <b
+style='mso-bidi-font-weight:normal'>JNI</b>. Two good books on JNI are:</span></span></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .25in'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportLists]><span style='font-family:
+Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]><i
+style='mso-bidi-font-style:normal'>“The Java Native Interface, Programmer’s
+Guide and Specification”</i> by Sheng Liang</span></span></p>
+
+<p class=MsoNormal style='margin-left:43.5pt;text-indent:-.25in;mso-list:l1 level1 lfo6;
+tab-stops:list .25in'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportLists]><span style='font-family:
+Symbol'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp; </span></span><![endif]><i
+style='mso-bidi-font-style:normal'>“Essential JNI, Java Native Interface”</i>
+by Rob Gordon</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>This section also assumes that you have done
+some platform programming before, and are proficient in C and in the use of
+makefiles. You must have platform documentation available, such as the MSDN
+Library on Windows, and Motif 2.1 documentation or ‘man pages’ for your Motif
+Unix/Linux system. If you are programming to a third party widget, you will
+need to know its API.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>In this section, we will create a shared
+library and load it using:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>System.loadLibrary(<span
+style='color:teal'>&quot;mywidget&quot;</span>);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>On Windows, this loads a Dynamic Link
+Library or DLL file called “mywidget.dll”.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>On Motif, this loads a Shared Object Library
+or SO file called “libmywidget.so”.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>For our example, we will be building a
+widget we will call <i style='mso-bidi-font-style:normal'>Spinner</i>. On
+Windows, the native widget we will use is called an <i style='mso-bidi-font-style:
+normal'>UpDown</i> control, and on Motif we will be using an <i
+style='mso-bidi-font-style:normal'>XmSimpleSpinBox</i>. They look like this:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><!--[if gte vml 1]><o:wrapblock><v:shape
+ id="_x0000_s1032" type="#_x0000_t75" style='position:absolute;left:0;
+ text-align:left;margin-left:59.55pt;margin-top:0;width:134.25pt;height:44.25pt;
+ z-index:2;mso-position-horizontal:absolute;
+ mso-position-horizontal-relative:text;mso-position-vertical:top;
+ mso-position-vertical-relative:text'>
+ <v:imagedata src="./Writing%20Your%20Own%20Widget_files/image007.png"
+ o:title=""/>
+ <w:wrap type="topAndBottom" anchorx="page"/>
+ </v:shape><![if gte mso 9]><o:OLEObject Type="Embed" ProgID="PBrush"
+ ShapeID="_x0000_s1032" DrawAspect="Content" ObjectID="_1053168692">
+ </o:OLEObject>
+ <![endif]><![endif]--><![if !vml]><span style='mso-ignore:vglayout'>
+ <table cellpadding=0 cellspacing=0 align=left>
+ <tr>
+ <td width=79 height=0></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img width=179 height=59
+ src="./Writing%20Your%20Own%20Widget_files/image008.jpg" v:shapes="_x0000_s1032"></td>
+ </tr>
+ </table>
+ </span><![endif]><!--[if gte vml 1]></o:wrapblock><![endif]--><br
+style='mso-ignore:vglayout' clear=ALL>
+<span style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span><p></p>
+
+<br style='mso-ignore:vglayout' clear=ALL>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Our <i style='mso-bidi-font-style:normal'>Spinner</i>
+will be numeric, and we want to be able to set and get the maximum and minimum
+value, as well as the current value (which we will call the ‘selection’, to
+conform to SWT convention). We also want to be able to set the font. When the
+user clicks on one of the arrows, we want to notify listeners that the
+selection has changed, so we will need to implement a selection listener. The
+test code for our widget looks something like this (the full source listing for
+class <i style='mso-bidi-font-style:normal'>SpinnerTest</i> is in </span></span><a
+href="Writing%20Your%20Own%20Widget_files/AppendixB.htm"><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>Appendix
+B: SpinnerTest and Spinner</span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'></span></span></a><span style='mso-bookmark:
+_Toc496069785'><span style='mso-bookmark:_Toc496069428'>):</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:1'>  </span></span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>final</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+Spinner spinner = </span></span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>new</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+Spinner(shell, 0);<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:1'>  </span>spinner.setMaximum(999);<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:1'>  </span>spinner.setSelection(500);<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:1'>  </span>spinner.setMinimum(100);<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:1'>  </span>Font
+font = </span></span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:navy;layout-grid-mode:line'>new</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+Font(display, </span></span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:teal;layout-grid-mode:line'>&quot;Courier&quot;</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>, 20,
+SWT.NORMAL);<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:1'>  </span>spinner.setFont(font);<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:1'>  </span>spinner.addSelectionListener(</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>new</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+SelectionAdapter() {<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:2'>         </span></span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>public</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'> </span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:navy;layout-grid-mode:line'>void</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:black;layout-grid-mode:line'>
+widgetSelected(SelectionEvent e) {<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:3'>                </span>System.out.println(spinner.getSelection());<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:2'>         </span>}<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><span style='mso-tab-count:1'>  </span>});<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The next step is to write the API in Java. Since
+we know we will be writing the native interface file (we’ll call it
+“spinner.c”) twice – once on Windows and once on Motif – we try to write the
+Java code only once so that it is easier to maintain. We start by creating a
+subclass of <i style='mso-bidi-font-style:normal'>Composite</i>, and we load
+the shared library in a static initializer:</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:1'>  </span></span>static<span style='color:black'> {<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:2'>     </span>System.loadLibrary(</span><span
+style='color:teal'>&quot;spinner&quot;</span><span style='color:black'>);<span
+style='mso-tab-count:1'> </span><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>This will load a file called “spinner.dll”
+on Windows, and “libspinner.so” on Motif. Since we know that creating a widget
+returns a ‘handle’ on both platforms, we define an instance variable to hold
+the handle:</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>int</span> handleSpinner;</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:9.0pt;mso-bidi-font-size:
+10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+color:black;layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Since we will be providing a listener, we
+know that we will need to map this handle back to the Java <i style='mso-bidi-font-style:
+normal'>Spinner</i> object when the platform calls in to Java to notify us of
+the event. So we create a static <i style='mso-bidi-font-style:normal'>Hashtable</i>
+that will contain <i style='mso-bidi-font-style:normal'>Spinner</i> handles as
+keys and <i style='mso-bidi-font-style:normal'>Spinner</i> objects as values: </span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> Hashtable table = <span style='color:navy'>new</span>
+Hashtable();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Now we write the constructor. We add the
+handle to the table after the widget is created, and we remove it when the
+widget is destroyed. Note that we don’t create the widget in Java. We will
+create it later, in the native <b style='mso-bidi-font-weight:normal'>createControl</b>
+method. We also forward all <b style='mso-bidi-font-weight:normal'>controlResized</b>
+and <b style='mso-bidi-font-weight:normal'>focusGained</b> events to the native
+<b style='mso-bidi-font-weight:normal'>resizeControl</b> and <b
+style='mso-bidi-font-weight:normal'>setFocus</b> methods, and set our font to
+the default font using the native <b style='mso-bidi-font-weight:normal'>setFont</b>
+method. There is one more thing to explain in the constructor. You may notice
+that we are actually creating two widgets: a <i style='mso-bidi-font-style:
+normal'>Composite</i> parent named <b style='mso-bidi-font-weight:normal'>handle</b>
+in the call to super, and a <i style='mso-bidi-font-style:normal'>Spinner</i>
+child named <b style='mso-bidi-font-weight:normal'>handleSpinner</b> in the
+call to <b style='mso-bidi-font-weight:normal'>createControl</b>. This wraps
+the native control in an SWT parent, allowing it to participate in the SWT
+system.</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> Spinner(Composite parent, <span
+style='color:navy'>int</span> style) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>super</span>(parent, style);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>int</span> handleParent = handle;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='mso-tab-count:1'>   </span>handleSpinner = createControl(handleParent);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>if</span> (handleSpinner == 0)
+SWT.error(SWT.ERROR_NO_HANDLES);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>table.put(<span
+style='color:navy'>new</span> Integer(handleSpinner), <span style='color:navy'>this</span>);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>addDisposeListener(<span
+style='color:navy'>new</span> DisposeListener() {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+widgetDisposed(DisposeEvent e) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>            </span>Spinner.<span
+style='color:navy'>this</span>.widgetDisposed(e);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>});</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>addControlListener(<span
+style='color:navy'>new</span> ControlAdapter() {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+controlResized(ControlEvent e) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>            </span>Spinner.<span
+style='color:navy'>this</span>.controlResized(e);<span style='mso-tab-count:
+3'>          </span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>});</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>addFocusListener(<span
+style='color:navy'>new</span> FocusAdapter() {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+focusGained(FocusEvent e) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>            </span>Spinner.<span
+style='color:navy'>this</span>.focusGained(e);<span style='mso-tab-count:3'>          </span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>});</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>Font
+font = getFont();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>setFont(handleSpinner,
+font.handle);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span><span style='color:black'> </span><span
+style='color:navy'>void</span><span style='color:black'>
+widgetDisposed(DisposeEvent e) {<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:2'>     </span>table.remove(</span><span style='color:
+navy'>new</span> Integer(handleSpinner)<span style='color:black'>);<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:2'>     </span>handleSpinner = 0;<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:1'>  </span><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:1'>  </span></span><span style='color:navy'>public</span><span
+style='color:black'> </span><span style='color:navy'>void</span><span
+style='color:black'> controlResized(ControlEvent e) {<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:2'>     </span>Rectangle rect = getClientArea();<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:2'>     </span>resizeControl(handleSpinner, rect.x,
+rect.y, rect.width, rect.height);<span style='mso-tab-count:2'>         </span><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:black'><span
+style='mso-tab-count:1'>  </span>}<o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+focusGained(FocusEvent e) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>setFocus(handleSpinner);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='color:navy'><span
+style='mso-tab-count:1'>  </span>static</span> <span style='color:navy'>final</span>
+<span style='color:navy'>native</span> <span style='color:navy'>int</span> createControl(<span
+style='color:navy'>int</span> handleParent);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+resizeControl(<span style='color:navy'>int</span> handle, <span
+style='color:navy'>int</span> x, <span style='color:navy'>int</span> y, <span
+style='color:navy'>int</span> width, <span style='color:navy'>int</span>
+height);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span> setFocus(<span
+style='color:navy'>int</span> handle);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>We write the <b style='mso-bidi-font-weight:
+normal'>setFont</b> API method to call the native <b style='mso-bidi-font-weight:
+normal'>setFont</b> method with the <i style='mso-bidi-font-style:normal'>Spinner</i>
+handle and the font handle. Call <b style='mso-bidi-font-weight:normal'>super.setFont</b>
+because some superclasses need to set fonts for things like titles – it will
+not actually be needed in this case, but by convention widgets usually inform
+their superclass of font and color changes.</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+setFont(Font font) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>super</span>.setFont(font);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>int</span> hFont = 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>if</span> (font != <span style='color:navy'>null</span>)
+hFont = font.handle;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>setFont(handleSpinner,
+hFont);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span> setFont(<span
+style='color:navy'>int</span> handle, <span style='color:navy'>int</span>
+hFont);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>In a similar manner, we write the remaining
+set and get API methods and declare the corresponding native methods. The <b
+style='mso-bidi-font-weight:normal'>checkWidget</b> method simply checks that
+the widget is still valid.</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+setSelection(<span style='color:navy'>int</span> selection) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>checkWidget();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>setPosition(handleSpinner,
+selection);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> <span style='color:navy'>int</span> getSelection()
+{</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>checkWidget();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>return</span> getPosition(handleSpinner);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+setMaximum(<span style='color:navy'>int</span> maximum) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>checkWidget();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>setMaximum(handleSpinner,
+maximum);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> <span style='color:navy'>int</span>
+getMaximum() {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>checkWidget();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>return</span> getMaximum(handleSpinner);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+setMinimum(<span style='color:navy'>int</span> minimum) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>checkWidget();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>setMinimum(handleSpinner,
+minimum);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> <span style='color:navy'>int</span>
+getMinimum() {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>checkWidget();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>return</span> getMinimum(handleSpinner);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+setPosition(<span style='color:navy'>int</span> handle, <span style='color:
+navy'>int</span> position);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>int</span>
+getPosition(<span style='color:navy'>int</span> handle);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+setMaximum(<span style='color:navy'>int</span> handle, <span style='color:navy'>int</span>
+max);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>int</span>
+getMaximum(<span style='color:navy'>int</span> handle);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+setMinimum(<span style='color:navy'>int</span> handle, <span style='color:navy'>int</span>
+min);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>int</span>
+getMinimum(<span style='color:navy'>int</span> handle);</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>As with all widgets we implement, we need to
+provide a <b style='mso-bidi-font-weight:normal'>computeSize</b> method to
+compute the preferred size of the widget. This one also forwards to a native to
+do the work. In this case, the native needs to return two integers (width and
+height) so we use an int array of size 2 to hold the returned values:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> Point computeSize(<span style='color:navy'>int</span>
+wHint, <span style='color:navy'>int</span> hHint, <span style='color:navy'>boolean</span>
+changed) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>checkWidget();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>int</span> [] result = <span style='color:navy'>new</span> <span
+style='color:navy'>int</span> [2];</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>computeSize(handleSpinner,
+result);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>if</span> (wHint != SWT.DEFAULT) result [0] = wHint;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>if</span> (hHint != SWT.DEFAULT) result [1] = hHint;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>int</span> border = getBorderWidth();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>return</span> <span style='color:navy'>new</span>
+Point(result [0] + border * 2, result [1] + border * 2);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+computeSize(<span style='color:navy'>int</span> handle, <span style='color:
+navy'>int</span> [] result);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Finally, we need to define the listener
+interface. The <b style='mso-bidi-font-weight:normal'>addSelectionListener</b>
+method simply adds an <b style='mso-bidi-font-weight:normal'>SWT.Selection</b>
+listener using the SWT low-level listener mechanism. The <b style='mso-bidi-font-weight:
+normal'>widgetSelected</b> method is special. It is the entry point into Java
+when the event occurs. In other words, we will be calling this method from C.
+When the method is called, it determines the <i style='mso-bidi-font-style:
+normal'>Spinner</i> for the event by looking in the table, and then forwards to
+the SWT event mechanism by calling <b style='mso-bidi-font-weight:normal'>notifyListeners</b>.</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>public</span> <span style='color:navy'>void</span>
+addSelectionListener(SelectionListener listener) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>if</span> (listener == <span style='color:navy'>null</span>)
+<span style='color:navy'>throw</span> <span style='color:navy'>new</span>
+SWTError(SWT.ERROR_NULL_ARGUMENT);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>addListener(SWT.Selection,
+<span style='color:navy'>new</span> TypedListener(listener));</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>void</span>
+widgetSelected(<span style='color:navy'>int</span> handle) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>Spinner
+spinner = (Spinner) table.get(<span style='color:navy'>new</span>
+Integer(handle));</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style='color:navy'>if</span> (spinner == <span style='color:navy'>null</span>) <span
+style='color:navy'>return</span>;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>spinner.notifyListeners(SWT.Selection,
+<span style='color:navy'>new</span> Event());</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Notice that the <i style='mso-bidi-font-style:
+normal'>Event</i> object that we create for the <i style='mso-bidi-font-style:
+normal'>Spinner</i> selection listener does not need to have any fields set. If
+you need to return more information for your event, such as the x and y
+coordinates of the event or the key that was pressed, then your call-in method
+(<b style='mso-bidi-font-weight:normal'>widgetSelected</b>, in this case) will
+have to have more parameters than just the handle.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>One more thing to note before we write the C
+code. All of our native methods have been defined as static methods, and all of
+them have the handle passed as the first parameter. This consistency makes it
+easier to write the C native code.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The full source code listing for the Java <i
+style='mso-bidi-font-style:normal'>Spinner</i> class is in in </span></span><a
+href="Writing%20Your%20Own%20Widget_files/AppendixB.htm"><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>Appendix
+B: SpinnerTest and Spinner</span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'></span></span></a><span style='mso-bookmark:
+_Toc496069785'><span style='mso-bookmark:_Toc496069428'>. Now we need to write
+the native interface methods in C. First we will write the native interface for
+Windows, and then we will write it for Motif.</span></span></p>
+
+<h3 style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><a name="_Toc506634637">Windows Native Code</a></span></span></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Now we really get into JNI and platform
+programming. We will write a C file called “spinner.c”. It needs to implement
+the following Java methods from class spinner.<i style='mso-bidi-font-style:
+normal'>Spinner</i>:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>int</span>
+createControl(<span style='color:navy'>int</span> handleParent);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+computeSize(<span style='color:navy'>int</span> handle, <span style='color:
+navy'>int</span> [] result);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+resizeControl(<span style='color:navy'>int</span> handle, <span
+style='color:navy'>int</span> x, <span style='color:navy'>int</span> y, <span
+style='color:navy'>int</span> width, <span style='color:navy'>int</span>
+height);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+setPosition(<span style='color:navy'>int</span> handle, <span style='color:
+navy'>int</span> position);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>int</span>
+getPosition(<span style='color:navy'>int</span> handle);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+setMaximum(<span style='color:navy'>int</span> handle, <span style='color:navy'>int</span>
+max);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>int</span>
+getMaximum(<span style='color:navy'>int</span> handle);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span>
+setMinimum(<span style='color:navy'>int</span> handle, <span style='color:navy'>int</span>
+min);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>int</span>
+getMinimum(<span style='color:navy'>int</span> handle);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span> setFont(<span
+style='color:navy'>int</span> handle, <span style='color:navy'>int</span>
+hFont);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>final</span> <span
+style='color:navy'>native</span> <span style='color:navy'>void</span> setFocus(<span
+style='color:navy'>int</span> handle);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>It also needs to call in to the following
+Java method when the selection changes:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style='color:navy'>static</span> <span style='color:navy'>void</span>
+widgetSelected(<span style='color:navy'>int</span> handle);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The first thing we need to do is to include
+at least these three files. Your control may require additional files.</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>#include &lt;jni.h&gt;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>#include &lt;windows.h&gt;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>#include &lt;commctrl.h&gt;</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>We will start with the <b style='mso-bidi-font-weight:
+normal'>createControl</b> method. Recall that we decided to use a Windows <i
+style='mso-bidi-font-style:normal'>UpDown</i> control. If we create an <i
+style='mso-bidi-font-style:normal'>Edit</i> control first, and then create the <i
+style='mso-bidi-font-style:normal'>UpDown</i> control with </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt;layout-grid-mode:line'>UDS_AUTOBUDDY
+</span><span style='layout-grid-mode:line'>and</span></span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt;layout-grid-mode:line'>
+UDS_SETBUDDYINT</span><span style='layout-grid-mode:line'> flags set, then the <i
+style='mso-bidi-font-style:normal'>Edit</i> control will automatically be
+associated with the <i style='mso-bidi-font-style:normal'>UpDown</i> control’s
+arrows. We can retrieve the <i style='mso-bidi-font-style:normal'>Edit</i> control
+by sending </span></span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:11.0pt;mso-bidi-font-size:
+10.0pt;layout-grid-mode:line'>UDM_GETBUDDY</span><span style='layout-grid-mode:
+line'> to the <i style='mso-bidi-font-style:normal'>UpDown </i>control. We will
+show you the complete <b style='mso-bidi-font-weight:normal'>createControl</b>
+method after we explain how to call in to Java.<o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><b style='mso-bidi-font-weight:normal'><span
+style='layout-grid-mode:line'>Calling in to Java:<o:p></o:p></span></b></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The first time we ever call <b
+style='mso-bidi-font-weight:normal'>createControl</b>, we initialize some
+static variables:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>static DWORD tlsIndex = 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>static jobject javaClass;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>static jmethodID mid;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>static WNDPROC oldProc;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>We use one of them (<b style='mso-bidi-font-weight:
+normal'>tlsIndex</b>) as a flag to make sure we initialize them only once. Here
+is the initialization code from <b style='mso-bidi-font-weight:normal'>createControl</b>:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>if
+(tlsIndex == 0) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>tlsIndex
+= TlsAlloc();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>if
+(tlsIndex == -1) return (jint) 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>javaClass
+= (*env)-&gt;NewGlobalRef(env, (jobject) that);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>mid
+= (*env)-&gt;GetStaticMethodID(env, (jobject) that, &quot;widgetSelected&quot;,
+&quot;(I)V&quot;);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>oldProc
+= (WNDPROC) GetWindowLong((HWND) hwndParent, GWL_WNDPROC);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>TlsSetValue(tlsIndex,
+(LPVOID) env);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>These variables are needed to implement
+call-in. As this is important code, we will describe each variable that is
+initialized:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>tlsIndex
+= TlsAlloc();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>if
+(tlsIndex == -1) return (jint) 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>…</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>TlsSetValue(tlsIndex,
+(LPVOID) env);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Here, we allocate a Windows <i
+style='mso-bidi-font-style:normal'>Thread Local Storage</i> (TLS) index, and
+then (for each <i style='mso-bidi-font-style:normal'>Spinner</i>) we use the
+TLS index to store a pointer called <b style='mso-bidi-font-weight:normal'>env</b>.
+Notice that <b style='mso-bidi-font-weight:normal'>JNIEnv *env</b> is the first
+parameter passed to every JNI method. It is a pointer to a function table, and
+it is only valid in the thread associated with it. We know that we need to call
+in to Java when the user changes the <i style='mso-bidi-font-style:normal'>Spinner</i>
+value, and that we will be calling in from a Windows ‘window procedure’ or </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>WNDPROC</span>. The </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>WNDPROC</span> does not know
+about the Java environment. When the </span></span><span style='mso-bookmark:
+_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span style='font-size:
+11.0pt;mso-bidi-font-size:10.0pt'>WNDPROC</span> is invoked, we will need
+‘env’. So we have to save it on creation so that we have it when we need to
+call in. We also need the class and method ID to call in to, and we can store
+these in statics because they will be the same across all threads:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>javaClass
+= (*env)-&gt;NewGlobalRef(env, (jobject) that);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>mid
+= (*env)-&gt;GetStaticMethodID(env, (jobject) that, &quot;widgetSelected&quot;,
+&quot;(I)V&quot;);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>When the user changes the <i
+style='mso-bidi-font-style:normal'>Spinner</i> value, the <i style='mso-bidi-font-style:
+normal'>UpDown</i> sends a </span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:11.0pt;mso-bidi-font-size:
+10.0pt'>WM_VSCROLL</span> to its parent control.<span style="mso-spacerun:
+yes">  </span>In order to see this message, it is necessary to “subclass the
+window proc” of the parent.<span style="mso-spacerun: yes">  </span>In Windows,
+this means replacing the window proc of the parent with our own window
+proc.<span style="mso-spacerun: yes">  </span>The new </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>WNDPROC</span> will look for
+</span></span><span style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:
+_Toc496069428'><span style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>WM_VSCROLL</span>
+(in order to notify the Java code that the <i style='mso-bidi-font-style:normal'>Spinner</i>
+value has been changed) and then call the previous </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>WNDPROC</span> to handle
+other messages that our control is not interested in.<span style="mso-spacerun:
+yes">  </span>Note that it is important to call the previous </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>WNDPROC</span>, or the
+parent window will not behave properly (i.e. it will not paint or resize, etc.)
+We store the previous </span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:11.0pt;mso-bidi-font-size:
+10.0pt'>WNDPROC</span> in oldProc:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>oldProc
+= (WNDPROC) GetWindowLong((HWND) hwndParent, GWL_WNDPROC);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The last line in <b style='mso-bidi-font-weight:
+normal'>createControl</b> before we return the new handle installs a </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>WNDPROC</span> called <b
+style='mso-bidi-font-weight:normal'>WindowProc</b>:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>SetWindowLong((HWND)
+hwndParent, GWL_WNDPROC, (long) WindowProc);</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Here is the code for our <b
+style='mso-bidi-font-weight:normal'>WindowProc</b>. First we retrieve <b
+style='mso-bidi-font-weight:normal'>env</b> from Thread Local Storage and check
+if an exception has occurred. Then we see if this is an “<i style='mso-bidi-font-style:
+normal'>UpDown</i> value changed” event (a </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>WM_VSCROLL<span
+style='layout-grid-mode:line'> message with SB_THUMBPOSITION</span></span> in
+the low order bits of <b style='mso-bidi-font-weight:normal'>wParam</b>). If it
+is, we use <b style='mso-bidi-font-weight:normal'>env</b> to call in to the
+Java static method called “widgetSelected”, passing <b style='mso-bidi-font-weight:
+normal'>lParam</b> as the handle of the <i style='mso-bidi-font-style:normal'>UpDown</i>
+control. Otherwise, we just forward to the parent control’s window procedure.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>LRESULT CALLBACK WindowProc(HWND hwnd, UINT
+msg, WPARAM wParam, LPARAM lParam) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>JNIEnv
+*env = TlsGetValue(tlsIndex);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>if
+(env != NULL) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>/*
+If an exception has already occurred,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style="mso-spacerun: yes"> </span>* allow the stack to unwind so that the</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span><span
+style="mso-spacerun: yes"> </span>* exception will be thrown in Java. */</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>if
+((*env)-&gt;ExceptionOccurred(env)) return 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>switch
+(msg) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span>case
+WM_VSCROLL:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>            </span>if
+((wParam &amp; 0xFFFF) == SB_THUMBPOSITION) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:5'>                </span>return
+(LRESULT) ((*env)-&gt;CallStaticIntMethod(env, javaClass, mid, lParam));</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>            </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:4'>            </span>break;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>return
+CallWindowProc(oldProc, hwnd, msg, wParam, lParam);<span style='mso-tab-count:
+1'> </span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>And finally, here is the code for <b
+style='mso-bidi-font-weight:normal'>createControl</b>:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>JNIEXPORT jint JNICALL
+Java_spinner_Spinner_createControl</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style="mso-spacerun: yes"> 
+</span>(JNIEnv *env, jclass that, jint hwndParent)</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>{</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>HWND
+hwndText, hwndUpDown;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>if
+(tlsIndex == 0) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>tlsIndex
+= TlsAlloc();</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>if
+(tlsIndex == -1) return (jint) 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>javaClass
+= (*env)-&gt;NewGlobalRef(env, (jobject) that);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>mid
+= (*env)-&gt;GetStaticMethodID(env, (jobject) that, &quot;widgetSelected&quot;,
+&quot;(I)V&quot;);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>oldProc
+= (WNDPROC) GetWindowLong((HWND) hwndParent, GWL_WNDPROC);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>TlsSetValue(tlsIndex,
+(LPVOID) env);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>hwndText
+= CreateWindowEx(</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>WS_EX_CLIENTEDGE,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>&quot;EDIT&quot;,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>NULL,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>WS_CHILD
+| WS_VISIBLE | WS_TABSTOP,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>0,
+0, 0, 0,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>(HWND)
+hwndParent,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>0,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>GetModuleHandle(NULL),</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>NULL);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>if
+(hwndText == 0) return (jint) 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>hwndUpDown
+= CreateWindowEx(</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>0,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>UPDOWN_CLASS,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>NULL,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>WS_CHILD
+| WS_VISIBLE | UDS_AUTOBUDDY | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS
+| UDS_NOTHOUSANDS,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>0,
+0, 0, 0,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>(HWND)
+hwndParent,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>0,</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>GetModuleHandle(NULL),</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>NULL);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>if
+(hwndUpDown == 0) return (jint) 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>SetWindowLong((HWND)
+hwndParent, GWL_WNDPROC, (long) WindowProc);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>return
+(jint) hwndUpDown;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The set and get methods we need to implement
+are much simpler than the <b style='mso-bidi-font-weight:normal'>createControl</b>
+and <b style='mso-bidi-font-weight:normal'>WindowProc</b> methods. Here are <b
+style='mso-bidi-font-weight:normal'>setPosition</b> and <b style='mso-bidi-font-weight:
+normal'>getPosition</b>. They simply send the </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>UDM_SETPOS</span> or </span></span><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><span
+style='font-size:11.0pt;mso-bidi-font-size:10.0pt'>UDM_GETPOS</span> message to
+the <i style='mso-bidi-font-style:normal'>UpDown</i> handle. The remaining set and
+get methods are similar, and they are listed in </span></span><a
+href="Writing%20Your%20Own%20Widget_files/AppendixC.htm"><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>Appendix
+C: Spinner for Windows</span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'></span></span></a><span style='mso-bookmark:
+_Toc496069785'><span style='mso-bookmark:_Toc496069428'>. The only interesting
+one is <b style='mso-bidi-font-weight:normal'>setFont</b>, which sets the font
+of the <i style='mso-bidi-font-style:normal'>Edit</i> control, which it gets by
+sending </span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='font-size:11.0pt;mso-bidi-font-size:
+10.0pt'>UDM_GETBUDDY</span> to the <i style='mso-bidi-font-style:normal'>UpDown</i>
+handle.</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>JNIEXPORT void JNICALL
+Java_spinner_Spinner_setPosition</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style="mso-spacerun: yes"> 
+</span>(JNIEnv *env, jclass that, jint hwnd, jint position)</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>{</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>SendMessage((HWND)
+hwnd, UDM_SETPOS, 0, position);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>JNIEXPORT jint JNICALL Java_spinner_Spinner_getPosition</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style="mso-spacerun: yes"> 
+</span>(JNIEnv *env, jclass that, jint hwnd)</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>{</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>return
+(jint) SendMessage((HWND) hwnd, UDM_GETPOS, 0, 0) &amp; 0xFFFF;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The <b style='mso-bidi-font-weight:normal'>resizeControl</b>
+method positions the <i style='mso-bidi-font-style:normal'>Edit</i> control
+(the buddy) and the <i style='mso-bidi-font-style:normal'>UpDown</i> (the arrow
+buttons) using the specified coordinates and size. For the width of the arrow
+buttons, we use the width of a typical vertical scrollbar.</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>JNIEXPORT void JNICALL
+Java_spinner_Spinner_resizeControl</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style="mso-spacerun: yes"> 
+</span>(JNIEnv *env, jclass that, jint hwndUpDown, jint x, jint y, jint width,
+jint height)</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>{</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>HWND
+hwndText = (HWND) SendMessage((HWND) hwndUpDown, UDM_GETBUDDY, 0, 0);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>UINT
+flags = SWP_NOZORDER | SWP_DRAWFRAME | SWP_NOACTIVATE;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>int
+upDownWidth = GetSystemMetrics(SM_CXVSCROLL);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>SetWindowPos(hwndText,
+(HWND) 0, x, y, width - upDownWidth + 2, height, flags);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>SetWindowPos((HWND)
+hwndUpDown, (HWND) 0, x + width - upDownWidth, y, upDownWidth, height, flags);<span
+style='mso-tab-count:3'>         </span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The final method we need to write is <b
+style='mso-bidi-font-weight:normal'>computeSize</b>. This is typically a
+complex method, and our <b style='mso-bidi-font-weight:normal'>computeSize</b>
+is no exception. We construct a string of digits the same length as the maximum
+value, and measure its height and width if drawn in the <i style='mso-bidi-font-style:
+normal'>Edit</i> control’s font. We make sure our control is no shorter than a
+combo box, and we add in text margins, and the width of the arrow buttons. In
+order to return the computed height and width values in the <b
+style='mso-bidi-font-weight:normal'>result</b> array, we need to lock down the
+array using the JNI function <b style='mso-bidi-font-weight:normal'>GetIntArrayElements</b>
+to protect it from moving as a result of garbage collection.</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>JNIEXPORT void JNICALL Java_spinner_Spinner_computeSize</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style="mso-spacerun: yes"> 
+</span>(JNIEnv *env, jclass that, jint hwndUpDown, jintArray result) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>int
+width, height;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>TEXTMETRIC
+tm;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>RECT
+rect;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>int
+comboHeight;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>int
+max, digits;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>UINT
+flags;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>char
+text[64];</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>HWND hwndText
+= (HWND) SendMessage((HWND) hwndUpDown, UDM_GETBUDDY, 0, 0);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>HDC
+hDC = GetDC(hwndText);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>HFONT
+oldFont = 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>HFONT
+newFont = (HFONT) SendMessage(hwndText, WM_GETFONT, 0, 0);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>jint
+*result1 = NULL;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>result1
+= (*env)-&gt;GetIntArrayElements(env, result, NULL);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>if
+(newFont != 0) oldFont = SelectObject(hDC, newFont);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>GetTextMetrics(hDC,
+&amp;tm);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>comboHeight
+= GetSystemMetrics(SM_CYVSCROLL);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>height
+= (comboHeight &gt; tm.tmHeight) ? comboHeight : tm.tmHeight;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>max =
+SendMessage((HWND) hwndUpDown, UDM_GETRANGE, 0, 0) &amp; 0xFFFF;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>if
+(max &gt; 0) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>digits
+= 0;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>while
+(max &gt; 0) {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span>text[digits]
+= '0';</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span>max
+/= 10;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:3'>         </span>digits++;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>flags
+= DT_CALCRECT | DT_EDITCONTROL | DT_NOPREFIX;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>DrawText(hDC,
+(LPCTSTR) text, digits, (LPRECT) &amp;rect, flags);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>width
+= rect.right - rect.left + 3;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}
+else {</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span><span
+style="mso-spacerun: yes"> </span><span style='mso-tab-count:1'>  </span>width
+= 10;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>if
+(newFont != 0) SelectObject(hDC, oldFont);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>ReleaseDC(hwndText,
+hDC);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>width
++= GetSystemMetrics(SM_CXVSCROLL);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>SendMessage(hwndText,
+EM_GETRECT, 0, (LPARAM) &amp;rect);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>if (rect.top
+== 0) rect.top = 1; // windows bug fix</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>width
++= (rect.left + 1) * 2;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>height
++= (rect.top + 1) * 2;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>result1
+[0] = width;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>result1
+[1] = height;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>(*env)-&gt;ReleaseIntArrayElements(env,
+result, result1, 0);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>}</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The full source listing for the Windows C
+code and makefile are in </span></span><a
+href="Writing%20Your%20Own%20Widget_files/AppendixC.htm"><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>Appendix
+C: Spinner for Windows</span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'></span></span></a><span style='mso-bookmark:
+_Toc496069785'><span style='mso-bookmark:_Toc496069428'>. A batch file sets
+environment variables and calls make to create the DLL. Options for your
+compiler and linker may differ, but you will have to link in the win32 libs:
+comctl32.lib, user32.lib, and gdi32.lib.</span></span></p>
+
+<span style='font-size:12.0pt;mso-bidi-font-size:10.0pt;font-family:"Times New Roman";
+mso-fareast-font-family:"Times New Roman";mso-ansi-language:EN-US;mso-fareast-language:
+EN-US;mso-bidi-language:AR-SA'><br clear=all style='mso-special-character:line-break;
+page-break-before:always'>
+</span>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'><o:p></o:p></span></span></p>
+
+<h3 style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><a name="_Toc506634638">Motif Native Code</a></span></span></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Now we need to write “spinner.c” for Motif.
+In this section, we will only point out the differences between the Motif
+“spinner.c” and the Windows one. The full source listing for the Motif C code
+and makefile are in </span></span><a
+href="Writing%20Your%20Own%20Widget_files/AppendixD.htm"><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>Appendix
+D: Spinner for Motif</span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'></span></span></a><span style='mso-bookmark:
+_Toc496069785'><span style='mso-bookmark:_Toc496069428'>. A shell script sets
+environment variables and calls make.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The Motif equivalent to Thread Local Storage
+is called Thread-Specific Data (TSD), and its functions are defined in <b
+style='mso-bidi-font-weight:normal'>pthread.h</b>. You will need to include at
+least the following files:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>#include &lt;jni.h&gt;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>#include &lt;Xm/XmAll.h&gt;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>#include &lt;pthread.h&gt;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>In order to store the <b style='mso-bidi-font-weight:
+normal'>env</b> pointer in Thread-Specific Data, you first create a key:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>static pthread_key_t envKey;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>…</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:2'>     </span>pthread_key_create(&amp;envKey,
+NULL);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>and then you store into and retrieve from
+TSD as follows:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>pthread_setspecific(envKey,
+env);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>JNIEnv
+*env = (JNIEnv *) pthread_getspecific(envKey);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>As you compare the Windows and Motif
+“spinner.c” listings, you will notice that the JNI portions of the code are
+identical: method templates, the use of JNI functions like <b style='mso-bidi-font-weight:
+normal'>GetIntArrayElements</b> and <b style='mso-bidi-font-weight:normal'>ReleaseIntArrayElements</b>
+for locking/releasing an array of integers, and <b style='mso-bidi-font-weight:
+normal'>NewGlobalRef</b>, <b style='mso-bidi-font-weight:normal'>GetStaticMethodID</b>,
+and <b style='mso-bidi-font-weight:normal'>CallStaticIntMethod</b> to call in
+to Java.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The platform code, however, is completely
+different. On Motif, we create the native control using <b style='mso-bidi-font-weight:
+normal'>XmCreateSimpleSpinBox</b>. The <i style='mso-bidi-font-style:normal'>Text</i>
+widget is created automatically and stored in the <b style='mso-bidi-font-weight:
+normal'>XmNtextField</b> resource of the <i style='mso-bidi-font-style:normal'>SimpleSpinBox</i>.
+You can retrieve the <i style='mso-bidi-font-style:normal'>Text</i> (for
+setting the font or computing the preferred size) using:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>Arg
+arg;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>Widget
+handleText;</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>XtSetArg(arg,
+XmNtextField, &amp;handleText);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>XtGetValues((Widget)
+handle, &amp;arg, 1);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>After creating the <i style='mso-bidi-font-style:
+normal'>SimpleSpinBox</i>, we have to ‘manage’ it, and then we add an <b
+style='mso-bidi-font-weight:normal'>XtCallbackProc</b> for the <b
+style='mso-bidi-font-weight:normal'>valueChanged</b> callback:</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>XtManageChild(handleSpinBox);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><span style='mso-tab-count:1'>  </span>XtAddCallback(handleSpinBox,
+XmNvalueChangedCallback, (XtCallbackProc) Callback, NULL);</span></span></p>
+
+<p class=Code style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>The <b style='mso-bidi-font-weight:normal'>computeSize</b>
+method is about as complex as the one for Windows, with height and width based
+on the maximum number of digits, with margins and shadows added in.
+Unfortunately, we had to guess a nice width for the arrow buttons, as this value
+could not be retrieved from a <i style='mso-bidi-font-style:normal'>SimpleSpinBox</i>.<br
+clear=all style='mso-special-character:line-break;page-break-before:always'>
+</span></span></p>
+
+<h3 style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><a name="_Toc506634639">Mixing Native and
+Java Widgets</a></span></span></h3>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Occasionally it is necessary to implement a
+widget using a native widget on one platform, and emulating the widget behavior
+with Java code on another platform. SWT does this for several widgets; for
+example, <i style='mso-bidi-font-style:normal'>Tree</i> is native on Windows,
+and emulated on Motif. All of the code to implement <i style='mso-bidi-font-style:
+normal'>Tree</i> on Motif is shipped in the SWT jar for Motif. On Windows, the
+API for <i style='mso-bidi-font-style:normal'>Tree</i> is shipped in the
+Windows SWT jar and the interface to the native control is shipped in the
+Windows SWT shared library (SWT.DLL).</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>When emulating a widget on one platform and
+wrapping a native or third party widget on another, it is important to subclass
+at the same point in the <i style='mso-bidi-font-style:normal'>Widget</i>
+hierarchy on both platforms (i.e. <i style='mso-bidi-font-style:normal'>Composite</i>
+or <i style='mso-bidi-font-style:normal'>Canvas</i>). It is also important to
+make certain that the public API is identical for both widgets. This makes it
+possible for applications to run on any platform without recompiling.</span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'>Looking at the <i style='mso-bidi-font-style:
+normal'>Spinner</i> example in the previous section, suppose we now want to
+have a <i style='mso-bidi-font-style:normal'>Spinner</i> on a third platform
+that does not have a native <i style='mso-bidi-font-style:normal'>SpinBox</i>
+or <i style='mso-bidi-font-style:normal'>UpDown</i> control. Since we
+subclassed<i style='mso-bidi-font-style:normal'> Composite</i> on Windows and
+Motif, we again subclass <i style='mso-bidi-font-style:normal'>Composite</i> on
+the new platform. Then we create three children: a <i style='mso-bidi-font-style:
+normal'>Text</i> and two arrow <i style='mso-bidi-font-style:normal'>Buttons</i>.
+Then we fill in the API and write our widget as described earlier in the <span
+style='mso-field-code:"REF _Ref506190201 \\h"'>Compound Widget Example<!--[if gte mso 9]><xml>
+ <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003500300036003100390030003200300031000000</w:data>
+</xml><![endif]--></span> section. The full source code listing for this 100%
+Java <i style='mso-bidi-font-style:normal'>Spinner</i> is in </span></span><a
+href="Writing%20Your%20Own%20Widget_files/AppendixE.htm"><span
+style='mso-bookmark:_Toc496069785'><span style='mso-bookmark:_Toc496069428'>Appendix
+E: Spinner for Any Platform</span></span><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'></span></span></a><span style='mso-bookmark:
+_Toc496069785'><span style='mso-bookmark:_Toc496069428'>.</span></span></p>
+
+<b style='mso-bidi-font-weight:normal'><span style='font-size:14.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Times New Roman";mso-fareast-font-family:
+"Times New Roman";mso-ansi-language:EN-US;mso-fareast-language:EN-US;
+mso-bidi-language:AR-SA'><br clear=all style='page-break-before:always'>
+</span></b>
+
+<p class=MsoNormal style='margin-left:25.5pt'><span style='mso-bookmark:_Toc496069785'><span
+style='mso-bookmark:_Toc496069428'><b style='mso-bidi-font-weight:normal'><span
+style='font-size:18.0pt;mso-bidi-font-size:10.0pt'>Summary</span></b></span></span><b
+style='mso-bidi-font-weight:normal'><span style='font-size:18.0pt;mso-bidi-font-size:
+10.0pt'><o:p></o:p></span></b></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>SWT provides several different
+ways to implement new widgets. The simplest method, and the one you will
+typically use, is to subclass <i style='mso-bidi-font-style:normal'>Canvas</i>
+or <i style='mso-bidi-font-style:normal'>Composite</i> and add listeners and
+methods to get the job done.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>In certain cases the
+specification for your new widget will so closely resemble a single existing
+SWT widget that you will want to use that widget in your implementation. The recommended
+way to do this is to wrap the SWT widget in a subclass of <i style='mso-bidi-font-style:
+normal'>Composite</i>, and implement a carefully determined subset of the
+wrapped widget’s methods by forwarding to the wrapped widget.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>Occasionally, you may need to
+wrap a platform or third party widget by writing a platform-specific shared
+library that makes calls to this widget. You can then subclass <i
+style='mso-bidi-font-style:normal'>Composite</i> and provide a Java native
+interface to your library code.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+<p class=MsoNormal style='margin-left:25.5pt'>Finally, in very special and rare
+circumstances, you can subclass an existing SWT widget, but this is not
+recommended.</p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:24.0pt 48.0pt 1.0in 96.0pt 120.0pt 2.0in 168.0pt 192.0pt 3.0in 240.0pt 264.0pt 4.0in 312.0pt 336.0pt 5.0in 384.0pt 408.0pt 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";layout-grid-mode:line'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<h4 style='margin-left:25.5pt'><b>Example Code<o:p></o:p></b></h4>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:24.0pt 48.0pt 1.0in 96.0pt 120.0pt 2.0in 168.0pt 192.0pt 3.0in 240.0pt 264.0pt 4.0in 312.0pt 336.0pt 5.0in 384.0pt 408.0pt 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><a
+name="_Ref498278978"></a><a name="_Toc506634640"><span style='mso-bookmark:
+_Ref498278978'></span></a><a
+href="Writing%20Your%20Own%20Widget_files/AppendixA.htm"><span
+style='mso-bookmark:_Toc506634640'><span style='mso-bookmark:_Ref498278978'>Appendix
+A: TableTree and TableTreeItem</span></span><span style='mso-bookmark:_Ref498278978'></span><span
+style='mso-bookmark:_Toc506634640'></span><span style='mso-bookmark:_Ref506196466'><span
+style='mso-bookmark:_Ref506203309'><span style='mso-bookmark:_Toc506634643'></span></span></span><span
+style='mso-bookmark:_Ref506196466'><span style='mso-bookmark:_Ref506203309'><span
+style='mso-bookmark:_Toc506634643'></span></span></span></a><![if !supportNestedAnchors]><a
+name="_Toc506634643"></a><a name="_Ref506203309"></a><a name="_Ref506196466"></a><![endif]><span
+style='mso-bookmark:_Ref506196466'><span style='mso-bookmark:_Ref506203309'><span
+style='mso-bookmark:_Toc506634643'></span></span></span></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:24.0pt 48.0pt 1.0in 96.0pt 120.0pt 2.0in 168.0pt 192.0pt 3.0in 240.0pt 264.0pt 4.0in 312.0pt 336.0pt 5.0in 384.0pt 408.0pt 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='mso-bookmark:_Ref506196466'><span style='mso-bookmark:_Ref506203309'><span
+style='mso-bookmark:_Toc506634643'></span></span></span><a
+href="Writing%20Your%20Own%20Widget_files/AppendixB.htm"><span
+style='mso-bookmark:_Ref506196466'><span style='mso-bookmark:_Ref506203309'><span
+style='mso-bookmark:_Toc506634643'>Appendix B: Spinner</span></span></span><span
+style='mso-bookmark:_Toc506634643'>Test and Spinner</span><span
+style='mso-bookmark:_Toc506634643'></span></a></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:24.0pt 48.0pt 1.0in 96.0pt 120.0pt 2.0in 168.0pt 192.0pt 3.0in 240.0pt 264.0pt 4.0in 312.0pt 336.0pt 5.0in 384.0pt 408.0pt 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><a
+name="_Ref506009163"></a><a name="_Toc506634646"><span style='mso-bookmark:
+_Ref506009163'></span></a><a
+href="Writing%20Your%20Own%20Widget_files/AppendixC.htm"><span
+style='mso-bookmark:_Toc506634646'><span style='mso-bookmark:_Ref506009163'>Appendix
+C: Spinner for Windows</span></span><span style='mso-bookmark:_Ref506009163'></span><span
+style='mso-bookmark:_Toc506634646'></span><span style='mso-bookmark:_Ref506009181'><span
+style='mso-bookmark:_Toc506634650'></span></span><span style='mso-bookmark:
+_Ref506009181'><span style='mso-bookmark:_Toc506634650'></span></span></a><![if !supportNestedAnchors]><a
+name="_Toc506634650"></a><a name="_Ref506009181"></a><![endif]><span
+style='mso-bookmark:_Ref506009181'><span style='mso-bookmark:_Toc506634650'></span></span></p>
+
+<p class=MsoHeader style='margin-left:25.5pt;tab-stops:24.0pt 48.0pt 1.0in 96.0pt 120.0pt 2.0in 168.0pt 192.0pt 3.0in 240.0pt 264.0pt 4.0in 312.0pt 336.0pt 5.0in 384.0pt 408.0pt 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='mso-bookmark:_Ref506009181'><span style='mso-bookmark:_Toc506634650'></span></span><a
+href="Writing%20Your%20Own%20Widget_files/AppendixD.htm"><span
+style='mso-bookmark:_Ref506009181'><span style='mso-bookmark:_Toc506634650'>Appendix
+D: Spinner for Motif</span></span><span style='mso-bookmark:_Toc506634650'></span><span
+style='mso-bookmark:_Ref506009181'></span></a></p>
+
+<p class=MsoNormal style='margin-left:25.5pt;tab-stops:24.0pt 48.0pt 1.0in 96.0pt 120.0pt 2.0in 168.0pt 192.0pt 3.0in 240.0pt 264.0pt 4.0in 312.0pt 336.0pt 5.0in 384.0pt 408.0pt 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><a
+name="_Ref506190577"></a><a name="_Toc506634654"><span style='mso-bookmark:
+_Ref506190577'></span></a><a
+href="Writing%20Your%20Own%20Widget_files/AppendixE.htm"><span
+style='mso-bookmark:_Toc506634654'><span style='mso-bookmark:_Ref506190577'>Appendix
+E: Spinner for Any Platform</span></span><span style='mso-bookmark:_Ref506190577'></span><span
+style='mso-bookmark:_Toc506634654'></span></a><span style='font-size:9.0pt;
+mso-bidi-font-size:10.0pt;font-family:"Courier New";mso-bidi-font-family:"Times New Roman";
+layout-grid-mode:line'><o:p></o:p></span></p>
+
+</div>
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+</body>
+
+</html>
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixA.htm b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixA.htm
new file mode 100644
index 0000000..fe143b0
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixA.htm
@@ -0,0 +1,10017 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<title>Appendix A: TableTree and TableTreeItem</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Author>Dave Thomson</o:Author>
+ <o:LastAuthor>Carolyn MacLeod</o:LastAuthor>
+ <o:Revision>6</o:Revision>
+ <o:TotalTime>13</o:TotalTime>
+ <o:Created>2001-06-04T02:58:00Z</o:Created>
+ <o:LastSaved>2001-06-04T03:49:00Z</o:LastSaved>
+ <o:Pages>20</o:Pages>
+ <o:Words>5130</o:Words>
+ <o:Characters>29242</o:Characters>
+ <o:Lines>243</o:Lines>
+ <o:Paragraphs>58</o:Paragraphs>
+ <o:CharactersWithSpaces>35911</o:CharactersWithSpaces>
+ <o:Version>9.2720</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+ {font-family:Courier;
+ panose-1:0 0 0 0 0 0 0 0 0 0;
+ mso-font-charset:0;
+ mso-generic-font-family:modern;
+ mso-font-format:other;
+ mso-font-pitch:fixed;
+ mso-font-signature:3 0 0 0 1 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ mso-ansi-language:EN-CA;}
+h1
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:20.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ color:windowtext;
+ mso-font-kerning:14.0pt;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+h2
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:2;
+ font-size:18.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+h3
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:3;
+ font-size:14.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc1, li.MsoToc1, div.MsoToc1
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:.25in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ text-transform:uppercase;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc2, li.MsoToc2, div.MsoToc2
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc3, li.MsoToc3, div.MsoToc3
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:10.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc4, li.MsoToc4, div.MsoToc4
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:20.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc5, li.MsoToc5, div.MsoToc5
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:30.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc6, li.MsoToc6, div.MsoToc6
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:40.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc7, li.MsoToc7, div.MsoToc7
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:50.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc8, li.MsoToc8, div.MsoToc8
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:60.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc9, li.MsoToc9, div.MsoToc9
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:70.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoHeader, li.MsoHeader, div.MsoHeader
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoFooter, li.MsoFooter, div.MsoFooter
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoBodyText, li.MsoBodyText, div.MsoBodyText
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:red;}
+p.MsoBodyText2, li.MsoBodyText2, div.MsoBodyText2
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in;
+ layout-grid-mode:char;
+ font-size:9.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:black;}
+a:link, span.MsoHyperlink
+ {color:blue;
+ text-decoration:underline;
+ text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+ {color:purple;
+ text-decoration:underline;
+ text-underline:single;}
+strong
+ {mso-bidi-font-weight:normal;}
+em
+ {mso-bidi-font-style:normal;}
+p
+ {margin-top:5.0pt;
+ margin-right:0in;
+ margin-bottom:5.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:black;}
+code
+ {mso-ascii-font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-hansi-font-family:"Courier New";
+ mso-bidi-font-family:"Times New Roman";}
+p.Code, li.Code, div.Code
+ {mso-style-name:Code;
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in 2.25in 2.5in 2.75in 3.0in 3.25in 3.5in 3.75in 4.0in 4.25in 4.5in 4.75in 5.0in 5.25in 5.5in 5.75in;
+ layout-grid-mode:char;
+ font-size:9.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:windowtext;}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US link=blue vlink=purple style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<h2><a name="_Ref498278978"></a><a name="_Toc506634640"><span style='mso-bookmark:
+_Ref498278978'>Appendix A: TableTree and TableTreeItem</span></a><i
+style='mso-bidi-font-style:normal'><o:p></o:p></i></h2>
+
+<p class=MsoNormal><span lang=EN-CA>This appendix contains the source code for
+the <i style='mso-bidi-font-style:normal'>TableTree</i> and <i
+style='mso-bidi-font-style:normal'>TableTreeItem</i> classes.</span><span
+style='mso-bidi-font-size:10.0pt;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<h3><a name="_Toc506634641">TableTree</a></h3>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>package </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.custom;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/*</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* (c) Copyright IBM Corp. 2000, 2001.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* All Rights Reserved</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>java.util.Enumeration;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>java.util.Vector;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.events.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.graphics.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.widgets.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/** </span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* A TableTree is a selectable user interface object</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* that displays a hierarchy of items, and issues</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* notification when an item is selected.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* A TableTree may be single or multi select.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+The item children that may be added to instances of this class</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* must be of type </span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>&lt;code&gt;</span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/code&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/p&gt;&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+Note that although this class is a subclass of </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;code&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>Composite</span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/code&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>,</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* it does not make sense to add </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;code&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>Control</span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/code&gt; </span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>children to it,</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* or set a layout on it.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/p&gt;&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;dl&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;dt&gt;&lt;b&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>Styles:</span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/b&gt; &lt;dd&gt; </span><span style='font-size:
+10.0pt;font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>SINGLE, MULTI, CHECK, FULL_SELECTION</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;dt&gt;&lt;b&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Events:</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/b&gt; &lt;dd&gt; </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Selection, DefaultSelection,
+Collapse, Expand</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/dl&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public class </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTree </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>extends </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Composite {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Table
+table;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem[]
+items = EMPTY_ITEMS;</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Image
+plusImage, minusImage, sizeImage;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/*</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+TableTreeItems are not treated as children but rather as items.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+When the TableTree is disposed, all children are disposed because </span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+TableTree inherits this behaviour from Composite.<span style="mso-spacerun:
+yes">  </span>The items</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+must be disposed separately.<span style="mso-spacerun: yes">  </span>Because
+TableTree is not part of</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+the org.eclipse.swt.widgets package, the method releaseWidget can </span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+not be overriden (this is how items are disposed of in Table and Tree).</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+Instead, the items are disposed of in response to the dispose event on the</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+TableTree.<span style="mso-spacerun: yes">  </span>The &quot;inDispose&quot;
+flag is used to distinguish between disposing</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+one TableTreeItem (e.g. when removing an entry from the TableTree) and </span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*
+disposing the entire TableTree.</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>boolean
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>inDispose = </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>false</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>static final </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem[] EMPTY_ITEMS = </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>new </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>TableTreeItem [0];<span style='mso-tab-count:1'> </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>static final </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>String[] EMPTY_TEXTS = </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>new </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>String [0];<span style='mso-tab-count:1'>   </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>static final </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Image[] EMPTY_IMAGES = </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>new </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>Image [0];<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Creates a new instance of the widget.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>parent a
+composite widget</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>style the bitwise
+OR'ing of widget styles</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTree(Composite parent, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>style) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(parent, SWT.NONE);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Table(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>, style);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>setBackground(table.getBackground());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>setForeground(table.getForeground());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>setFont(table.getFont());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.addListener(SWT.MouseDown,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>onMouseDown(e);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.addListener(SWT.Selection,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>onSelection(e);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.addListener(SWT.DefaultSelection,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>onSelection(e);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>addListener(SWT.Dispose,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>onDispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>addListener(SWT.Resize,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>onResize();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>addListener(SWT.FocusIn,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>onFocusIn();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>addItem(TableTreeItem item, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(index &lt; 0 || index &gt; items.length) </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError(SWT.ERROR_INVALID_ARGUMENT);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem[]
+newItems = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem[items.length + 1];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+0, newItems, 0, index);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>newItems[index]
+= item;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+index, newItems, index + 1, items.length - index); </span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>items
+= newItems;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/* Return the index in the table
+where this table should be inserted */</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>if
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>(index ==
+items.length - 1 ) </span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>table.getItemCount();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>else </span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>return
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>table.indexOf(items[index+1].tableItem);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**<span style='mso-tab-count:
+1'>   </span> </span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Adds the listener to receive selection events.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>listener the
+selection listener</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_NULL_ARGUMENT when listener
+is null</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>addSelectionListener(SelectionListener
+listener) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(listener == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError
+(SWT.ERROR_NULL_ARGUMENT);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TypedListener
+typedListener = </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:EN-US'>new
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>TypedListener
+(listener);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>addListener
+(SWT.Selection,typedListener);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>addListener
+(SWT.DefaultSelection,typedListener);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**<span style='mso-tab-count:
+1'>   </span> </span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Adds the listener to receive tree events.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>listener the tree
+listener</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_NULL_ARGUMENT when listener
+is null</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>addTreeListener(TreeListener
+listener) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(listener == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError
+(SWT.ERROR_NULL_ARGUMENT);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TypedListener
+typedListener = </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:EN-US'>new
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>TypedListener
+(listener);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>addListener
+(SWT.Expand, typedListener);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>addListener
+(SWT.Collapse, typedListener);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}<span style="mso-spacerun: yes"> 
+</span></span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Computes the preferred size of the widget.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+Calculate the preferred size of the widget based</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* on the current contents. The hint arguments allow</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* a specific client area width and/or height to be</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* requested. The hints may be honored depending on</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* the platform and the layout.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>wHint the width
+hint (can be SWT.DEFAULT)</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>hHint the height
+hint (can be SWT.DEFAULT)</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>a point
+containing the preferred size of the widget including trim</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Point computeSize (</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>wHint, </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>int </span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>hHint) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>table.computeSize (wHint, hHint, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>true</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Computes the widget trim.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+Trim is widget specific and may include scroll</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* bars and menu bar in addition to other trimmings</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* that are outside of the widget's client area.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>x the x location
+of the client area</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>y the y location
+of the client area</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>width the width
+of the client area</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>height the height
+of the client area</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>a rectangle
+containing the trim of the widget.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Rectangle computeTrim (</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>x, </span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>y, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>width, </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>int </span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>height) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>table.computeTrim(x, y, width,
+height);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Deselects all items.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+If an item is selected, it is deselected.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* If an item is not selected, it remains unselected.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>deselectAll () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.deselectAll();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/* Expand upward from the
+specified leaf item. */</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>expandItem (TableTreeItem item) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(item == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null </span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>|| item.getExpanded()) </span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>return</span><span style='font-size:10.0pt;font-family:Courier;
+color:black;background:white;mso-highlight:white;mso-ansi-language:EN-US'>;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>expandItem(item.parentItem);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>item.setExpanded(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>true</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Event
+event = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Event();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>event.item
+= item;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>notifyListeners(SWT.Expand,
+event);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the number of items.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>the number of items in the widget</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getItemCount () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>items.length;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the height of one item.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+This operation will fail if the height of</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* one item could not be queried from the OS.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the height of one
+item in the widget</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_CANNOT_GET_ITEM_HEIGHT when
+the operation fails</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getItemHeight () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>table.getItemHeight();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the items.</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>the items in the widget</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem [] getItems () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem[]
+newItems = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem[items.length];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+0, newItems, 0, items.length);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>newItems;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the selected items.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+This operation will fail if the selected</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* items cannot be queried from the OS.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the selected
+items in the widget</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* <span
+style='mso-tab-count:2'>         </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_CANNOT_GET_SELECTION when the operation fails</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem [] getSelection () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableItem[]
+selection = table.getSelection();</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem
+[] result = </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:EN-US'>new
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem[selection.length];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+selection.length; i++){</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>result[i]
+= (TableTreeItem) selection[i].getData();</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>result;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the number of selected items.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+This operation will fail if the number of selected</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* items cannot be queried from the OS.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the number of
+selected items in the widget</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* <span
+style='mso-tab-count:2'>         </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_CANNOT_GET_COUNT when the operation fails</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getSelectionCount () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>table.getSelectionCount();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Returns the underlying Table control.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the underlying
+Table control</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Table getTable () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>table;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>createImages () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>itemHeight = sizeImage.getBounds().height;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>// Calculate border around image. </span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>//
+At least 9 pixels are needed to draw the image</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>//
+Leave at least a 6 pixel border.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>indent = Math.min(6, (itemHeight - 9) / 2);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>indent
+= Math.max(0, indent);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>size = Math.max (10, itemHeight - 2 * indent); </span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>size
+= ((size + 1) / 2) * 2; </span><span style='font-size:10.0pt;font-family:Courier;
+color:#2A7FAA;background:white;mso-highlight:white;mso-ansi-language:EN-US'>//
+size must be an even number</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>midpoint = indent + size / 2;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Color
+foreground = getForeground();</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Color
+plusMinus = getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Color
+background = getBackground();</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/* Plus image */</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>PaletteData
+palette = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>PaletteData(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>new </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>RGB[]{foreground.getRGB(), background.getRGB(),
+plusMinus.getRGB()});</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>ImageData
+imageData = </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:EN-US'>new
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>ImageData(itemHeight,
+itemHeight, 4, palette);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>imageData.transparentPixel
+= 1;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>plusImage
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Image(getDisplay(), imageData);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>GC
+gc = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>GC(plusImage);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.setBackground(background);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.fillRectangle(0,
+0, itemHeight, itemHeight);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.setForeground(plusMinus);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.drawRectangle(indent,
+indent, size, size);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.setForeground(foreground);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.drawLine(midpoint,
+indent + 2, midpoint, indent + size - 2);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.drawLine(indent
++ 2, midpoint, indent + size - 2, midpoint);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/* Minus image */</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>palette
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>PaletteData(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>new </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>RGB[]{foreground.getRGB(), background.getRGB(),
+plusMinus.getRGB()});</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>imageData
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ImageData(itemHeight, itemHeight,
+4, palette);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>imageData.transparentPixel
+= 1;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>minusImage
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Image(getDisplay(), imageData);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>GC(minusImage);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.setBackground(background);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.fillRectangle(0,
+0, itemHeight, itemHeight);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.setForeground(plusMinus);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.drawRectangle(indent,
+indent, size, size);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.setForeground(foreground);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.drawLine(indent
++ 2, midpoint, indent + size - 2, midpoint);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>gc.dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Image getPlusImage() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(plusImage == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) createImages();</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>plusImage;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Image getMinusImage() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(minusImage == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) createImages();</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>minusImage;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the index of an item.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>The widget is searched starting at
+0 until an</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* item is found that is equal to the search item.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* If no item is found, -1 is returned.<span style="mso-spacerun:
+yes">  </span>Indexing</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* is zero based.<span style="mso-spacerun: yes">  </span>This
+index is relative to the parent only.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>item the search
+item</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the index of the
+item or -1</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>indexOf (TableTreeItem item) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt; items.length;
+i++) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(item == items[i]) </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>return </span><span style='font-size:10.0pt;
+font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>i;</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>-1;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>onDispose() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>inDispose
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>true</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+items.length; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>items[i].dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>inDispose
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>false</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(plusImage != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) plusImage.dispose();</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(minusImage != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) minusImage.dispose();</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(sizeImage != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) sizeImage.dispose();</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>plusImage
+= minusImage = sizeImage = </span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>null</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>onResize () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Rectangle
+area = getClientArea();</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.setBounds(0,
+0, area.width, area.height);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>onSelection (Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Event
+event = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Event();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableItem
+tableItem = (TableItem)e.item;</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes">    </span><span style='mso-tab-count:1'>  </span>TableTreeItem item =
+getItem(tableItem);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes">    </span><span style='mso-tab-count:1'>  </span>event.item = item;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(e.type == SWT.Selection </span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span><span
+style="mso-spacerun: yes">    </span>&amp;&amp; e.detail == SWT.CHECK</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span><span
+style="mso-spacerun: yes">    </span>&amp;&amp; item != </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>null</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>) {</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span><span
+style="mso-spacerun: yes">    </span><span style='mso-tab-count:1'>  </span>event.detail
+= SWT.CHECK;</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>item.checked
+= tableItem.getChecked();</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>notifyListeners(e.type,
+event);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem getItem(Point point)
+{</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableItem
+item = table.getItem(point);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(item == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>return null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getItem(item);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem getItem(TableItem
+tableItem) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>return null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+items.length; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span><span
+style="mso-spacerun: yes">    </span><span style='mso-tab-count:1'>  </span>TableTreeItem
+item = items[i].getItem(tableItem);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span><span
+style="mso-spacerun: yes">    </span><span style='mso-tab-count:1'>  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(item != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>item;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>onFocusIn () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.setFocus();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>onMouseDown(Event event) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/* If user clicked on the [+] or
+[-], expand or collapse the tree. */</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableItem[]
+items = table.getItems();</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+items.length; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>Rectangle
+rect = items[i].getImageBounds(0);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(rect.contains(event.x, event.y)) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>TableTreeItem
+item = (TableTreeItem) items[i].getData();</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>event
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Event();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>event.item
+= item;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>item.setExpanded(!item.getExpanded());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(item.getExpanded()) {</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>notifyListeners(SWT.Expand,
+event);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>else </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>{</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>notifyListeners(SWT.Collapse,
+event);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Removes all items.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+This operation will fail when an item</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* could not be removed in the OS.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* <span style='mso-tab-count:1'>   </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* <span style='mso-tab-count:1'>   </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_ITEM_NOT_REMOVED when the
+operation fails</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>removeAll () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>setRedraw(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>false</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>);</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = items.length
+- 1; i &gt;= 0; i--) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>items[i].dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>items
+= EMPTY_ITEMS;</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>setRedraw(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>true</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>removeItem(TableTreeItem item) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index = 0;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>while </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(index &lt; items.length
+&amp;&amp; items[index] != item) index++;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(index == items.length) </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>return</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem[]
+newItems = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem[items.length - 1];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+0, newItems, 0, index);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+index + 1, newItems, index, items.length - index - 1);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>items
+= newItems;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**<span style='mso-tab-count:
+1'>   </span> </span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Removes the listener.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>listener the
+listener</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* <span style='mso-tab-count:1'>   </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_NULL_ARGUMENT when listener
+is null</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>removeSelectionListener
+(SelectionListener listener) {</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(listener == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError
+(SWT.ERROR_NULL_ARGUMENT);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>removeListener(SWT.Selection,
+listener);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>removeListener(SWT.DefaultSelection,
+listener);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**<span style='mso-tab-count:
+1'>   </span> </span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Removes the listener.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>listener the
+listener</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_NULL_ARGUMENT when listener
+is null</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>removeTreeListener (TreeListener
+listener) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(listener == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError
+(SWT.ERROR_NULL_ARGUMENT);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>removeListener(SWT.Expand,
+listener);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>removeListener(SWT.Collapse,
+listener);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Selects all items.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+If an item is not selected, it is selected.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* If an item is selected, it remains selected.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>selectAll () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.selectAll();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the widget background color.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+When new color is null, the background reverts</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* to the default system color for the widget.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>color the new
+color (or null)</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setBackground (Color color) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.setBackground(color);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.setBackground(color);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(sizeImage != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>GC
+gc = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>GC (sizeImage);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>gc.setBackground(getBackground());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>Rectangle
+size = sizeImage.getBounds();</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>gc.fillRectangle(size);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>gc.dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the enabled state.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* A
+disabled widget is typically not selectable from</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* the user interface and draws with an inactive or</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* grayed look.</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>enabled the new
+enabled state</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setEnabled (</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>boolean </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>enabled) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.setEnabled(enabled);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.setEnabled(enabled);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the widget font.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+When new font is null, the font reverts</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* to the default system font for the widget.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>font the new font
+(or null)</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setFont (Font font) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.setFont(font);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.setFont(font);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the widget foreground color.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>the widget foreground color</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setForeground (Color color) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.setForeground(color);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.setForeground(color);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the pop up menu.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+Every control has an optional pop up menu that is</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* displayed when the user requests a popup menu for</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* the control.<span style="mso-spacerun: yes">  </span>The
+sequence of key strokes/button</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* presses/button releases that is used to request</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* a pop up menu is platform specific.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>menu the new pop
+up menu</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_MENU_NOT_POP_UP when the menu is not a POP_UP</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_NO_COMMON_PARENT when the menu is not in the
+same widget tree</span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setMenu (Menu menu) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.setMenu(menu);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.setMenu(menu);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the selection.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@param </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>items new selection</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_NULL_ARGUMENT when items is
+null</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setSelection (TableTreeItem[]
+items) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableItem[]
+tableItems = </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:EN-US'>new
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>TableItem[items.length];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+items.length; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(items[i] == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError(SWT.ERROR_NULL_ARGUMENT);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(!items[i].getVisible()) expandItem (items[i]);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>tableItems[i]
+= items[i].tableItem;</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.setSelection(tableItems);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the tool tip text.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@param </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>string the new tool tip text (or
+null)</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setToolTipText (String string) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.setToolTipText(string);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.setToolTipText(string);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Shows the item.</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@param </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>item the item to be shown</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_NULL_ARGUMENT when item is
+null</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>showItem (TableTreeItem item) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(item == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError
+(SWT.ERROR_NULL_ARGUMENT);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(!item.getVisible()) expandItem (item);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableItem
+tableItem = item.tableItem;</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.showItem(tableItem);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Shows the selection.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+If there is no selection or the selection</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* is already visible, this method does nothing.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* If the selection is scrolled out of view,</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* the top index of the widget is changed such</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* that selection becomes visible.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*<span style='mso-tab-count:1'>    </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>showSelection () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>table.showSelection();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in 2.25in 2.5in 2.75in 3.25in 3.5in 3.75in 4.25in 4.5in 4.75in 5.25in 5.5in 5.75in'><span
+style='mso-bidi-font-size:10.0pt;font-family:Courier;color:black;mso-ansi-language:
+EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal><span style='mso-bidi-font-size:10.0pt;mso-ansi-language:
+EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<h3><a name="_Toc506634642">TableTreeItem</a></h3>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>package </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.custom;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/*</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* (c) Copyright IBM Corp. 2000, 2001.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* All Rights Reserved</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.events.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.graphics.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.widgets.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* A TableTreeItem is a selectable user interface object</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* that represents an item in a heirarchy of items in a</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* TableTree.</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public class </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>extends </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Item {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableItem
+tableItem;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTree
+parent;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem
+parentItem;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem
+[] items = TableTree.EMPTY_ITEMS;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>String[]
+texts = TableTree.EMPTY_TEXTS;</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Image[]
+images = TableTree.EMPTY_IMAGES;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>boolean </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>expanded;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>boolean </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>checked;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Create a new instance of a root item.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>parent the
+TableTree that contains this root item</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>style the bitwise
+OR'ing of widget styles</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem(TableTree parent, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>style) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(parent, style,
+parent.getItemCount());</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Create a new instance of a root item in the position</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* indicated by the specified index.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>parent the
+TableTree that contains this root item</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>style the bitwise
+OR'ing of widget styles</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>index specifies
+the position of this item in the TableTree</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* <span style='mso-tab-count:1'>   </span>relative to other root
+items</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem(TableTree parent, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>style, </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>int </span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>index) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(parent, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>null</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>, style, index);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Create a new instance of a sub item.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>parent this
+item's parent in the hierarchy of TableTree items</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>style the bitwise
+OR'ing of widget styles</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem(TableTreeItem
+parent, </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>style) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(parent, style,
+parent.getItemCount());</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Create a new instance of a sub item in the position</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* indicated by the specified index.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>parent this
+item's parent in the hierarchy of TableTree items</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>style the bitwise
+OR'ing of widget styles</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>index specifies
+the position of this item in the TableTree</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* <span style='mso-tab-count:1'>   </span>relative to other
+children of the same parent</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem(TableTreeItem
+parent, </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>style, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(parent.getParent(), parent,
+style, index);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem(TableTree parent,
+TableTreeItem parentItem, </span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>style, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(parent, style);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>.parent = parent;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>.parentItem = parentItem;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(parentItem == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/* Root items are visible
+immediately */</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>int
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>tableIndex =
+parent.addItem(</span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:EN-US'>this</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>, index);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>tableItem
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableItem(parent.getTable(),
+style, tableIndex);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>tableItem.setData(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>addCheck();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/*</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>*
+Feature in the Table.<span style="mso-spacerun: yes">  </span>The table uses
+the first image that</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>*
+is inserted into the table to size the table rows.<span style="mso-spacerun:
+yes">  </span>If the</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>*
+user is allowed to insert the first image, this will cause</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>*
+the +/- images to be scaled.<span style="mso-spacerun: yes">  </span>The fix is
+to insert a dummy</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>*
+image to force the size.</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>if
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>(parent.sizeImage
+== </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>) {</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>itemHeight = parent.getItemHeight();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>parent.sizeImage
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Image(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>null</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>, itemHeight, itemHeight);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>GC
+gc = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>GC (parent.sizeImage);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>gc.setBackground(parent.getBackground());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>gc.fillRectangle(0,
+0, itemHeight, itemHeight);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>gc.dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>tableItem.setImage(0,
+parent.sizeImage);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>else </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>{</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>parentItem.addItem(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>, index);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>addCheck() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Table
+table = parent.getTable();</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>((table.getStyle() &amp; SWT.CHECK) == 0) </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>tableItem.setChecked(checked);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>addItem(TableTreeItem item, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(item == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError(SWT.ERROR_NULL_ARGUMENT);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(index &lt; 0 || index &gt; items.length) </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError(SWT.ERROR_INVALID_ARGUMENT);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/* Now that item has a sub-node it
+must indicate that it can be expanded */</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>if
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>(items.length ==
+0 &amp;&amp; index == 0) {</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>Image
+image = expanded ? parent.getMinusImage() : parent.getPlusImage();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>tableItem.setImage(0,
+image);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/* Put the item in the items list
+*/</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem[]
+newItems = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem[items.length + 1];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+0, newItems, 0, index);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>newItems[index]
+= item;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+index, newItems, index + 1, items.length - index);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>items
+= newItems;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(expanded) item.setVisible(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>true</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the widget bounds at the specified index.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>the widget bounds at the specified
+index</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt; </span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Rectangle getBounds (</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>tableItem.getBounds(index);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>else </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>{</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Rectangle(0, 0, 0, 0);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>* Gets the checked state.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>* </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;p&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>* </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>@return </span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>the item checked state.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>* </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>@exception </span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>SWTError </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*<span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when
+called from the wrong thread</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>&lt;/li&gt;</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*<span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*<span style='mso-tab-count:1'>     </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public boolean </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getChecked () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>checked;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>tableItem.getChecked();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the Display.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+This method gets the Display that is associated</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* with the widget.</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the widget data</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Display getDisplay () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTree
+parent = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>this</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.parent;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(parent == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError
+(SWT.ERROR_WIDGET_DISPOSED);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>parent.getDisplay ();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the expanded state of the widget.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>a boolean that is the expanded
+state of the widget</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public boolean </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getExpanded () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>expanded;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the first image.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+The image in column 0 is reserved for the [+] and [-]</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* images of the tree, therefore getImage(0) will return null.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the image at
+index 0</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Image getImage () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getImage(0);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the image at the specified index.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+Indexing is zero based. The image can be null.</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* The image in column 0 is reserved for the [+] and [-]</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* images of the tree, therefore getImage(0) will return null.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Return null if the index is out of range.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>index the index
+of the image</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the image at the
+specified index or null</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Image getImage (</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(0 &lt; index &amp;&amp; index &lt; images.length) </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>images[index];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>getIndent() {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(parentItem == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>0;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>parentItem.getIndent() + 1;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the number of sub items.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>the number of sub items</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getItemCount () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>items.length;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the sub items.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>the sub items</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem[] getItems () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem[]
+newItems = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem[items.length];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+0, newItems, 0, items.length);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>newItems;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem getItem(TableItem
+tableItem) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>return null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>this</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>.tableItem ==
+tableItem) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>return this</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+items.length; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>TableTreeItem
+item =<span style="mso-spacerun: yes">  </span>items[i].getItem(tableItem);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span><span
+style="mso-spacerun: yes">    </span><span style='mso-tab-count:1'>  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(item != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>item;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the parent.</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>the parent</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTree getParent () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>parent;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the parent item.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>the parent item.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem getParentItem () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>parentItem;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the first item text.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@return </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>the item text at index 0, which
+can be null</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* <span
+style='mso-tab-count:2'>         </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_CANNOT_GET_TEXT when the operation fails</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>String getText () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getText(0);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the item text at the specified index.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+Indexing is zero based.</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* This operation will fail when the index is out</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* of range or an item could not be queried from</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* the OS.</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>index the index
+of the item</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the item text at
+the specified index, which can be null</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>String getText(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(0 &lt;= index &amp;&amp; index &lt; texts.length) </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>texts[index];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>boolean </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getVisible () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>tableItem != </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>null</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>;</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Gets the index of the specified item.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>The widget is searched starting at
+0 until an</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* item is found that is equal to the search item.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* If no item is found, -1 is returned.<span style="mso-spacerun:
+yes">  </span>Indexing</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* is zero based.<span style="mso-spacerun: yes">  </span>This
+index is relative to the parent only.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>item the search
+item</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@return
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>the index of the
+item or -1 if the item is not found</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>indexOf (TableTreeItem item) {<span
+style='mso-tab-count:1'> </span></span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+items.length; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(items[i] == item) </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>return </span><span style='font-size:10.0pt;
+font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>i;</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>-1;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>expandedIndexOf (TableTreeItem item) {<span
+style='mso-tab-count:1'>      </span></span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index = 0;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+items.length; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(items[i] == item) </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>return </span><span style='font-size:10.0pt;
+font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index;</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(items[i].expanded) index +=
+items[i].visibleChildrenCount ();</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>index++;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>-1;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>visibleChildrenCount () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>count = 0;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+items.length; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(items[i].getVisible ()) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>count
++= 1 + items[i].visibleChildrenCount ();</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>count;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>dispose () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = items.length
+- 1; i &gt;= 0; i--) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>items[i].dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(!parent.inDispose) {</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(parentItem != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>parentItem.removeItem(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>else </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>{</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>parent.removeItem(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) tableItem.dispose();</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>items
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>parentItem
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>parent
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>images
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>texts
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>tableItem
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;<span style='mso-tab-count:1'> </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>removeItem(TableTreeItem item) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index = 0;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>while </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(index &lt; items.length
+&amp;&amp; items[index] != item) index++;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(index == items.length) </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>return</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>TableTreeItem[]
+newItems = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableTreeItem[items.length - 1];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+0, newItems, 0, index);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>System.arraycopy(items,
+index + 1, newItems, index, items.length - index - 1);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>items
+= newItems;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(items.length == 0) {</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) tableItem.setImage(0, </span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>null</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>* Sets the checked state.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>* </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;p&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>* </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>@param </span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>checked the new checked state.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>* </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>@exception </span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>SWTError </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*<span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when
+called from the wrong thread</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>&lt;/li&gt;</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*<span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the
+widget has been disposed</span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*<span style='mso-tab-count:1'>     </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setChecked (</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>boolean </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>checked) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>tableItem.setChecked(checked);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>.checked = checked;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the expanded state.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>* </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>@param </span><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>expanded the new expanded state.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setExpanded (</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>boolean </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>expanded) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(items.length == 0) </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>return</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>.expanded = expanded;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>return</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>parent.setRedraw(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>false</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>);</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+items.length; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>items[i].setVisible(expanded);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Image
+image = expanded ? parent.getMinusImage() : parent.getPlusImage();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>tableItem.setImage(0,
+image);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>parent.setRedraw(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>true</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the image at an index.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+The image can be null.</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* The image in column 0 is reserved for the [+] and [-]</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* images of the tree, therefore do nothing if index is 0.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>image the new
+image or null</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setImage (</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index, Image image) {</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>columnCount =
+Math.max(parent.getTable().getColumnCount(), 1);</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(index &lt;= 0 || index &gt;= columnCount) </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(images.length &lt; columnCount) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>Image[]
+newImages = </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:EN-US'>new
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>Image[columnCount];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>System.arraycopy(images,
+0, newImages, 0, images.length);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>images
+= newImages;</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>images[index]
+= image;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) tableItem.setImage(index, image);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the first image.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*
+The image can be null.</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* The image in column 0 is reserved for the [+] and [-]</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* images of the tree, therefore do nothing.</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>image the new
+image or null</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*/</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setImage (Image image) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>setImage(0,
+image);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the widget text.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* The widget text for an item is the label of the</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* item or the label of the text specified by a column</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* number.</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>index the column
+number</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>text the new text</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_NULL_ARGUMENT when string is null</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setText(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index, String text) {</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>columnCount =
+Math.max(parent.getTable().getColumnCount(), 1);</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(index &lt; 0 || index &gt;= columnCount) </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(texts.length &lt; columnCount) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>String[]
+newTexts = </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>String[columnCount];</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>System.arraycopy(texts,
+0, newTexts, 0, texts.length);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>texts
+= newTexts;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>texts[index]
+= text;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(tableItem != </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) tableItem.setText(index, text);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>/**</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* Sets the widget text.</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;p&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* The widget text for an item is the label of the</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* item or the label of the text specified by a column</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* number.</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>index the column
+number</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@param
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>text the new text</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>*</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span>* </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F9F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>@exception
+</span><span style='font-size:10.0pt;font-family:Courier;color:#3F7F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>SWTError </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;ul&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_THREAD_INVALID_ACCESS when called from the wrong
+thread</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_WIDGET_DISPOSED when the widget has been
+disposed</span><span style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:2'>          </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;li&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;color:#3F7F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>ERROR_NULL_ARGUMENT when string is null</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>&lt;/li&gt;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*<span
+style='mso-tab-count:1'>    </span></span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F9F5F;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>&lt;/ul&gt;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F9F5F;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span></span><span style='font-size:10.0pt;font-family:Courier;
+color:#3F7F5F;background:white;mso-highlight:white;mso-ansi-language:EN-US'>*/</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setText (String string) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>setText(0,
+string);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setVisible (</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>boolean </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>show) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(parentItem == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>return</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>; </span><span style='font-size:
+10.0pt;font-family:Courier;color:#2A7FAA;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>// this is a root and can not be toggled between
+visible and hidden</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(getVisible() == show) </span><span style='font-size:
+10.0pt;font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>return</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(show) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(!parentItem.getVisible()) </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>; </span><span style='font-size:
+10.0pt;font-family:Courier;color:#2A7FAA;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>// parentItem must already be visible</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>//
+create underlying table item and set data in table item to stored data</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Table table = parent.getTable();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>parentIndex = table.indexOf(parentItem.tableItem);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>index = parentItem.expandedIndexOf(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>) + parentIndex + 1;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(index &lt; 0) </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>return</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>tableItem
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TableItem(table, getStyle(),
+index);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>tableItem.setData(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>tableItem.setImageIndent(getIndent());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>addCheck();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>// restore fields to item</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>//
+ignore any images in the first column</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>columnCount = Math.max(table.getColumnCount(), 1);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0; i &lt;
+columnCount; i++) {</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(i &lt; texts.length &amp;&amp; texts[i] != </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>null</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>) setText(i, texts[i]);</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(i &lt; images.length &amp;&amp; images[i] != </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>null</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>) setImage(i, images[i]);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>// display the children and the
+appropriate [+]/[-] symbol as required</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(items.length != 0) {</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(expanded) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>tableItem.setImage(0,
+parent.getMinusImage());</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0, length =
+items.length; i &lt; length; i++) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:5'>                              </span>items[i].setVisible(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>true</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>else </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>{</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>tableItem.setImage(0,
+parent.getPlusImage());</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>else </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>{</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>for </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(</span><span style='font-size:10.0pt;font-family:
+Courier;color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>int </span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>i = 0, length =
+items.length; i &lt; length; i++) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>items[i].setVisible(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>false</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>);</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>// remove row from table</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#2A7FAA;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>tableItem.dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>tableItem
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>null</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>}</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal><span lang=EN-CA><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+</div>
+
+</body>
+
+</html>
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixB.htm b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixB.htm
new file mode 100644
index 0000000..29d8dcb
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixB.htm
@@ -0,0 +1,198 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<meta name="Author" content="Carolyn MacLeod">
+<title>Appendix B: SpinnerTest and Spinner</title>
+</head>
+
+<body>
+<h2>Appendix B: SpinnerTest and Spinner</h2>
+This appendix contains the source code for the <i>SpinnerTest</i> and <i>Spinner</i> classes. The <i>Spinner</i> class loads and calls the native
+code listed in either <A href="AppendixC.htm">Appendix C: Spinner For Windows</A>, or <A
+href="AppendixD.htm">Appendix D: Spinner for Motif</A>.
+<p>
+<h3><strong>SpinnerTest.java</strong></h3>
+<pre>
+<font color="#7F0055">package</font> spinner;
+<font color="maroon">
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+</font>
+<font color="#7F0055">import</font> org.eclipse.swt.*;
+<font color="#7F0055">import</font> org.eclipse.swt.widgets.*;
+<font color="#7F0055">import</font> org.eclipse.swt.events.*;
+<font color="#7F0055">import</font> org.eclipse.swt.layout.*;
+<font color="#7F0055">import</font> org.eclipse.swt.graphics.*;
+
+<font color="#7F0055">public class</font> SpinnerTest {
+
+<font color="#7F0055">public static void</font> main (String [] args) {
+ Display display = <font color="#7F0055">new</font> Display ();
+ Shell shell = <font color="#7F0055">new</font> Shell (display);
+ shell.setLayout (<font color="#7F0055">new</font> RowLayout ());
+
+ <font color="#7F0055">final</font> Spinner spinner = <font color="#7F0055">new</font> Spinner (shell, 0);
+ spinner.setMaximum (999);
+ System.out.println (<font color="blue">&quot;max set to &quot;</font> + spinner.getMaximum ());
+ spinner.setSelection (500);
+ System.out.println (<font color="blue">&quot;selection set to &quot;</font> + spinner.getSelection ());
+ spinner.setMinimum (100);
+ System.out.println (<font color="blue">&quot;min set to &quot;</font> + spinner.getMinimum ());
+ Font font = <font color="#7F0055">new</font> Font (display, &quot;Courier&quot;, 20, SWT.NORMAL);
+ spinner.setFont (font);
+ spinner.addSelectionListener (<font color="#7F0055">new</font> SelectionAdapter () {
+ <font color="#7F0055">public void</font> widgetSelected (SelectionEvent e) {
+ System.out.println (spinner.getSelection ());
+ }
+ });
+ shell.pack ();
+ shell.open ();
+ <font color="#7F0055">while</font> (!shell.isDisposed ()){
+ <font color="#7F0055">if</font> (!display.readAndDispatch ()) display.sleep ();
+ }
+ font.dispose ();
+}
+}
+</pre>
+<p>
+<h3><strong>Spinner.java</strong></h3>
+<pre>
+<font color="#7F0055">package</font> spinner;
+<font color="maroon">
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+</font>
+<font color="#7F0055">import</font> java.util.*;
+<font color="#7F0055">import</font> org.eclipse.swt.*;
+<font color="#7F0055">import</font> org.eclipse.swt.graphics.*;
+<font color="#7F0055">import</font> org.eclipse.swt.widgets.*;
+<font color="#7F0055">import</font> org.eclipse.swt.events.*;
+
+<font color="#7F0055">public class</font> Spinner <font color="#7F0055">extends</font> Composite {
+ <font color="#7F0055">int</font> handleSpinner;
+ <font color="#7F0055">static</font> Hashtable table = <font color="#7F0055">new</font> Hashtable ();
+ <font color="#7F0055">static</font> {
+ System.loadLibrary (<font color="blue">&quot;spinner&quot;</font>);
+ }
+
+ <font color="#7F0055">public</font> Spinner (Composite parent, <font color="#7F0055">int</font> style) {
+ <font color="#7F0055">super</font> (parent, style);
+ <font color="#7F0055">int</font> handleParent = handle;
+ handleSpinner = createControl (handleParent);
+ <font color="#7F0055">if</font> (handleSpinner == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ table.put (<font color="#7F0055">new</font> Integer (handleSpinner), <font color="#7F0055">this</font>);
+ addDisposeListener (<font color="#7F0055">new</font> DisposeListener () {
+ <font color="#7F0055">public void</font> widgetDisposed (DisposeEvent e) {
+ Spinner.<font color="#7F0055">this</font>.widgetDisposed (e);
+ }
+ });
+ addControlListener (<font color="#7F0055">new</font> ControlAdapter () {
+ <font color="#7F0055">public void</font> controlResized (ControlEvent e) {
+ Spinner.<font color="#7F0055">this</font>.controlResized (e);
+ }
+ });
+ addFocusListener (<font color="#7F0055">new</font> FocusAdapter () {
+ <font color="#7F0055">public void</font> focusGained (FocusEvent e) {
+ Spinner.<font color="#7F0055">this</font>.focusGained (e);
+ }
+ });
+ Font font = getFont ();
+ setFont (handleSpinner, font.handle);
+ }
+
+ <font color="#7F0055">public void</font> setFont (Font font) {
+ <font color="#7F0055">super</font>.setFont (font);
+ <font color="#7F0055">int</font> hFont = 0;
+ <font color="#7F0055">if</font> (font != <font color="#7F0055">null</font>) hFont = font.handle;
+ setFont (handleSpinner, hFont);
+ }
+
+ <font color="#7F0055">public int</font> getSelection () {
+ checkWidget ();
+ <font color="#7F0055">return</font> getPosition (handleSpinner);
+ }
+
+ <font color="#7F0055">public void</font> setSelection (<font color="#7F0055">int</font> selection) {
+ checkWidget ();
+ setPosition (handleSpinner, selection);
+ }
+
+ <font color="#7F0055">public void</font> setMaximum (<font color="#7F0055">int</font> maximum) {
+ checkWidget ();
+ setMaximum (handleSpinner, maximum);
+ }
+
+ <font color="#7F0055">public int</font> getMaximum () {
+ checkWidget ();
+ <font color="#7F0055">return</font> getMaximum (handleSpinner);
+ }
+
+ <font color="#7F0055">public void</font> setMinimum (<font color="#7F0055">int</font> minimum) {
+ checkWidget ();
+ setMinimum (handleSpinner, minimum);
+ }
+
+ <font color="#7F0055">public int</font> getMinimum () {
+ checkWidget ();
+ <font color="#7F0055">return</font> getMinimum (handleSpinner);
+ }
+
+ <font color="#7F0055">public void</font> widgetDisposed (DisposeEvent e) {
+ table.remove (<font color="#7F0055">new</font> Integer (handleSpinner));
+ handleSpinner = 0;
+ }
+
+ <font color="#7F0055">public void</font> controlResized (ControlEvent e) {
+ Rectangle rect = getClientArea ();
+ resizeControl (handleSpinner, rect.x, rect.y, rect.width, rect.height);
+ }
+
+ <font color="#7F0055">public void</font> focusGained (FocusEvent e) {
+ setFocus (handleSpinner);
+ }
+
+ <font color="#7F0055">public</font> Point computeSize (<font color="#7F0055">int</font> wHint, <font color="#7F0055">int</font> hHint, <font color="#7F0055">boolean</font> changed) {
+ checkWidget ();
+ <font color="#7F0055">int</font> [] result = <font color="#7F0055">new int</font> [2];
+ computeSize (handleSpinner, result);
+ <font color="#7F0055">if</font> (wHint != SWT.DEFAULT) result [0] = wHint;
+ <font color="#7F0055">if</font> (hHint != SWT.DEFAULT) result [1] = hHint;
+ <font color="#7F0055">int</font> border = getBorderWidth ();
+ <font color="#7F0055">return</font> new Point (result [0] + border * 2, result [1] + border * 2);
+ }
+
+ <font color="#7F0055">public void</font> addSelectionListener (SelectionListener listener) {
+ <font color="#7F0055">if</font> (listener == <font color="#7F0055">null</font>) <font color="#7F0055">throw new</font> SWTError (SWT.ERROR_NULL_ARGUMENT);
+ addListener (SWT.Selection, <font color="#7F0055">new</font> TypedListener (listener));
+ }
+
+ <font color="#7F0055">static void</font> widgetSelected (<font color="#7F0055">int</font> handle) {
+ Spinner spinner = (Spinner) table.get (<font color="#7F0055">new</font> Integer (handle));
+ <font color="#7F0055">if</font> (spinner == <font color="#7F0055">null</font>) <font color="#7F0055">return</font>;
+ spinner.notifyListeners (SWT.Selection, <font color="#7F0055">new</font> Event ());
+ }
+
+ <font color="#3F7F5F">/*********** JAVA NATIVES ************/</font>
+
+ <font color="#7F0055">static final native int</font> createControl (<font color="#7F0055">int</font> handle);
+ <font color="#7F0055">static final native void</font> computeSize (<font color="#7F0055">int</font> handle, <font color="#7F0055">int</font> [] result);
+ <font color="#7F0055">static final native void</font> resizeControl (<font color="#7F0055">int</font> handle, <font color="#7F0055">int</font> x, <font color="#7F0055">int</font> y, <font color="#7F0055">int</font> width, <font color="#7F0055">int</font> height);
+ <font color="#7F0055">static final native void</font> setPosition (<font color="#7F0055">int</font> handle, <font color="#7F0055">int</font> position);
+ <font color="#7F0055">static final native int</font> getPosition (<font color="#7F0055">int</font> handle);
+ <font color="#7F0055">static final native void</font> setMaximum (<font color="#7F0055">int</font> handle, <font color="#7F0055">int</font> max);
+ <font color="#7F0055">static final native int</font> getMaximum (<font color="#7F0055">int</font> handle);
+ <font color="#7F0055">static final native void</font> setMinimum (<font color="#7F0055">int</font> handle, <font color="#7F0055">int</font> min);
+ <font color="#7F0055">static final native int</font> getMinimum (<font color="#7F0055">int</font> handle);
+ <font color="#7F0055">static final native void</font> setFont (<font color="#7F0055">int</font> handle, <font color="#7F0055">int</font> hFont);
+ <font color="#7F0055">static final native void</font> setFocus (<font color="#7F0055">int</font> handle);
+}
+</pre>
+</body>
+</html>
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixC.htm b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixC.htm
new file mode 100644
index 0000000..902cc6c
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixC.htm
@@ -0,0 +1,313 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<meta name="Author" content="Carolyn MacLeod">
+<title>Appendix C: Spinner for Windows</title>
+</head>
+
+<body>
+<h2>Appendix C: Spinner for Windows</h2>
+This appendix contains the source code for the Windows version of the <i>Spinner</i> natives in spinner.c, and the batch file and makefile for building the Windows Dynamic Link Library
+spinner.dll.
+<h3><strong>spinner.c</strong></h3>
+<pre>
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+#include &lt;jni.h&gt;
+#include &lt;windows.h&gt;
+#include &lt;commctrl.h&gt;
+
+static DWORD tlsIndex = 0;
+static jobject javaClass;
+static jmethodID mid;
+static WNDPROC oldProc;
+
+LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ JNIEnv *env = TlsGetValue(tlsIndex);
+ if (env != NULL) {
+ /* If an exception has already occurred,
+ * allow the stack to unwind so that the
+ * exception will be thrown in Java. */
+ if ((*env)-&gt;ExceptionOccurred(env)) return 0;
+ switch (msg) {
+ case WM_VSCROLL:
+ if ((wParam &amp; 0xFFFF) == SB_THUMBPOSITION) {
+ ((*env)-&gt;CallStaticVoidMethod(env, javaClass, mid, lParam));
+ return (LRESULT) 0;
+ }
+ break;
+ }
+ }
+ return CallWindowProc(oldProc, hwnd, msg, wParam, lParam);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: createControl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_spinner_Spinner_createControl
+ (JNIEnv *env, jclass that, jint hwndParent)
+{
+ HWND hwndText, hwndUpDown;
+ if (tlsIndex == 0) {
+ tlsIndex = TlsAlloc();
+ if (tlsIndex == -1) return (jint) 0;
+ javaClass = (*env)-&gt;NewGlobalRef(env, (jobject) that);
+ mid = (*env)-&gt;GetStaticMethodID(env, (jobject) that, &quot;widgetSelected&quot;, &quot;(I)V&quot;);
+ oldProc = (WNDPROC) GetWindowLong((HWND) hwndParent, GWL_WNDPROC);
+ }
+ TlsSetValue(tlsIndex, (LPVOID) env);
+
+ hwndText = CreateWindowEx(
+ WS_EX_CLIENTEDGE,
+ &quot;EDIT&quot;,
+ NULL,
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP,
+ 0, 0, 0, 0,
+ (HWND) hwndParent,
+ 0,
+ GetModuleHandle(NULL),
+ NULL);
+ if (hwndText == 0) return (jint) 0;
+ hwndUpDown = CreateWindowEx(
+ 0,
+ UPDOWN_CLASS,
+ NULL,
+ WS_CHILD | WS_VISIBLE | UDS_AUTOBUDDY | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,
+ 0, 0, 0, 0,
+ (HWND) hwndParent,
+ 0,
+ GetModuleHandle(NULL),
+ NULL);
+ if (hwndUpDown == 0) return (jint) 0;
+ SetWindowLong((HWND) hwndParent, GWL_WNDPROC, (long) WindowProc);
+ return (jint) hwndUpDown;
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: computeSize
+ * Signature: (I[I)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_computeSize
+ (JNIEnv *env, jclass that, jint hwndUpDown, jintArray result) {
+ int width, height;
+ TEXTMETRIC tm;
+ RECT rect;
+ int comboHeight;
+ int max, digits;
+ UINT flags;
+ char text[64];
+ HWND hwndText = (HWND) SendMessage((HWND) hwndUpDown, UDM_GETBUDDY, 0, 0);
+ HDC hDC = GetDC(hwndText);
+ HFONT oldFont = 0;
+ HFONT newFont = (HFONT) SendMessage(hwndText, WM_GETFONT, 0, 0);
+
+ jint *result1 = NULL;
+ result1 = (*env)-&gt;GetIntArrayElements(env, result, NULL);
+
+ if (newFont != 0) oldFont = SelectObject(hDC, newFont);
+ GetTextMetrics(hDC, &amp;tm);
+ comboHeight = GetSystemMetrics(SM_CYVSCROLL);
+ height = (comboHeight &gt; tm.tmHeight) ? comboHeight : tm.tmHeight;
+ max = SendMessage((HWND) hwndUpDown, UDM_GETRANGE, 0, 0) &amp; 0xFFFF;
+ if (max &gt; 0) {
+ digits = 0;
+ while (max &gt; 0) {
+ text[digits] = '0';
+ max /= 10;
+ digits++;
+ }
+ flags = DT_CALCRECT | DT_EDITCONTROL | DT_NOPREFIX;
+ DrawText(hDC, (LPCTSTR) text, digits, (LPRECT) &amp;rect, flags);
+ width = rect.right - rect.left + 3;
+ } else {
+ width = 10;
+ }
+ if (newFont != 0) SelectObject(hDC, oldFont);
+ ReleaseDC(hwndText, hDC);
+ width += GetSystemMetrics(SM_CXVSCROLL);
+ SendMessage(hwndText, EM_GETRECT, 0, (LPARAM) &amp;rect);
+ if (rect.top == 0) rect.top = 1; // windows bug fix
+ width += (rect.left + 1) * 2;
+ height += (rect.top + 1) * 2;
+
+ result1 [0] = width;
+ result1 [1] = height;
+ (*env)-&gt;ReleaseIntArrayElements(env, result, result1, 0);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: resizeControl
+ * Signature: (IIIII)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_resizeControl
+ (JNIEnv *env, jclass that, jint hwndUpDown, jint x, jint y, jint width, jint height)
+{
+ HWND hwndText = (HWND) SendMessage((HWND) hwndUpDown, UDM_GETBUDDY, 0, 0);
+ UINT flags = SWP_NOZORDER | SWP_DRAWFRAME | SWP_NOACTIVATE;
+ int upDownWidth = GetSystemMetrics(SM_CXVSCROLL);
+ SetWindowPos(hwndText, (HWND) 0, x, y, width - upDownWidth + 2, height, flags);
+ SetWindowPos((HWND) hwndUpDown, (HWND) 0, x + width - upDownWidth, y, upDownWidth, height, flags);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setPosition
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setPosition
+ (JNIEnv *env, jclass that, jint hwnd, jint position)
+{
+ SendMessage((HWND) hwnd, UDM_SETPOS, 0, position);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: getPosition
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_spinner_Spinner_getPosition
+ (JNIEnv *env, jclass that, jint hwnd)
+{
+ return (jint) SendMessage((HWND) hwnd, UDM_GETPOS, 0, 0) &amp; 0xFFFF;
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setMaximum
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setMaximum
+ (JNIEnv *env, jclass that, jint hwnd, jint max)
+{
+ int min = SendMessage((HWND) hwnd, UDM_GETRANGE, 0, 0) &gt;&gt; 16;
+ SendMessage((HWND) hwnd, UDM_SETRANGE, 0, (min &lt;&lt; 16) | max);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: getMaximum
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_spinner_Spinner_getMaximum
+ (JNIEnv *env, jclass that, jint hwnd)
+{
+ return SendMessage((HWND) hwnd, UDM_GETRANGE, 0, 0) &amp; 0xFFFF;
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setMinimum
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setMinimum
+ (JNIEnv *env, jclass that, jint hwnd, jint min)
+{
+ int max = SendMessage((HWND) hwnd, UDM_GETRANGE, 0, 0) &amp; 0xFFFF;
+ SendMessage((HWND) hwnd, UDM_SETRANGE, 0, (min &lt;&lt; 16) | max);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: getMinimum
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_spinner_Spinner_getMinimum
+ (JNIEnv *env, jclass that, jint hwnd)
+{
+ return SendMessage((HWND) hwnd, UDM_GETRANGE, 0, 0) &gt;&gt; 16;
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setFont
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setFont
+ (JNIEnv *env, jclass that, jint hwnd, jint hFont)
+{
+ HWND hwndText = (HWND) SendMessage((HWND) hwnd, UDM_GETBUDDY, 0, 0);
+ SendMessage(hwndText, WM_SETFONT, hFont, 1);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setFocus
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setFocus
+ (JNIEnv *env, jclass that, jint hwnd)
+{
+ HWND hwndText = (HWND) SendMessage((HWND) hwnd, UDM_GETBUDDY, 0, 0);
+ SetFocus(hwndText);
+}
+</pre>
+<p>
+<h3><strong>build.bat</strong></h3>
+<pre>
+@echo off
+
+IF NOT &quot;%IVE_HOME%&quot;==&quot;&quot; GOTO MAKE
+
+set IVE_HOME=j:\teamswt\swt-builddir\ive\bin
+set path=%IVE_HOME%;%path%
+
+rem NOTE:
+rem Initialize MSVC 6.0/MSSDK environment
+call k:\dev\products\msvc60\vc98\bin\vcvars32.bat
+set Mssdk=j:\teamswt\swt-builddir\mssdk
+call %Mssdk%\setenv.bat
+
+:MAKE
+nmake makefile.mak
+</pre>
+<p>
+<h3><strong>makefile.mak</strong></h3>
+<pre>
+# Makefile for module 'spinner.dll'
+# assumes IVE_HOME is set in the environment from which nmake is run
+
+!include &lt;win32.mak&gt;
+
+DLLPREFIX=spinner
+DLLNAME=$(DLLPREFIX).dll
+
+CFLAGS=-c -W3 -G6 -GD -O1 -nologo -D_X86_=1 -D_WIN32 -D_WIN95 -D_WIN32_WINDOWS=0x0400 -D_MT -MT -DWIN32 -D_WIN32_DCOM /I$(IVE_HOME)\include /I.
+LFLAGS=/INCREMENTAL:NO /PDB:NONE /RELEASE /NOLOGO /BASE:0x10000000 /DLL
+
+LINK_LIBS=comctl32.lib user32.lib gdi32.lib
+
+OBJS=$(DLLPREFIX).obj
+
+all: $(OBJS) $(DLLPREFIX)
+
+$(DLLPREFIX): $(OBJS)
+ echo $(LINK_LIBS) &gt;templrf
+ echo $(LFLAGS) &gt;&gt;templrf
+ echo -machine:IX86 &gt;&gt;templrf
+ echo -subsystem:windows &gt;&gt;templrf
+ echo -out:$(DLLNAME) &gt;&gt;templrf
+ echo $(OBJS) &gt;&gt;templrf
+ link @templrf
+ del templrf
+
+clean:
+ del *.obj
+ del *.dll
+ del *.exp
+
+.c.obj:
+ cl $(CFLAGS) $*.c
+</pre>
+</body>
+
+</html>
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixD.htm b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixD.htm
new file mode 100644
index 0000000..6e7531c
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixD.htm
@@ -0,0 +1,317 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<meta name="Author" content="Carolyn MacLeod">
+<title>Appendix D: Spinner for Motif</title>
+</head>
+
+<body>
+<h2>Appendix D: Spinner for Motif</h2>
+This appendix contains the source code for the Motif version of the <i>Spinner</i> natives in spinner.c, and the shell file and makefile for building the Motif Shared Object Library
+libspinner.so.
+<h3><strong>spinner.c</strong></h3>
+<pre>
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+#include &lt;jni.h&gt;
+#include &lt;Xm/XmAll.h&gt;
+#include &lt;pthread.h&gt;
+#include &lt;stdio.h&gt;
+
+#define ARROW_WIDTH 19
+#define SPACING 2
+
+static jobject javaClass;
+static jmethodID mid;
+static pthread_key_t envKey;
+
+int Callback(Widget handle, XtPointer clientData, XmAnyCallbackStruct * callData) {
+ JNIEnv *env = (JNIEnv *) pthread_getspecific(envKey);
+ if (env != NULL) {
+ /* If an exception has already occurred,
+ * allow the stack to unwind so that the
+ * exception will be thrown in Java. */
+ if ((*env)-&gt;ExceptionOccurred(env)) return 0;
+ switch (callData-&gt;reason) {
+ //case XmCR_SPIN_NEXT:
+ //case XmCR_SPIN_PRIOR:
+ case XmCR_OK:
+ ((*env)-&gt;CallStaticVoidMethod(env, javaClass, mid, handle));
+ return 0;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: createControl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_spinner_Spinner_createControl
+ (JNIEnv *env, jclass that, jint handleParent)
+{
+ Widget handleSpinBox;
+ Arg argList[10];
+ int n = 0;
+ XtSetArg(argList[n], XmNspinBoxChildType, XmNUMERIC); n++;
+ XtSetArg(argList[n], XmNarrowLayout, XmARROWS_END); n++;
+ handleSpinBox = XmCreateSimpleSpinBox((Widget) handleParent, NULL, argList, n);
+ if (handleSpinBox == 0) return 0;
+ XtManageChild(handleSpinBox);
+ XtAddCallback(handleSpinBox, XmNvalueChangedCallback, (XtCallbackProc) Callback, NULL);
+ if (javaClass == 0) {
+ javaClass = (*env)-&gt;NewGlobalRef(env, (jobject) that);
+ mid = (*env)-&gt;GetStaticMethodID(env, (jobject) that, &quot;widgetSelected&quot;, &quot;(I)V&quot;);
+ pthread_key_create(&amp;envKey, NULL);
+ }
+ pthread_setspecific(envKey, env);
+ return (jint) handleSpinBox;
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: computeSize
+ * Signature: (I[I)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_computeSize
+ (JNIEnv *env, jclass that, jint handleSpinBox, jintArray result)
+{
+ Dimension width, height;
+ Arg argList[10];
+ int n;
+ Widget handleText;
+ XmFontList fontList;
+ Dimension sbShadowThickness, textMarginWidth, textMarginHeight, textShadowThickness;
+ int max, digits;
+ char text [64];
+ XmString xmString;
+
+ jint *result1 = NULL;
+ result1 = (*env)-&gt;GetIntArrayElements(env, result, NULL);
+
+ n = 0;
+ XtSetArg(argList[n], XmNtextField, &amp;handleText); n++;
+ XtSetArg(argList[n], XmNmaximumValue, &amp;max); n++;
+ XtSetArg(argList[n], XmNshadowThickness, &amp;sbShadowThickness); n++;
+ XtGetValues((Widget) handleSpinBox, argList, n);
+
+ n = 0;
+ XtSetArg(argList[n], XmNfontList, &amp;fontList); n++;
+ XtSetArg(argList[n], XmNmarginWidth, &amp;textMarginWidth); n++;
+ XtSetArg(argList[n], XmNmarginHeight, &amp;textMarginHeight); n++;
+ XtSetArg(argList[n], XmNshadowThickness, &amp;textShadowThickness); n++;
+ XtGetValues(handleText, argList, n);
+
+ if (max &gt; 0) {
+ digits = 0;
+ while (max &gt; 0) {
+ text[digits] = '0';
+ max /= 10;
+ digits++;
+ }
+ text [digits] = 0;
+ xmString = XmStringParseText(
+ (XtPointer) text,
+ (XtPointer *) NULL,
+ XmFONTLIST_DEFAULT_TAG,
+ XmCHARSET_TEXT,
+ (XmParseTable) NULL,
+ 0,
+ (XtPointer) 0);
+ width = XmStringWidth(fontList, xmString);
+ height = XmStringHeight(fontList, xmString);
+ XmStringFree(xmString);
+ } else {
+ width = 200;
+ height = 50;
+ }
+
+ // Add in the margins.
+ width += textMarginWidth * 2 + textShadowThickness * 2 + sbShadowThickness * 2 + ARROW_WIDTH + SPACING;
+ height += textMarginHeight * 2 + textShadowThickness * 2 + sbShadowThickness * 2;
+ result1 [0] = width;
+ result1 [1] = height;
+ (*env)-&gt;ReleaseIntArrayElements(env, result, result1, 0);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: resizeControl
+ * Signature: (IIIII)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_resizeControl
+ (JNIEnv *env, jclass that, jint handleSpinBox, jint x, jint y, jint width, jint height)
+{
+ Arg arg;
+ Widget handleText;
+ XtSetArg(arg, XmNtextField, &amp;handleText);
+ XtGetValues((Widget) handleSpinBox, &amp;arg, 1);
+ XtResizeWidget((Widget) handleSpinBox, width, height, 0);
+ XtResizeWidget(handleText, width - ARROW_WIDTH, height, 0);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setPosition
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setPosition
+ (JNIEnv *env, jclass that, jint handle, jint position)
+{
+ Arg arg;
+ XtSetArg(arg, XmNposition, position);
+ XtSetValues((Widget) handle, &amp;arg, 1);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: getPosition
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_spinner_Spinner_getPosition
+ (JNIEnv *env, jclass that, jint handle)
+{
+ Arg arg;
+ int pos;
+ XtSetArg(arg, XmNposition, &amp;pos);
+ XtGetValues((Widget) handle, &amp;arg, 1);
+ return (jint) pos;
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setMaximum
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setMaximum
+ (JNIEnv *env, jclass that, jint handle, jint max)
+{
+ Arg arg;
+ XtSetArg(arg, XmNmaximumValue, max);
+ XtSetValues((Widget) handle, &amp;arg, 1);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: getMaximum
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_spinner_Spinner_getMaximum
+ (JNIEnv *env, jclass that, jint handle)
+{
+ Arg arg;
+ int max;
+ XtSetArg(arg, XmNmaximumValue, &amp;max);
+ XtGetValues((Widget) handle, &amp;arg, 1);
+ return (jint) max;
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setMinimum
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setMinimum
+ (JNIEnv *env, jclass that, jint handle, jint min)
+{
+ Arg arg;
+ XtSetArg(arg, XmNminimumValue, min);
+ XtSetValues((Widget) handle, &amp;arg, 1);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: getMinimum
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_spinner_Spinner_getMinimum
+ (JNIEnv *env, jclass that, jint handle)
+{
+ Arg arg;
+ int min;
+ XtSetArg(arg, XmNminimumValue, &amp;min);
+ XtGetValues((Widget) handle, &amp;arg, 1);
+ return (jint) min;
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setFont
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setFont
+ (JNIEnv *env, jclass that, jint handle, jint fontList)
+{
+ Arg arg;
+ Widget handleText;
+ XtSetArg(arg, XmNtextField, &amp;handleText);
+ XtGetValues((Widget) handle, &amp;arg, 1);
+ XtSetArg(arg, XmNfontList, (XmFontList) fontList);
+ XtSetValues(handleText, &amp;arg, 1);
+}
+
+/*
+ * Class: spinner_Spinner
+ * Method: setFocus
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_spinner_Spinner_setFocus
+ (JNIEnv *env, jclass that, jint handle)
+{
+ Arg arg;
+ Widget handleText;
+ XtSetArg(arg, XmNtextField, &amp;handleText);
+ XtGetValues((Widget) handle, &amp;arg, 1);
+ XSetInputFocus(XtDisplay(handleText), XtWindow(handleText), RevertToParent, CurrentTime);
+}
+</pre>
+<p>
+<h3><strong>build.csh</strong></h3>
+<pre>
+#!/bin/csh
+
+setenv IVE_HOME /bluebird/teamswt/swt-builddir/ive/bin
+setenv MOTIF_HOME /bluebird/teamswt/swt-builddir/motif21
+setenv X_HOME /usr/X11R6
+set path=($IVE_HOME $path)
+setenv LD_LIBRARY_PATH .:$IVE_HOME
+
+make -f makefile.mak</pre>
+<p>
+<h3><strong>makefile.mak</strong></h3>
+<pre>
+# Makefile for module 'libspinner.so'
+# assumes IVE_HOME, MOTIF_HOME, and X_HOME are set in the environment
+
+# NOTE:
+# We use the VPATH directive to allow the generic UNIX source files to be
+# located in a single directory. IX make does not understand VPATH so
+# you must use a 'make' which does understand it (like LINUX make)
+VPATH= ../:../../common
+
+DLLPREFIX=spinner
+DLLNAME=lib$(DLLPREFIX).so
+
+CFLAGS=-fpic -O -s -DLINUX -DMOTIF -I./ -I../ -I$(IVE_HOME)/include -I$(MOTIF_HOME)/include -I$(X_HOME)/include
+LFLAGS=-L$(MOTIF_HOME)/lib -lXm -L/usr/lib -L/usr/X11R6/lib -rpath . -x -shared -lX11 -lm -lXext -lXt
+OBJS = spinner.o
+
+all: $(DLLNAME)
+
+$(DLLNAME): $(OBJS)
+ ld $(LFLAGS) -o $(DLLNAME) $(OBJS)
+
+clean:
+ rm -f *.o
+ rm -f $(DLLNAME)
+</pre>
+</body>
+
+</html>
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE.htm b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE.htm
new file mode 100644
index 0000000..653771b
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE.htm
@@ -0,0 +1,1517 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml"
+xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List href="./AppendixE_files/filelist.xml">
+<title>Appendix E: Spinner for Any Platform</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Author>Dave Thomson</o:Author>
+ <o:LastAuthor>Carolyn MacLeod</o:LastAuthor>
+ <o:Revision>6</o:Revision>
+ <o:TotalTime>33</o:TotalTime>
+ <o:Created>2001-06-04T02:59:00Z</o:Created>
+ <o:LastSaved>2001-06-04T04:15:00Z</o:LastSaved>
+ <o:Pages>3</o:Pages>
+ <o:Words>489</o:Words>
+ <o:Characters>2792</o:Characters>
+ <o:Lines>23</o:Lines>
+ <o:Paragraphs>5</o:Paragraphs>
+ <o:CharactersWithSpaces>3428</o:CharactersWithSpaces>
+ <o:Version>9.2720</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+ {font-family:Courier;
+ panose-1:0 0 0 0 0 0 0 0 0 0;
+ mso-font-charset:0;
+ mso-generic-font-family:modern;
+ mso-font-format:other;
+ mso-font-pitch:fixed;
+ mso-font-signature:3 0 0 0 1 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ mso-ansi-language:EN-CA;}
+h1
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:20.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ color:windowtext;
+ mso-font-kerning:14.0pt;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+h2
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:2;
+ font-size:18.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+h3
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:3;
+ font-size:14.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc1, li.MsoToc1, div.MsoToc1
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:.25in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ text-transform:uppercase;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc2, li.MsoToc2, div.MsoToc2
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+p.MsoToc3, li.MsoToc3, div.MsoToc3
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:10.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc4, li.MsoToc4, div.MsoToc4
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:20.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc5, li.MsoToc5, div.MsoToc5
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:30.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc6, li.MsoToc6, div.MsoToc6
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:40.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc7, li.MsoToc7, div.MsoToc7
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:50.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc8, li.MsoToc8, div.MsoToc8
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:60.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoToc9, li.MsoToc9, div.MsoToc9
+ {mso-style-update:auto;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:70.0pt;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoHeader, li.MsoHeader, div.MsoHeader
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoFooter, li.MsoFooter, div.MsoFooter
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:windowtext;}
+p.MsoBodyText, li.MsoBodyText, div.MsoBodyText
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:red;}
+p.MsoBodyText2, li.MsoBodyText2, div.MsoBodyText2
+ {margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in;
+ layout-grid-mode:char;
+ font-size:9.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:black;}
+a:link, span.MsoHyperlink
+ {color:blue;
+ text-decoration:underline;
+ text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+ {color:purple;
+ text-decoration:underline;
+ text-underline:single;}
+strong
+ {mso-bidi-font-weight:normal;}
+em
+ {mso-bidi-font-style:normal;}
+p
+ {margin-top:5.0pt;
+ margin-right:0in;
+ margin-bottom:5.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";
+ color:black;}
+code
+ {mso-ascii-font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-hansi-font-family:"Courier New";
+ mso-bidi-font-family:"Times New Roman";}
+p.Code, li.Code, div.Code
+ {mso-style-name:Code;
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in 2.25in 2.5in 2.75in 3.0in 3.25in 3.5in 3.75in 4.0in 4.25in 4.5in 4.75in 5.0in 5.25in 5.5in 5.75in;
+ layout-grid-mode:char;
+ font-size:9.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:windowtext;}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-title-page:yes;
+ mso-even-footer:url("./AppendixE_files/header.htm") ef1;
+ mso-footer:url("./AppendixE_files/header.htm") f1;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US link=blue vlink=purple style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<h2><a name="_Ref506190577"></a><a name="_Toc506634654"><span style='mso-bookmark:
+_Ref506190577'>Appendix E: Spinner for Any Platform</span></a></h2>
+
+<p class=MsoNormal><span lang=EN-CA>This appendix contains the source code for
+a <i style='mso-bidi-font-style:normal'>Spinner</i> class that will run on any
+platform.</span><span style='mso-bidi-font-size:10.0pt;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=Code><span style='color:navy'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>package </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>spinner;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in 2.25in 2.5in 2.75in 3.0in 3.25in 3.5in 3.75in 4.0in 4.25in 4.5in 4.75in 5.0in 5.25in 5.5in 5.75in 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+lang=EN-CA style='font-size:9.0pt;mso-bidi-font-size:12.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:maroon;layout-grid-mode:line'>/*</span><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:maroon;mso-ansi-language:EN-US;
+layout-grid-mode:line'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in 2.25in 2.5in 2.75in 3.0in 3.25in 3.5in 3.75in 4.0in 4.25in 4.5in 4.75in 5.0in 5.25in 5.5in 5.75in 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='font-size:9.0pt;mso-bidi-font-size:12.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:maroon;layout-grid-mode:line'><span
+style="mso-spacerun: yes"> </span><span lang=EN-CA>* (c) Copyright IBM Corp.
+2000, 2001.<o:p></o:p></span></span></p>
+
+<p class=MsoNormal style='tab-stops:.25in .5in .75in 1.0in 1.25in 1.5in 1.75in 2.0in 2.25in 2.5in 2.75in 3.0in 3.25in 3.5in 3.75in 4.0in 4.25in 4.5in 4.75in 5.0in 5.25in 5.5in 5.75in 6.0in 456.0pt 480.0pt 7.0in 528.0pt 552.0pt 8.0in 600.0pt 624.0pt 9.0in 672.0pt 696.0pt 10.0in 744.0pt 768.0pt'><span
+style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:"Courier New";
+mso-bidi-font-family:"Times New Roman";color:maroon;mso-ansi-language:EN-US;
+layout-grid-mode:line'><span style="mso-spacerun: yes"> </span>* All Rights Reserved.<o:p></o:p></span></p>
+
+<p class=Code><span style='color:maroon;layout-grid-mode:line'><span
+style="mso-spacerun: yes"> </span>*/<o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>java.util.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.graphics.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.widgets.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>import </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>org.eclipse.swt.events.*;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public class </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Spinner </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>extends </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Composite {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>static final int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>BUTTON_WIDTH = 16;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Text
+text;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>Button
+up, down;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>minimum, maximum;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Spinner(Composite parent, </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>style) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(parent, style);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>text
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Text(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>, style | SWT.SINGLE | SWT.BORDER);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>up
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Button(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>, style | SWT.ARROW | SWT.UP);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>down
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Button(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>, style | SWT.ARROW | SWT.DOWN);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>text.addListener(SWT.Verify,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>verify(e);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>text.addListener
+(SWT.Traverse, </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:EN-US'>new
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>Listener () {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>traverse(e);<span
+style='mso-tab-count:3'>                  </span></span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>up.addListener(SWT.Selection,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>up();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>down.addListener(SWT.Selection,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>down();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>addListener(SWT.Resize,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>resize();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>addListener(SWT.FocusIn,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Listener() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>handleEvent(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>focusIn();<span
+style='mso-tab-count:3'>              </span></span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>});</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>text.setFont(getFont());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>minimum
+= 0;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>maximum
+= 9;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>setSelection(minimum);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>verify(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>try </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>{</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>Integer.parseInt(e.text);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>catch </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(NumberFormatException ex) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>e.doit
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>false</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>traverse(Event e) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>switch </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(e.detail) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>case </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWT.TRAVERSE_ARROW_PREVIOUS:</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(e.keyCode == SWT.ARROW_UP) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:5'>                              </span>e.doit
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>true</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:5'>                              </span>e.detail
+= SWT.NULL;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:5'>                              </span>up();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>break</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>case </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWT.TRAVERSE_ARROW_NEXT:</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(e.keyCode == SWT.ARROW_DOWN) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:5'>                              </span>e.doit
+= </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>true</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:5'>                              </span>e.detail
+= SWT.NULL;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:5'>                              </span>down();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:4'>                        </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>break</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>up() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>setSelection(getSelection()
++ 1);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>notifyListeners(SWT.Selection,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Event());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>down() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>setSelection(getSelection()
+- 1);</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>notifyListeners(SWT.Selection,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Event());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>focusIn() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>text.setFocus();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setFont(Font font) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>super</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>.setFont(font);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>text.setFont(font);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setSelection(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>selection) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(selection &lt; minimum) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>selection
+= minimum;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>else if </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>(selection &gt; maximum) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:3'>                  </span>selection
+= maximum;</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>text.setText(String.valueOf(selection));</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>text.selectAll();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>text.setFocus();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getSelection() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Integer.parseInt(text.getText());</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setMaximum(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>maximum) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>checkWidget();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>.maximum = maximum;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>resize();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getMaximum() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>maximum;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>setMinimum(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>minimum) {</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>this</span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>.minimum = minimum;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public int </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>getMinimum() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>minimum;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:1'>     </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>resize() {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>Point
+pt = computeSize(SWT.DEFAULT, SWT.DEFAULT);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>textWidth = pt.x - BUTTON_WIDTH;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>buttonHeight = pt.y / 2;</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span>text.setBounds(0,
+0, textWidth, pt.y);</span><span style='font-size:10.0pt;font-family:Courier;
+mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span>up.setBounds(textWidth,
+0, BUTTON_WIDTH, buttonHeight);</span><span style='font-size:10.0pt;font-family:
+Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span>down.setBounds(textWidth,
+pt.y - buttonHeight, BUTTON_WIDTH, buttonHeight);</span><span style='font-size:
+10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:1'>     </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:1'>     </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Point computeSize(</span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>wHint, </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>int </span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>hHint, </span><span style='font-size:10.0pt;font-family:Courier;
+color:#7F0055;background:white;mso-highlight:white;mso-ansi-language:EN-US'>boolean
+</span><span style='font-size:10.0pt;font-family:Courier;color:black;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>changed) {</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span>GC gc = </span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>new </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>GC(text);</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>Point
+textExtent = gc.textExtent(String.valueOf(maximum));</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>gc.dispose();</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>Point
+pt = text.computeSize(textExtent.x, textExtent.y);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>width = pt.x + BUTTON_WIDTH;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>int </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>height = pt.y;</span><span style='font-size:10.0pt;
+font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(wHint != SWT.DEFAULT) width = wHint;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(hHint != SWT.DEFAULT) height = hHint;</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:2'>           </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>return new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>Point(width, height);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style="mso-spacerun:
+yes"> </span><span style='mso-tab-count:1'>     </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>public void </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>addSelectionListener(SelectionListener
+listener) {</span><span style='font-size:10.0pt;font-family:Courier;mso-ansi-language:
+EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span></span><span
+style='font-size:10.0pt;font-family:Courier;color:#7F0055;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>if </span><span style='font-size:
+10.0pt;font-family:Courier;color:black;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>(listener == </span><span style='font-size:10.0pt;
+font-family:Courier;color:#7F0055;background:white;mso-highlight:white;
+mso-ansi-language:EN-US'>null</span><span style='font-size:10.0pt;font-family:
+Courier;color:black;background:white;mso-highlight:white;mso-ansi-language:
+EN-US'>) </span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>throw new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>SWTError(SWT.ERROR_NULL_ARGUMENT);</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:2'>            </span>addListener(SWT.Selection,
+</span><span style='font-size:10.0pt;font-family:Courier;color:#7F0055;
+background:white;mso-highlight:white;mso-ansi-language:EN-US'>new </span><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'>TypedListener(listener));</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-layout-grid-align:none;text-autospace:none'><span
+style='font-size:10.0pt;font-family:Courier;color:black;background:white;
+mso-highlight:white;mso-ansi-language:EN-US'><span style='mso-tab-count:1'>      </span>}</span><span
+style='font-size:10.0pt;font-family:Courier;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal><span style='font-size:10.0pt;font-family:Courier;
+color:black;background:white;mso-highlight:white;mso-ansi-language:EN-US'>}</span><span
+style='font-size:10.0pt;font-family:Courier;color:black;mso-ansi-language:EN-US'><o:p></o:p></span></p>
+
+<p class=MsoNormal><span lang=EN-CA><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></span></p>
+
+</div>
+
+</body>
+
+</html>
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE_files/filelist.xml b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE_files/filelist.xml
new file mode 100644
index 0000000..d81a0e8
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE_files/filelist.xml
@@ -0,0 +1,5 @@
+<xml xmlns:o="urn:schemas-microsoft-com:office:office">
+ <o:MainFile HRef="../AppendixE.htm"/>
+ <o:File HRef="header.htm"/>
+ <o:File HRef="filelist.xml"/>
+</xml> \ No newline at end of file
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE_files/header.htm b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE_files/header.htm
new file mode 100644
index 0000000..c34e781
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/AppendixE_files/header.htm
@@ -0,0 +1,66 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml"
+xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link id=Main-File rel=Main-File href="../AppendixE.htm">
+</head>
+
+<body lang=EN-US link=blue vlink=purple>
+
+<div style='mso-element:footer' id=ef1>
+
+<div style='mso-element:frame;mso-element-wrap:around;mso-element-anchor-vertical:
+paragraph;mso-element-anchor-horizontal:margin;mso-element-left:right;
+mso-element-top:.05pt;mso-height-rule:exactly'>
+
+<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
+ <tr>
+ <td valign=top align=left style='padding-top:0in;padding-right:0in;
+ padding-bottom:0in;padding-left:0in'>
+ <p class=MsoFooter style='mso-element:frame;mso-element-wrap:around;
+ mso-element-anchor-vertical:paragraph;mso-element-anchor-horizontal:margin;
+ mso-element-left:right;mso-element-top:.05pt;mso-height-rule:exactly'><span
+ class=MsoPageNumber><span style='mso-field-code:PAGE'>1</span><o:p></o:p></span></p>
+ </td>
+ </tr>
+</table>
+
+</div>
+
+<p class=MsoFooter style='margin-right:.25in'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+<div style='mso-element:footer' id=f1>
+
+<div style='mso-element:frame;mso-element-wrap:around;mso-element-anchor-vertical:
+paragraph;mso-element-anchor-horizontal:margin;mso-element-left:right;
+mso-element-top:.05pt;mso-height-rule:exactly'>
+
+<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
+ <tr>
+ <td valign=top align=left style='padding-top:0in;padding-right:0in;
+ padding-bottom:0in;padding-left:0in'>
+ <p class=MsoFooter style='mso-element:frame;mso-element-wrap:around;
+ mso-element-anchor-vertical:paragraph;mso-element-anchor-horizontal:margin;
+ mso-element-left:right;mso-element-top:.05pt;mso-height-rule:exactly'><span
+ class=MsoPageNumber><span style='mso-field-code:PAGE'>3</span><o:p></o:p></span></p>
+ </td>
+ </tr>
+</table>
+
+</div>
+
+<p class=MsoFooter style='margin-right:.25in'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/Idea.jpg b/Article-Writing Your Own Widget/Writing Your Own Widget_files/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/Idea.jpg
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/default_style.css b/Article-Writing Your Own Widget/Writing Your Own Widget_files/default_style.css
new file mode 100644
index 0000000..85e4e07
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/default_style.css
@@ -0,0 +1,11 @@
+p { font-family: arial, helvetica, geneva; font-size: 10pt}
+td { font-family: arial,helvetica,geneva; font-size: -1}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 11px}
+th { font-family: arial,helvetica,geneva; font-size: 11px; font-weight: bold}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/filelist.xml b/Article-Writing Your Own Widget/Writing Your Own Widget_files/filelist.xml
new file mode 100644
index 0000000..2da8605
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/filelist.xml
@@ -0,0 +1,14 @@
+<xml xmlns:o="urn:schemas-microsoft-com:office:office">
+ <o:MainFile HRef="../Writing%20Your%20Own%20Widget.htm"/>
+ <o:File HRef="image001.png"/>
+ <o:File HRef="oledata.mso"/>
+ <o:File HRef="image002.jpg"/>
+ <o:File HRef="image003.png"/>
+ <o:File HRef="image004.jpg"/>
+ <o:File HRef="image005.png"/>
+ <o:File HRef="image006.jpg"/>
+ <o:File HRef="image007.png"/>
+ <o:File HRef="image008.jpg"/>
+ <o:File HRef="header.htm"/>
+ <o:File HRef="filelist.xml"/>
+</xml> \ No newline at end of file
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/header.htm b/Article-Writing Your Own Widget/Writing Your Own Widget_files/header.htm
new file mode 100644
index 0000000..e012c15
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/header.htm
@@ -0,0 +1,69 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml"
+xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link id=Main-File rel=Main-File href="../Writing%20Your%20Own%20Widget.htm">
+</head>
+
+<body lang=EN-US link=blue vlink=purple>
+
+<div style='mso-element:footer' id=ef1>
+
+<div style='mso-element:frame;mso-element-wrap:around;mso-element-anchor-vertical:
+paragraph;mso-element-anchor-horizontal:margin;mso-element-left:right;
+mso-element-top:.05pt;mso-height-rule:exactly'>
+
+<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
+ <tr>
+ <td valign=top align=left style='padding-top:0in;padding-right:0in;
+ padding-bottom:0in;padding-left:0in'>
+ <p class=MsoFooter style='margin-top:14.2pt;margin-right:0in;margin-bottom:
+ 0in;margin-left:17.0pt;margin-bottom:.0001pt;mso-element:frame;mso-element-wrap:
+ around;mso-element-anchor-vertical:paragraph;mso-element-anchor-horizontal:
+ margin;mso-element-left:right;mso-element-top:.05pt;mso-height-rule:exactly'><span
+ class=MsoPageNumber><span style='mso-field-code:PAGE'>1</span><o:p></o:p></span></p>
+ </td>
+ </tr>
+</table>
+
+</div>
+
+<p class=MsoFooter style='margin-top:0in;margin-right:.25in;margin-bottom:0in;
+margin-left:17.0pt;margin-bottom:.0001pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+<div style='mso-element:footer' id=f1>
+
+<div style='mso-element:frame;mso-element-wrap:around;mso-element-anchor-vertical:
+paragraph;mso-element-anchor-horizontal:margin;mso-element-left:right;
+mso-element-top:.05pt;mso-height-rule:exactly'>
+
+<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
+ <tr>
+ <td valign=top align=left style='padding-top:0in;padding-right:0in;
+ padding-bottom:0in;padding-left:0in'>
+ <p class=MsoFooter style='margin-left:17.0pt;mso-element:frame;mso-element-wrap:
+ around;mso-element-anchor-vertical:paragraph;mso-element-anchor-horizontal:
+ margin;mso-element-left:right;mso-element-top:.05pt;mso-height-rule:exactly'><span
+ class=MsoPageNumber><span style='mso-field-code:PAGE'>11</span><o:p></o:p></span></p>
+ </td>
+ </tr>
+</table>
+
+</div>
+
+<p class=MsoFooter style='margin-top:0in;margin-right:.25in;margin-bottom:0in;
+margin-left:17.0pt;margin-bottom:.0001pt'><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/image001.png b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image001.png
new file mode 100644
index 0000000..9a0daf5
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image001.png
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/image002.jpg b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image002.jpg
new file mode 100644
index 0000000..8ae11a6
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image002.jpg
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/image003.png b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image003.png
new file mode 100644
index 0000000..48a4c8a
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image003.png
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/image004.jpg b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image004.jpg
new file mode 100644
index 0000000..0f7708d
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image004.jpg
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/image005.png b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image005.png
new file mode 100644
index 0000000..b7fe433
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image005.png
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/image006.jpg b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image006.jpg
new file mode 100644
index 0000000..e3aa725
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image006.jpg
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/image007.png b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image007.png
new file mode 100644
index 0000000..774ee8a
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image007.png
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/image008.jpg b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image008.jpg
new file mode 100644
index 0000000..0c19fba
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/image008.jpg
Binary files differ
diff --git a/Article-Writing Your Own Widget/Writing Your Own Widget_files/oledata.mso b/Article-Writing Your Own Widget/Writing Your Own Widget_files/oledata.mso
new file mode 100644
index 0000000..72ecd39
--- /dev/null
+++ b/Article-Writing Your Own Widget/Writing Your Own Widget_files/oledata.mso
Binary files differ
diff --git a/Article-Your First Plug-in/YourFirstPlugin.html b/Article-Your First Plug-in/YourFirstPlugin.html
new file mode 100644
index 0000000..26d2b89
--- /dev/null
+++ b/Article-Your First Plug-in/YourFirstPlugin.html
@@ -0,0 +1,425 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!-- saved from url=(0065)http://www.eclipsecorner.org/articles/Your%20First%20Plug-in.html -->
+<HTML><HEAD><TITLE>Your First Plug-In</TITLE>
+<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
+<link rel="stylesheet" href="../../default_style.css">
+</HEAD>
+<BODY>
+<DIV align=right>&nbsp; <FONT face="Times New Roman, Times, serif"
+size=2>Copyright © 2001, 2003 Object Technology International, Inc.</FONT> </DIV>
+<TABLE border=0 cellPadding=2 cellSpacing=0 width="100%">
+ <TBODY>
+ <TR>
+ <TD align=left bgColor=#0080c0 colSpan=2 vAlign=top><B><FONT
+ face=Arial,Helvetica><FONT color=#ffffff>&nbsp;Eclipse Corner
+ Article</FONT></FONT></B></TD></TR></TBODY></TABLE>
+<H1><img align="center" height=86
+src="../images/Idea.jpg" width=120></H1>
+<CENTER>
+<H1>Your First Plug-in</H1>
+<H3>Developing the Eclipse "Hello World" plug-in<BR></H3></CENTER>
+<CENTER></CENTER>
+<BLOCKQUOTE><B>Summary</B> <BR>
+ The traditional Hello World program doesn't do that much, but it can be invaluable
+ when exploring a new development environment. In this article we'll develop
+ the Eclipse Hello World plug-in and show you how to integrate it with the Eclipse
+ Workbench. After you read this article you should know how to use the Eclipse
+ Java&trade; Development Tooling to create, run, and debug a simple plug-in that
+ extends the Eclipse Platform. You'll see how to setup a project for your plug-in,
+ edit the Java code, compile, and run or debug your plug-in in another launched
+ copy of Eclipse. We'll be looking at plug-in manifest files, extensions, and
+ extension points to see how plug-ins are described to Eclipse and how they are
+ integrated with the Platform.
+ <p><B>By Jim Amsden, OTI</B><BR>
+ Updated September 6, 2002 for Eclipse release 2.0 by <strong>Andrew Irvine,
+ OTI</strong><br>
+ Last revised January 28, 2003</p>
+ <p>Editor's note: <em>Sept. 2003 - This article has been retired from service.</em>
+ The newer article <a href="../Article-PDE-does-plugins/PDE-intro.html">PDE
+ Does Plug-ins</a> shows how PDE greatly simplifies the task of creating a
+ plug-in.</p>
+ <p>This article describes Eclipse release 2.0, which differs in minor ways from
+ the previous Eclipse release. If you are still working with Eclipse release
+ 1.0, you should consult <a href="../Your%20First%20Plug-in.html">the original
+ version of this article</a>.</p>
+ </BLOCKQUOTE>
+<P>
+<HR width="100%">
+
+<P>The Eclipse Plug-in Development Environment (PDE) project provides a very nice
+ environment for creating plug-ins and integrating them with the Eclipse Platform
+ and/or other plug-ins. We're not proposing an alternative to PDE here. PDE is
+ definitely the way to go. But sometimes its helpful to do things "by hand" in
+ order to gain a more thorough understanding of how something works and how the
+ pieces fit together. That's the approach we're going to take in this article.
+ We'll develop a very simple plug-in implementing the Eclipse version of the
+ classic Hello World sample. This will allow us to focus on the relationships
+ between the various components of Eclipse and our plug-in without getting bogged
+ down in the details of the example itself. We'll go raw as much as possible
+ so we can see what's actually happening under the covers. Hopefully this will
+ give you a better understanding of Eclipse, help you make better use of PDE,
+ and give you some idea where to look when things don't go quite as planned.</P>
+<H3>The Problem</H3>
+<P>For the Eclipse Hello World program, let's start out with a simple design.
+ We're going to add a button to the Workbench toolbar that when pressed, displays
+ an information dialog containing the string "Hello World". Pressing OK dismisses
+ the dialog. Nothing fancy, and certainly not anything that begins to exploit
+ the full extensibility of Eclipse. But something we can easily use to get our
+ feet wet. And it turns out that more complicated examples follow roughly the
+ same pattern so we'll get a lot out of this very simple example.</P>
+<P>So lets get started! I'll assume you've already downloaded the latest Eclipse
+ code drop from eclipse.org, have it installed, and know how to start it up.
+ If not, checkout the downloads page at the Eclipse site, and follow the instructions
+ there. </P>
+<H3>Step 1: Getting ready to write Java code</H3>
+<P>Before we get started, we need to check some workbench preferences to make
+sure its configured properly for plug-in development. We'll be setting other
+properties later in the article, but for now, let's just set the default project
+layout and select the JRE we're
+going to use.</P>
+<P><B>Setting the default project layout</B>:&nbsp; Edit the Java preferences
+ by selecting the <code>Window-&gt;Preferences</code> menu item.&nbsp; Expand the
+ <code>Java</code> list item.&nbsp; Click on the <code>New Project item</code>&nbsp;
+ and check the <code>Folders</code>&nbsp; radio button.
+ Ensure &quot;<code>Source folder name</code>&quot; is set to 'src' and
+ that &quot;<code>Output folder name</code>&quot; is set to 'bin'.
+ If you do not alter this setting, all of the class files and source files will
+ be placed in directories based at the root of the project.&nbsp; This is fine
+ for small scale development, but is not the structure you want when constructing
+ bigger programs.&nbsp;</P>
+<P>Note:&nbsp; The Hello World plug-in assumes that the project layout has been
+ altered to use 'src' and 'bin' folders.&nbsp; If you do not do this, you will
+ get runtime errors when testing your plug-in.</P>
+<H3>Step 2: Creating the plug-in Project</H3>
+<P>Now we are ready to create a Java project for your plug-in. Go to the Navigator
+ view (Resource Perspective), and select <code>File-&gt;New-&gt;Project</code>.&nbsp; The project creation wizard
+ has a list of categories each with a list of projects.&nbsp; Select the <code>Java</code>&nbsp;
+ category in the left hand list and <code>Java project</code>&nbsp; in the right. Creating a Java
+ project vs. some other project creates a project which understands Java resources
+ and how to manage changes in them. In the Java project wizard, enter a project
+ name for your plug-in. Generally it is a good idea to use the plug-in name or
+ id as the project name to make it easier to deploy your plug-in, and to make
+ sure your plug-in name doesn't collide or get confused with some other plug-in.
+ In our example, we'll use the plug-in id as the project name. Enter <i>org.eclipse.examples.helloworld</i>.</P>
+<H3>Step 3: Integrating with Eclipse</H3>
+<P>Before we can start writing our code, we need to determine how we're going
+ to integrate with Eclipse. That's because all extensions to Eclipse are done
+ through plug-ins, and plug-ins integrate with each other through extensions
+ on extension points. Eclipse plug-ins typically provide extensions to the platform
+ that support some additional capability or semantics. What is needed is a way
+ for plug-ins to allow other plug-ins to change their behavior in a controlled
+ manner.</P>
+<P>Eclipse provides an extensibility mechanism that is scalable, avoids name collisions,
+ doesn't require compilation of the whole product as a unit, and supports multiple
+ versions of the same component at the same time. Eclipse does this by introducing
+ the notion of a plug-in which encapsulates functional extensions to the Platform.
+ Each plug-in has a name, id, provider name, version, a list of other required
+ plug-ins, and a specification for its runtime. A plug-in can also have any number
+ of extension points that provide a portal into which other plug-ins can add
+ their functionality. This is how Eclipse enables other plug-ins to handle the
+ variability supported by your plug-in. In order to integrate with other plug-ins,
+ a plug-in provides extensions on these extension points (perhaps even its own
+ extension points in order to provide some default behavior).</P>
+<P>A plug-in is described in an XML file called the plug-in manifest file. This
+file is always called plugin.xml, and is always contained in the plug-in
+sub-directory. The Eclipse Platform reads these manifest files and uses the
+information to populate and/or update a registry of information that is used to
+configure the whole platform. </P>
+<P>In our case, we want to use a button on the Workbench toolbar, so the extension
+ point we will use is <code>org.eclipse.ui.actionSets</code>.&nbsp; An action set is a strategy for
+ the addition and removal of menu and toolbar items. This strategy is executed
+ if the user explicitly adds the action set to the workbench. A user can add
+ an action set to the workbench by invoking <code>Window-&gt;Customize Perspective-&gt;Other...</code>&nbsp;
+ to display the available actions. To activate an action set, you would navigate
+ the action set categories, select the desired action set, and press OK. A perspective
+ can also add an action set to the initial page layout by invoking <code>IPageLayout.addActionSet(id)</code>.&nbsp;
+ For details on the actionSets extension point, open the help reference material by
+ invoking <code>Help-&gt;Help Contents...</code>&nbsp;
+ select <code>Platform Plug-in Developer Guide-&gt;Reference-&gt;Extension Points
+ Reference-&gt;Workbench</code>.&nbsp Select this hyper-link and you will be presented with
+ the Platform Extension Points. You are interested in <code>org.eclipse.ui.actionSets</code>.&nbsp;</P>
+<H3>Step 4: Creating the plug-in Manifest File</H3>
+<P>Now that we know what we've got to do, lets tell Eclipse about our plug-in
+ by creating the plug-in manifest file. Use <code>File-&gt;New-&gt;Other...</code>&nbsp;
+ and select <code>Simple-&gt;File</code>&nbsp; to create a file called plugin.xml in
+ the org.eclipse.examples.helloworld project. </P>
+<P>Edit the plugin.xml file so that it looks like this:</P>
+<PRE>&lt;?xml version=&quot;1.0&quot;?&gt;
+&lt;plugin
+ name=&quot;Eclipse Hello World Example&quot;
+ id=&quot;org.eclipse.examples.helloworld&quot;
+ version=&quot;0.0.0&quot;
+ provider-name=&quot;OTI&quot;&gt;
+
+ &lt;requires&gt;
+ &lt;import plugin=&quot;org.eclipse.core.resources&quot;/&gt;
+ &lt;import plugin=&quot;org.eclipse.ui&quot;/&gt;
+ &lt;/requires&gt;
+
+ &lt;runtime&gt;
+ &lt;library name=&quot;helloworld.jar&quot;/&gt;
+ &lt;/runtime&gt;
+
+ &lt;extension point = &quot;org.eclipse.ui.actionSets&quot;&gt;
+ &lt;actionSet
+ id=&quot;org.eclipse.examples.helloworld.HelloWorldActionSet&quot;
+ label=&quot;Hello World&quot;
+ visible=&quot;true&quot;
+ description=&quot;The action set for the Eclipse Hello World example&quot;&gt;
+ &lt;menu
+ id=&quot;org.eclipse.examples.helloworld.HelloWorldMenu&quot;
+ label=&quot;Samples&quot;&gt;
+ &lt;separator name=&quot;samples&quot;/&gt;
+ &lt;/menu&gt;
+ &lt;action id=&quot;org.eclipse.examples.helloworld.actions.HelloWorldAction&quot;
+ menubarPath=&quot;org.eclipse.examples.helloworld.HelloWorldMenu/samples&quot;
+ toolbarPath=&quot;Normal&quot;
+ label=&quot;Hello World&quot;
+ tooltip=&quot;Press to see a message&quot;
+ icon=&quot;icons/helloworld.gif&quot;
+ class=&quot;org.eclipse.examples.helloworld.HelloWorldAction&quot;/&gt;
+ &lt;/actionSet&gt;
+ &lt;/extension&gt;
+&lt;/plugin&gt;
+</PRE>
+<P>You can use Eclipse to edit this file using the default text editor. To do
+ so, select <code>Window-&gt;Preferences</code>, expand the Workbench entry,
+ and select <code>File Associations</code>. Add resource extension xml, and add the
+ &quot;Text Editor&quot; to its associations. Now when you attempt to open an editor on a
+ .xml file, you'll do so with the default text editor. This will do just fine
+ for our simple example. PDE makes this a LOT easier for complex plug-ins. </P>
+<P>Now lets take a look at the manifest file and see exactly what's there. First
+ we see that we're declaring a <code>plugin</code>. That's always the root element
+ of a plug-in manifest file. The attributes of the <code>plugin</code>&nbsp; element
+ give the plug-in name, id, version, and provider name. The id is the really
+ interesting attribute. It specifies the identifier the platform uses to reference
+ this plug-in. Since this name has to be unique for all installed plug-ins, we
+ use Java package naming conventions to create a unique id. Anything will do,
+ but this is a reasonable convention that should be followed. You'll see how
+ these ids are used a little later when we have to reference another plug-in's
+ extension point.</P>
+<P>The <code>requires</code>&nbsp; element is where you specify all the other plug-ins
+ your plug-in depends on. In our case, we're using the actionSets extension of
+ plug-in <code>org.eclipse.ui</code>&nbsp;, so we specify that plug-in here. </P>
+<P>The plug-in <code>runtime</code>&nbsp; element is how you tell the platform where
+ to find the classes in your plug-in. Essentially, the <code>requires</code>&nbsp;
+ and the <code>runtime</code>&nbsp; elements go together to specify the "classpath"
+ for the plug-in. This approach allows each plug-in to have its own classpath
+ independent of any other plug-in. Further, each plug-in has its own classloader
+ which is used to load all classes defined by that plug-in (i.e., the classes
+ found in its library declarations).</P>
+<P>Now we're finally getting to the real integration! The extension element (in
+ our plugin.xml file) describes an extension on the org.eclipse.ui.actionSets
+ extension point. In our example, we're extending the actionSets extension-point
+ of plug-in <code>org.eclipse.ui</code>.&nbsp; The id of our extension, how the
+ platform refers to it, is <code>org.eclipse.examples.helloworld.HelloWorldActionSet</code>&nbsp;
+ while the display name is &quot;Hello World&quot;. If you look at the documentation
+ referenced above for the actionSets extension-point, you'll see that it can
+ have a number of action elements which describe the actions in the set. Each
+ action has a class attribute that specifies the class that implements the required
+ interface, <code>org.eclipse.ui.IWorkbenchWindowActionDelegate</code>.&nbsp;
+ This is what we have to implement for our extension. You'll also need to provide
+ the helloworld.gif file to provide an icon for your action. Anything will due
+ for testing. Create the icons folder in your plug-in folder. All plug-in file
+ and folder pathnames are relative to the plug-in folder.</P>
+<P>Don't get confused between an extension-point element and an extension element
+ with a point attribute. The extension-point element defines a hook into the
+ platform while the extension specifies and instance of using the hook. The point
+ attribute is the id of the extension-point you're extending. </P>
+<H3>Step 5: Setting up the plug-in Project</H3>
+<P>Switch to the Java perspective if you're not already there with
+ <code>Window-&gt;Open Perspective-&gt;Other</code>&nbsp; and select the Java
+ perspective (or if Java is available on the menu, you may select it directly).
+ Then select the packages explorer tab to view the packages in your project. You should only
+ see the packages you've specified in your Java build path so far, probably just
+ the JRE_LIB entry for your rt.jar. Since your going to be using the
+ <code>IWorkbenchWindowActionDelegate</code>&nbsp; interface, and other parts of
+ the platform to develop our example, you need to include the referenced plug-in
+ runtimes in your Java build path. </P>
+<P>From the plug-in manifest file above, we can see that we require plug-in <code>org.eclipse.ui</code>.&nbsp;
+ Referencing the plug-in in the requires element of our plug-in allows the platform
+ to find classes we reference at runtime, but it doesn't help the compiler at
+ development time. We need to get this plug-in's runtime in your project's build
+ path so we can compile against imported classes and interfaces. To do this,
+ select the project and view its properties; right click on the project. Select
+ the <code>Java Build Path</code>&nbsp; entry, and click on the <code>Libraries</code>&nbsp;
+ tab. Then click on the <code>Add External JARs...</code>&nbsp; button and browse
+ to &lt;your eclipse install directory&gt;/eclipse/plugins/org.eclipse.ui_2.0.0,
+ the directory for the 2.0 version of the Eclipse UI plug-in. </P>
+<P>See why we like to have the plug-in ids correspond to the plug-in directory names?
+ It makes it a lot easier to find things. In directory org.eclipse.ui_2.0.0 you'll
+ see the <code>workbench.jar</code>&nbsp; file. Select this file to add it to your
+ build path.
+ The Eclipse UI plug-in depends on the Eclipse SWT plug-in, so we will need to add that
+ one too: <code>org.eclipse.swt.win32_2.0.0-&gt;ws-&gt;win32</code>&nbsp; contains
+ <code>swt.jar</code>,&nbsp; assuming you are running on Windows&reg;. There are
+ similar directories for Linux users running either motif or gtk.
+ The platform automatically provides a special runtime support
+ plug-in: <code>org.eclipse.core.runtime_2.0.0</code>&nbsp; - you should also add the
+ <code>runtime.jar</code>&nbsp; from
+ this plug-in to your build path. If your plug-in depends on any other plug-ins,
+ you'll need to add their jar files too. PDE takes care of all of these things for
+ you, but we'll save that for another article.</P>
+<P>Note: Eclipse release 2.1 re-architects the UI plug-in. The <code>workbench.jar</code>&nbsp;
+ is located in the directory <code>org.eclipse.ui.workbench_2.1.0</code>.&nbsp;
+ In addition the JFace plug-in is required. The <code>jface.jar</code>&nbsp;
+ file can be found in the <code>org.eclipse.jface_2.1.0</code>.&nbsp; directory.
+ The remaining plug-ins can be found in the corresponding release 2.1 directories.
+<P>Now we're ready to write the code and compile it against workbench.jar and
+ swt.jar. The workbench has the JDK set, the project has all the jar files in
+ its build path we need, and the plug-in manifest file tells us what classes
+ we have to start with.</P>
+<H3>Step 6: Implementing the IWorkbenchWindowActionDelegate Interface</H3>
+<P>In this example, our implementation of interface <code>IWorkbenchWindowActionDelegate</code>&nbsp;
+ is <code>org.eclipse.examples.helloworld.HelloWorldAction</code>. Go take a
+ look at the JavaDoc for the <code>IWorkbenchWindowActionDelegate</code>&nbsp; interface to see
+ what methods we need to implement. The JavaDoc is available from the
+ <code>Help-&gt;Help Contents</code>&nbsp; menu item. Select <code>Platform Plug-in Developer Guide</code>&nbsp;
+ expand to <code>Reference-&gt;API Reference-&gt;Workbench-&gt;org.eclipse.ui</code>.&nbsp;
+ In addition to using standard Java package naming conventions, you should consider
+ including the plug-in id as part of your package name. While not required, it will
+ help you keep your code organized.</P>
+<P>To create the implementation class, we'll first create a package for our plug-in.
+ Select the src folder of the <code>org.eclipse.examples.helloworld</code>&nbsp; project in the
+ packages view, right click, and select <code>New-&gt;Package</code>.&nbsp; Create
+ a package named <i>org.eclipse.examples.helloworld</i>.</P>
+<P>Next, select the newly created package, right click, and select <code>New-&gt;Class</code>.&nbsp;
+ If you prefer using the tool bar, there are buttons to create a package and
+ a class, among other Java-specific buttons. In the dialog that comes
+ up, verify the package name is <code>org.eclipse.examples.helloworld</code>&nbsp; (it won't be
+ if you didn't select it first), and fill in the class name <i>HelloWorldAction</i>
+ as specified in the class attribute of the action element in our extension (see
+ the manifest file plugin.xml). The superclass <code>java.lang.Object</code>&nbsp;
+ is fine, but add the interface <code>IWorkbenchWindowActionDelegate</code>.&nbsp;
+ Just click on the <code>Add...</code>&nbsp; button on the right and start typing <i>IWorkbenchWindowActionDelegate</i>.
+ You'll see the selection list zero in as you type. Select <code>IWorkbenchWindowActionDelegate</code>&nbsp;
+ and click OK. You'll see <code>org.eclipse.ui.IWorkbenchWindowActionDelegate</code>&nbsp;
+ in the list of interfaces your class is going to implement. For convenience,
+ click on the <code>Inherited abstract methods</code>&nbsp; check box so the new class
+ wizard will create stubs for all the interface methods you need to implement.
+ This will save you a lot of typing. If you don't see the class in the selection
+ list that you expect, this is a good indication that your Java build path isn't
+ including everything it needs. Check your build path in the project preferences
+ and try again.&nbsp;</P>
+<P>Now we have our <code>IWorkbenchWindowActionDelegate</code>&nbsp; implementation
+ class. From the interface we have four methods to implement, <code>init</code>&nbsp; and <code>dispose</code>&nbsp;
+ from <code>IWorkbenchWindowActionDelegate</code>, and <code>run</code>&nbsp; and <code>selectionChanged</code>&nbsp;
+ from <code>IActionDelegate</code>. Edit the class, and provide the method implementations
+ given below.</P>
+<PRE>package org.eclipse.examples.helloworld;
+
+
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Shell;
+
+
+/** HelloWorldAction is a simple example of using an
+ * action set to extend the Eclipse Workbench with a menu
+ * and toolbar action that prints the &quot;Hello World&quot; message.
+ */
+public class HelloWorldAction implements IWorkbenchWindowActionDelegate {
+ IWorkbenchWindow activeWindow = null;
+
+ /** Run the action. Display the Hello World message
+ */
+ public void run(IAction proxyAction) {
+ // proxyAction has UI information from manifest file (ignored)
+ Shell shell = activeWindow.getShell();
+ MessageDialog.openInformation(shell, &quot;Hello World&quot;, &quot;Hello World!&quot;);
+ }
+
+ // IActionDelegate method
+ public void selectionChanged(IAction proxyAction, ISelection selection) {
+ // do nothing, action is not dependent on the selection
+ }
+
+ // IWorkbenchWindowActionDelegate method
+ public void init(IWorkbenchWindow window) {
+ activeWindow = window;
+ }
+
+ // IWorkbenchWindowActionDelegate method
+ public void dispose() {
+ // nothing to do
+ }
+}
+</PRE>
+<P>The code isn't too complicated, so I won't cover it in any more detail. Other
+ articles will be addressing the specific Eclipse features we're using, but we
+ want to focus on plug-ins and the end-to-end integration story rather than the
+ code specifics in this article.</P>
+<H3>Step 7: Testing your plug-in</H3>
+<P>We're ready to test our plug-in! The best way to do this is to use two
+Eclipse workbenches, one for plug-in development, a second for testing and
+debug. Let's call them the development workbench and the testing workbench to
+avoid confusion. We don't want to use the same instance the Eclipse workbench
+for both development and test for a number of reasons:</P>
+<UL>
+ <LI>You have to restart the workbench every time there's a change in your
+ plug-in so it gets reloaded properly. If you use your development instance for
+ this, you'll be restarting it all the time.
+ <LI>If there's a problem in your plug-in, it could hang the development
+ workbench making it difficult to locate and fix the problem.
+ <LI>You can't debug a workbench with the same workbench that's running the
+ debugger. That's because when the debugger hits a breakpoint, the whole
+ workbench is stopped. </LI></UL>
+<P>Prior to launching a testing workbench you must tell Eclipse where the required
+ plugins are located.
+ Edit the Plug-in Development preferences by selecting the <code>Window-&gt;Preferences</code>
+ menu item.&nbsp; Expand the <code>Plug-In Development</code> list item.&nbsp;
+ Select <code>Target Platform</code> and click on the <code>Not in Workspace</code> button on the
+ right hand side. You will note the selected items in the list to the left of this button are all
+ now checked. Finally click on the <code>OK</code> button to accept these changes.
+<P>To start Eclipse with Eclipse simply choose <code>Run-&gt;Run As-&gt;Run-time Workbench</code>.&nbsp;
+Eclipse automatically starts executing in a second workbench, the testing workbench.
+Be patient this operation may appear to take a long time; when a second
+workbench opens the operation is complete. To view the location of this second workbench browse
+the launch configuration via <code>Run-&gt;Run...</code>.&nbsp; Alternatively
+both these functions may be achieved via the Workbench toolbar Run icon.</P>
+<P>Now we can test the Hello World actions. You'll
+see the Hello World icon that was specified in the icon attribute of the action
+element in our plug-in manifest file on the Workbench toolbar (if you don't
+provide an icon, it will appear as a gray or red square). Move the cursor
+over it and you'll see the hover help you entered. Click and you see the
+message. Not quite as simple as <code>printf("Hello World");</code>&nbsp; but it looks
+a lot nicer.&nbsp; To turn off the Hello World action set (and remove the
+associated button), select <code>Window-&gt;Customize Perspective...</code>&nbsp;
+and expand the <code>Other</code>&nbsp;category.&nbsp; Now you can uncheck the
+Hello World item.</P>
+<P>When you turn off the Hello World action set, you'll see that the icon is
+removed from the toolbar and you can no longer invoke the plug-in action.</P>
+<H3>Debugging your plug-in</H3>
+<P>Debugging your plug-in is just as easy. Just open your Java source and put a
+breakpoint where you would like to start debugging. Then debug your test
+workbench by selecting <code>Run-&gt;Debug As-&gt;Run-time Workbench </code>.
+The workbench will open a debug perspective page,
+and you'll see the Eclipse process running. Eclipse will come up, and be ready
+for you to invoke your plug-in. Again, enable the Hello World actions and click
+on the Hello World button. The test workbench will halt at your breakpoint and
+you'll see your code, breakpoint, and variables in the debug perspective in your
+development workbench. Go ahead and experiment with the debugger. Then press
+resume when ready, and up comes the message. Remember you can only have one
+active Run-time workbench, so you will need to close your testing workbench
+between trials.</P>
+
+<H3>Conclusion</H3>
+<P>We've seen the complete development of a plug-in extension to Eclipse from
+design to debug and test. We've done all the development, testing, and debugging
+using Eclipse itself and the Java Development Tooling. The Hello World example
+doesn't do much, and the complexity per function is pretty high. But more
+complex plug-ins follow the same pattern, and Eclipse provides a lot more than
+we've seen with this simple example. You should now have a pretty good idea how
+all the pieces fit together and what it means to develop and integrate a
+plug-in. Now its time to do something real. You'll want to use PDE for that, so
+look for that article coming soon.</P>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+
+</BODY></HTML> \ No newline at end of file
diff --git a/Article-Your First Plug-in/history/Your First Plug-in.html b/Article-Your First Plug-in/history/Your First Plug-in.html
new file mode 100644
index 0000000..b10161c
--- /dev/null
+++ b/Article-Your First Plug-in/history/Your First Plug-in.html
@@ -0,0 +1,423 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!-- saved from url=(0065)http://www.eclipsecorner.org/articles/Your%20First%20Plug-in.html -->
+<HTML><HEAD><TITLE>Your First Plug-In</TITLE>
+<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
+<link rel="stylesheet" href="../default_style.css">
+</HEAD>
+<BODY>
+<DIV align=right>&nbsp; <FONT face="Times New Roman, Times, serif"
+size=2>Copyright © 2001 Object Technology International, Inc.</FONT> </DIV>
+<TABLE border=0 cellPadding=2 cellSpacing=0 width="100%">
+ <TBODY>
+ <TR>
+ <TD align=left bgColor=#0080c0 colSpan=2 vAlign=top><B><FONT
+ face=Arial,Helvetica><FONT color=#ffffff>&nbsp;Eclipse Corner
+ Article</FONT></FONT></B></TD></TR></TBODY></TABLE>
+<H1><img align="center" height=86
+src="images/Idea.jpg" width=120></H1>
+<CENTER>
+<H1>Your First Plug-in</H1>
+<H3>Developing the Eclipse "Hello World" plug-in<BR></H3></CENTER>
+<CENTER></CENTER>
+<BLOCKQUOTE><B>Summary</B> <BR>
+ The traditional Hello World program doesn't do that much, but it can be invaluable
+ when exploring a new development environment. In this article we'll develop
+ the Eclipse Hello World plug-in and show you how to integrate it with the Eclipse
+ Workbench. After you read this article you should know how to use the Eclipse
+ Java&trade; Development Tooling to create, run, and debug a simple plug-in that extends
+ the Eclipse Platform. You'll see how to setup a project for your plug-in, edit
+ the Java code, compile, and run or debug your plug-in in another launched copy
+ of Eclipse. We'll be looking at plug-in manifest files, extensions, and extension
+ points to see how plug-ins are described to Eclipse and how they are integrated
+ with the Platform.
+ <p><B>By Jim Amsden, OTI<BR>
+ </B>Updated: November 14, 2001</p>
+ <p>Editor's note: This article describes Eclipse release 1.0.
+ It has been superceded by the <a href="Article-Your%20First%20Plug-in/YourFirstPlugin.html">updated
+ version of this article</a> for Eclipse release 2.0.</p>
+ </BLOCKQUOTE>
+<P>
+<HR width="100%">
+
+<P>The Eclipse Plug-in Development Environment (PDE) project provides a very nice
+ environment for creating plug-ins and integrating them with the Eclipse Platform
+ and/or other plug-ins. We're not proposing an alternative to PDE here. PDE is
+ definitely the way to go. But sometimes its helpful to do things "by hand" in
+ order to gain a more thorough understanding of how something works and how the
+ pieces fit together. That's the approach we're going to take in this article.
+ We'll develop a very simple plug-in implementing the Eclipse version of the
+ classic Hello World sample. This will allow us to focus on the relationships
+ between the various components of Eclipse and our plug-in without getting bogged
+ down in the details of the example itself. We'll go raw as much as possible
+ so we can see what's actually happening under the covers. Hopefully this will
+ give you a better understanding of Eclipse, help you make better use of PDE,
+ and give you some idea where to look when things don't go quite as planned.</P>
+<H3>The Problem</H3>
+<P>For the Eclipse Hello World program, let's start out with a simple design.
+ We're going to add a button to the Workbench toolbar that when pressed, displays
+ an information dialog containing the string "Hello World". Pressing OK dismisses
+ the dialog. Nothing fancy, and certainly not anything that begins to exploit
+ the full extensibility of Eclipse. But something we can easily use to get our
+ feet wet. And it turns out that more complicated examples follow roughly the
+ same pattern so we'll get a lot out of this very simple example.</P>
+<P>So lets get started! I'll assume you've already downloaded the latest Eclipse
+ code drop from eclipse.org, have it installed, and know how to start it up.
+ If not, checkout the downloads page at the Eclipse site, and follow the instructions
+ there. </P>
+<H3>Step 1: Getting ready to write Java code</H3>
+<P>Before we get started, we need to check some workbench preferences to make
+sure its configured properly for plug-in development. We'll be setting other
+properties later in the article, but for now, let's just set the default project
+layout and select the JRE we're
+going to use.</P>
+<P><B>Setting the default project layout</B>:&nbsp; Edit the Java preferences
+ by selecting the Window-&gt;Preferences menu item.&nbsp; Expand the Java list
+ item.&nbsp; Click on the Java item and check the box corresponding to &quot;<code>Use
+ 'src' and 'bin' folders as default in new Java projects</code>&quot;.&nbsp;
+ If you do not alter this setting, all of the class files and source files will
+ be placed in directories based at the root of the project.&nbsp; This is fine
+ for small scale development, but is not the structure you want when constructing
+ bigger programs.&nbsp;</P>
+<P>Note:&nbsp; The Hello World plug-in assumes that the project layout has been
+ altered to use 'src' and 'bin' folders.&nbsp; If you do not do this, you will
+ get runtime errors when testing your plug-in.</P>
+<H3>Step 2: Creating the plug-in Project</H3>
+<P>Now we are ready to create a Java project for your plug-in. Go to the Navigator
+ view, and select File-&gt;New-&gt;Project.&nbsp; The project creation wizard
+ has a list of categories each with a list of projects.&nbsp; Select the Java
+ category in the left hand list and Java project in the right. Creating a Java
+ project vs. some other project creates a project which understands Java resources
+ and how to manage changes in them. In the Java project wizard, enter a project
+ name for your plug-in. Generally it is a good idea to use the plug-in name or
+ id as the project name to make it easier to deploy you plug-in, and to make
+ sure your plug-in name doesn't collide or get confused with some other plug-in.
+ In our example, we'll use the plug-in id as the project name. Enter <i>org.eclipse.examples.helloworld</i>.</P>
+<H3>Step 3: Integrating with Eclipse</H3>
+<P>Before we can start writing our code, we need to determine how we're going
+ to integrate with Eclipse. That's because all extensions to Eclipse are done
+ through plug-ins, and plug-ins integrate with each other through extensions
+ on extension points. Eclipse plug-ins typically provide extensions to the platform
+ that support some additional capability or semantics. What is needed is a way
+ for plug-ins to allow other plug-ins to change their behavior in a controlled
+ manner.</P>
+<P>Eclipse provides an extensibility mechanism that is scalable, avoids name collisions,
+ doesn't require compilation of the whole product as a unit, and supports multiple
+ versions of the same component at the same time. Eclipse does this by introducing
+ the notion of a plug-in which encapsulates functional extensions to the Platform.
+ Each plug-in has a name, id, provider name, version, a list of other required
+ plug-ins, and a specification for its runtime. A plug-in can also have any number
+ of extension points that provide a portal into which other plug-ins can add
+ their functionality. This is how Eclipse enables other plug-ins to handle the
+ variability supported by your plug-in. In order to integrate with other plug-ins,
+ a plug-in provides extensions on these extension points (perhaps even its own
+ extension points in order to provide some default behavior).</P>
+<P>A plug-in is described in an XML file called the plug-in manifest file. This
+file is always called plugin.xml, and is always contained in the plug-in
+sub-directory. The Eclipse Platform reads these manifest files and uses the
+information to populate and/or update a registry of information that is used to
+configure the whole platform. </P>
+<P>In our case, we want to use a button on the Workbench toolbar, so the extension
+ point we'd use is org.eclipse.ui.actionSets. An action set is a strategy for
+ the addition and removal of menu and toolbar items. This strategy is executed
+ if the user explicitly adds the action set to the workbench. A user can add
+ an action set to the workbench by invoking <code>Perspective-&gt;Show View-&gt;Other..</code>
+ to display the available actions. To activate an action set, you would navigate
+ the action set categories, select the desired action set, and press OK. A perspective
+ can also add an action set to the initial page layout by invoking IPageLayout.addActionSet(id).
+ For details on the actionSets extension point, open the help perspective and
+ select <code>Platform Plug-in Developer Guide-&gt;Reference-&gt;Extension Points
+ Reference-&gt;org.eclipse.ui.actionSets</code>.</P>
+<H3>Step 4: Creating the plug-in Manifest File</H3>
+<P>Now that we know what we've got to do, lets tell Eclipse about our plug-in
+ by creating the plug-in manifest file. Use <code>Fille-&gt;New-&gt;Other...</code>
+ and select <code>Simple-&gt;File</code> to create a file called plugin.xml in
+ the org.eclipse.examples.helloworld project. </P>
+<P>Edit the plugin.xml file so that it looks like this:</P>
+<PRE>&lt;?xml version=&quot;1.0&quot;?&gt;
+&lt;plugin
+ name=&quot;Eclipse Hello World Example&quot;
+ id=&quot;org.eclipse.examples.helloworld&quot;
+ version=&quot;0.0.0&quot;
+ provider-name=&quot;OTI&quot;&gt;
+
+ &lt;requires&gt;
+ &lt;import plugin=&quot;org.eclipse.ui&quot;/&gt;
+ &lt;/requires&gt;
+
+ &lt;runtime&gt;
+ &lt;library name=&quot;helloworld.jar&quot;/&gt;
+ &lt;/runtime&gt;
+
+ &lt;extension point = &quot;org.eclipse.ui.actionSets&quot;&gt;
+ &lt;actionSet
+ id=&quot;org.eclipse.examples.helloworld.HelloWorldActionSet&quot;
+ label=&quot;Hello World&quot;
+ visible=&quot;true&quot;
+ description=&quot;The action set for the Eclipse Hello World example&quot;&gt;
+ &lt;menu
+ id=&quot;org.eclipse.examples.helloworld.HelloWorldMenu&quot;
+ label=&quot;Samples&quot;&gt;
+ &lt;separator name=&quot;samples&quot;/&gt;
+ &lt;/menu&gt;
+ &lt;action id=&quot;org.eclipse.examples.helloworld.actions.HelloWorldAction&quot;
+ menubarPath=&quot;org.eclipse.examples.helloworld.HelloWorldMenu/samples&quot;
+ toolbarPath=&quot;Normal&quot;
+ label=&quot;Hello World&quot;
+ tooltip=&quot;Press to see a message&quot;
+ icon=&quot;icons/helloworld.gif&quot;
+ class=&quot;org.eclipse.examples.helloworld.HelloWorldAction&quot;/&gt;
+ &lt;/actionSet&gt;
+ &lt;/extension&gt;
+&lt;/plugin&gt;
+</PRE>
+<P>You can use Eclipse to edit this file using the default text editor. To do
+ so, select <code>Window-&gt;Preferences</code>, expand the Workbench entry,
+ and select <code>File Editors</code>. Add resource extension xml, and add the default
+ text editor to its associations. Now when you attempt to open an editor on a
+ .xml file, you'll do so with the default text editor. This will do just fine
+ for our simple example. PDE makes this a LOT easier for complex plug-ins. </P>
+<P>Now lets take a look at the manifest file and see exactly what's there. First
+ we see that we're declaring a <code>plugin</code>. That's always the root element
+ of a plug-in manifest file. The attributes of the <code>plugin</code> element
+ give the plug-in name, id, version, and provider name. The id is the really
+ interesting attribute. It specifies the identifier the platform uses to reference
+ this plug-in. Since this name has to be unique for all installed plug-ins, we
+ use Java package naming conventions to create a unique id. Anything will do,
+ but this is a reasonable convention that should be followed. You'll see how
+ these ids are used a little later when we have to reference another plug-in's
+ extension point.</P>
+<P>The <code>requires</code> element is where you specify all the other plug-ins
+ your plug-in depends on. In our case, we're using the actionSets extension of
+ plug-in org.eclipse.ui, so we specify that plug-in here. </P>
+<P>The plug-in <code>runtime</code> element is how you tell the platform where
+ to find the classes in your plug-in. Essentially, the <code>requires</code>
+ and the <code>runtime</code> elements go together to specify the "classpath"
+ for the plug-in. This approach allows each plug-in to have its own classpath
+ independent of any other plug-in. Further, each plug-in has its own classloader
+ which is used to load all classes defined by that plug-in (i.e., the classes
+ found in its library declarations).</P>
+<P>Now we're finally getting to the real integration! The extension element (in our plugin.xml file) describes an extension on the org.eclipse.ui.actionSets extension point. In our example, we're extending the actionSets extension-point of plug-in org.eclipse.ui. The id of our extension, how the platform refers to it, is org.eclipse.examples.helloworld.HelloWorldActionSet while the display name is &quot;Hello World&quot;. If you look at in the documentation referenced above for the actionSets extension-point, you'll see that it can have a number of action elements which describe the actions in the set. Each action has a class attribute that specifies the class that implements the required interface, org.eclipse.ui.IWorkbenchWindowActionDelegate. This is what we have to implement for our extension. You'll also need to provide the helloworld.gif file to provide an icon for your action. Anything will due for testing. Create the icons folder in you plug-in folder. All plug-in file and folder pathnames are relative to the plug-in folder.</P>
+<P>Don't get confused between an extension-point element and an extension element
+ with a point attribute. The extension-point element defines a hook into the
+ platform while the extension specifies and instance of using the hook. The point
+ attribute is the id of the extension-point you're extending. </P>
+<H3>Step 5: Setting up the plug-in Project</H3>
+<P>Switch to the Java perspective if you're not already there with Perspective-&gt;Open-&gt;Other
+ and select the Java perspective (or if Java is available on the menu, you may
+ select it directly). Then select the packages tab to view the packages in your
+ project. You should only see the packages you've specified in your Java build
+ path so far, probably just the JRE_LIB entry for your rt.jar. Since your going
+ to be using the IWorkbenchWindowActionDelegate interface, and other parts of
+ the platform to develop our example, you need to include the referenced plug-in
+ runtimes in your Java build path. </P>
+<P>From the plug-in manifest file above, we can see that we require plug-in org.eclipse.ui.
+ Referencing the plug-in in the requires element of our plug-in allows the platform
+ to find classes we reference at runtime, but it doesn't help the compiler at
+ development time. We need to get this plug-in's runtime in your project's build
+ path so we can compile against imported classes and interfaces. To do this,
+ select the project and view its properties. Select the <code>Java Build Path</code>
+ entry, and click on the <code>Libraries</code> tab. Then click on the <code>Add
+ External JARs...</code> button and browse to &lt;your eclipse install directory&gt;\plugins\org.eclipse.ui,
+ the directory for the Eclipse UI plug-in. </P>
+<P>See why we like to have the plug-in ids correspond to the plug-in directory names? It makes it a lot easier to find things. In directory org.eclipse.ui you'll see the workbench.jar file. Select this file to add it to your build path. The Eclipse UI plug-in depends on the Eclipse SWT plug-in, so we will need to add that one too: org.eclipse.swt contains swt.jar.&nbsp; The platform automatically provides a special runtime support plug-in: org.eclipse.core.runtime - you should also add the runtime.jar from this plug-in to your build path.&nbsp; If your plug-in depends on any other plug-ins, you'll need to add their jar files too.&nbsp; PDE takes care of all of these things for you, but we'll save that for another article.</P>
+<P>Now we're ready to write the code and compile it against workbench.jar and
+ swt.jar. The workbench has the JDK set, or project has all the jar files in
+ its build path we need, and the plug-in manifest file tells us what classes
+ we have to start with.</P>
+<H3>Step 6: Implementing the IWorkbenchWindowActionDelegate Interface</H3>
+<P>In this example, our implementation of interface <code>IWorkbenchWindowActionDelegate</code>
+ is <code>org.eclipse.examples.helloworld.HelloWorldAction</code>. Go take a
+ look at the JavaDoc for the <code>IWorkbenchWindowActionDelegate</code> interface to see what methods we need to implement. The JavaDoc is available from the Help-&gt;Help Contents menu item. Select &quot;Platform Plug-in Developer Guide&quot; from the drop-down menu, expand to Reference-&gt;Workbench-&gt;org.eclipse.ui. In addition to using standard Java package naming conventions, you should consider including the plug-in id as part of your package name. While not required, it will help you keep your code organized.</P>
+<P>To create the implementation class, we'll first create a package for our plug-in.
+ Select the src folder of the org.eclipse.examples.helloworld project in the
+ packages view, right click, and select <code>New-&gt;Package</code>. Create
+ a package named <i>org.eclipse.examples.helloworld</i>.</P>
+<P>Next, select the newly created package, right click, and select <code>New-&gt;Class</code>.
+ (If you prefer using the tool bar, there are buttons to create a package and
+ a class, among other Java-specific buttons.)&nbsp; In the dialog that comes
+ up, verify the package name is org.eclipse.examples.helloworld (it won't be
+ if you didn't select it first), and fill in the class name <i>HelloWorldAction</i>
+ as specified in the class attribute of the action element in our extension (see
+ the manifest file plugin.xml). The superclass <code>java.lang.Object</code>
+ is fine, but add the interface <code>IWorkbenchWindowActionDelegate</code>.
+ Just click on the <code>Add...</code> button on the right and start typing <i>IWorkbenchWindowActionDelegate</i>.
+ You'll see the selection list zero in as you type. Select <code>IWorkbenchWindowActionDelegate</code>
+ and click OK. You'll see <code>org.eclipse.ui.IWorkbenchWindowActionDelegate</code>
+ in the list of interfaces your class is going to implement. For convenience,
+ click on the <code>Inherited abstract methods</code> check box so the new class
+ wizard will create stubs for all the interface methods you need to implement.
+ This will save you a lot of typing. If you don't see the class in the selection
+ list that you expect, this is a good indication that your Java build path isn't
+ including everything it needs. Check your build path in the project preferences
+ and try again.&nbsp;</P>
+<P>Now we have our <code>IWorkbenchWindowActionDelegate</code> implementation
+ class. From the interface we have four methods to implement, init and dispose
+ from <code>IWorkbenchWindowActionDelegate</code>, and run and selectionChanged
+ from <code>IActionDelegate</code>. Edit the class, and provide the method implementations
+ given below.</P>
+<PRE>package org.eclipse.examples.helloworld;
+
+
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.swt.widgets.Shell;
+
+
+/** HelloWorldAction is a simple example of using an
+ * action set to extend the Eclipse Workbench with a menu
+ * and toolbar action that prints the &quot;Hello World&quot; message.
+ */
+public class HelloWorldAction implements IWorkbenchWindowActionDelegate {
+ IWorkbenchWindow activeWindow = null;
+
+ /** Run the action. Display the Hello World message
+ */
+ public void run(IAction proxyAction) {
+ // the proxyAction has the UI information from the manifest file
+ Shell shell = activeWindow.getShell();
+ MessageDialog.openInformation(shell, &quot;Hello World&quot;, &quot;Hello World!&quot;);
+ }
+
+ /**
+ * @see IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public void selectionChanged(IAction proxyAction, ISelection selection) {
+ // do nothing, action is not dependent on the selection
+ }
+
+ /**
+ * @see IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
+ */
+ public void init(IWorkbenchWindow window) {
+ activeWindow = window;
+ }
+
+ /**
+ * @see IWorkbenchWindowActionDelegate#dispose()
+ */
+ public void dispose() {
+ // nothing to do
+ }
+}
+</PRE>
+<P>The code isn't too complicated, so I won't cover it in any more detail. Other
+ articles will be addressing the specific Eclipse features we're using, but we
+ want to focus on plug-ins and the end-to-end integration story rather than the
+ code specifics in this article.</P>
+<H3>Step 7: Testing your plug-in</H3>
+<P>We're ready to test our plug-in! The best way to do this is to use two
+Eclipse workbenches, one for plug-in development, and another for testing and
+debug. Let's call them the development workbench and the testing workbench to
+avoid confusion. To do this we'll need to startup another workbench (the testing
+workbench) telling it
+where our plug-in is so it can load it when needed. PDE includes a launcher for
+this, but we can do it by hand with just a little more work. To make this a
+little easier to follow, let's assume you installed Eclipse on Windows&reg; in
+c:\eclipse. Let's also assume that you started up your plug-in development
+workbench on workspace c:\workspace. This would be done by running Eclipse
+with:</P>
+<BLOCKQUOTE><PRE>c:\eclipse\eclipse -data c:\workspace</PRE></BLOCKQUOTE>
+<P>Now your org.eclipse.examples.helloworld project will be in c:\workspace\org.eclipse.examples.helloworld.
+ If you installed Eclipse in some other directory, or used a different workspace,
+ adjust your pathnames accordingly.</P>
+<P>Next, we'll need a way to invoke our testing workbench. We don't want
+to use the same instance the Eclipse workbench for both development and test for
+a number of reasons:</P>
+<UL>
+ <LI>You have to restart the workbench every time there's a change in your
+ plug-in so it gets reloaded properly. If you use your development instance for
+ this, you'll be restarting it all the time.
+ <LI>If there's a problem in your plug-in, it could hang the development
+ workbench making it difficult to locate and fix the problem.
+ <LI>You can't debug a workbench with the same workbench that's running the
+ debugger. That's because when the debugger hits a breakpoint, the whole
+ workbench is stopped. </LI></UL>
+<P>Starting up Eclipse with Eclipse is really quite easy. Just create a Java
+project called say, "Eclipse Launcher". In the Java Build Path for this project,
+add the external jar: c:\eclipse\startup.jar. This file contains the Eclipse
+launcher main program that we'll need to startup our test workbench.</P>
+<P>Startup.jar contains a class called org.eclipse.core.launcher.UIMain which is
+the main program for Eclipse UI applications. Next we have to set the program
+arguments for UIMain so it knows where everything is, including our plug-in. The
+details of launching Eclipse and loading classes will be covered in a future
+article, so we'll only cover what you need to get it working here. Go to the
+Package view, expand startup.jar and package org.eclipse.core.launcher, and edit
+the properties of UIMain. Set the program arguments to:</P>
+<BLOCKQUOTE>
+ <PRE>-data c:\tempWorkspace -dev bin -plugins c:\workspace\.plugin-path</PRE>
+</BLOCKQUOTE>
+<P><CODE>-data c:\tempWorkspace</CODE> is the fully qualified path name to a
+temporary platform workspace used for testing your plug-in. You can use any
+workspace you want as long as its not the same one you are using for your
+development workbench. Only one instance of Eclipse can be running on a platform
+workspace at a time because the platform meta-data cannot be shared.</P>
+<P><CODE>-dev bin</code> specifies that the bin directory of every plugin should be added
+ to that plug-ins class path. This will help the platform find the classes you
+ have just written and compiled.</P>
+<P><CODE>-plugins c:\workspace\.plugin-path</CODE> is the fully qualified pathname
+ to a file that contains plug-in path URLs. These URLs tell the Eclipse boot
+ loader where to find plug-ins. We'll be telling it to look in the Eclipse plugins
+ directory, and your development workspace since its projects are plug-in sub-directories.
+ For example: File c:\workspace\.plugin-path might contain:</P>
+<BLOCKQUOTE>
+ <PRE>platformPath = file:C:/eclipse/plugins/
+pluginDevelopmentPath = file:C:/workspace/</PRE>
+</BLOCKQUOTE>
+<P>The plug-in path file can be called anything you want, and can be part of the
+ plug-in project for simplicity. This would allow everything associated with
+ the plug-ing development to be managed, versioned, edited, etc. completely withing
+ the platform (i,e. youdon't have to edit files in the file system directly).
+ I didn't do this because my whole workspace just happens to be used to develop
+ a number of plug-in examples, so its convenient to have a plug-in path for the
+ workspace as a whole rather than separate ones for each plug-in. </P>
+<P>We're ready to roll! Running the platform is easy. Just select UIMain, and
+press the run button on the Workbench toolbar. This will invoke your test
+workbench on the temporary workspace you specified above, and update the
+registry with information from your plug-in manifest file.</P>
+<P>Now we can test the Hello World actions. You'll
+see the Hello World icon that was specified in the icon attribute of the action
+element in our plug-in manifest file on the Workbench toolbar (if you don't
+provide an icon, it will appear as a gray or red square). Move the cursor
+over it and you'll see the hover help you entered. Click and you see the
+message. Not quite as simple as <CODE>printf("Hello World")</CODE>; but it looks
+a lot nicer.&nbsp; To turn off the Hello World action set (and remove the
+associated button), select Perspective-&gt;Customize and expand the Other
+category.&nbsp; Now you can uncheck the Hello World item.</P>
+<P>When you turn off the Hello World action set, you'll see that the icon is
+removed from the toolbar and you can no longer invoke the plug-in action.</P>
+<H3>Debugging your plug-in</H3>
+<P>Debugging your plug-in is just as easy. Just open your Java source and put a
+breakpoint where you would like to start debugging. Then debug your test
+workbench by selecting UIMain in the Eclipse Launcher project and pressing the
+debug button on the toolbar. The workbench will open a debug perspective page,
+and you'll see the Eclipse process running. Eclipse will come up, and be ready
+for you to invoke your plug-in. Again, enable the Hello World actions and click
+on the Hello World button. The test workbench will halt at your breakpoint and
+you'll see your code, breakpoint, and variables in the debug perspective in your
+development workbench. Go ahead and experiment with the debugger. Then press
+resume when ready, and up comes the message.</P>
+<P>Note: If your debugging using Eclipse running on jdk1.2.2, there are a couple
+ of additional DLLs you need. Files dt_socket.dll and jtwp.dll provide the jdk1.3
+ debug API on jdk1.2.2. These are available at http://java.sun.com/products/jpda/download.html.</P>
+<H3>Conclusion</H3>
+<P>We've seen the complete development of a plug-in extension to Eclipse from
+design to debug and test. We've done all the development, testing, and debugging
+using Eclipse itself and the Java Development Tooling. The Hello World example
+doesn't do much, and the complexity per function is pretty high. But more
+complex plug-ins follow the same pattern, and Eclipse provides a lot more than
+we've seen with this simple example. You should now have a pretty good idea how
+all the pieces fit together and what it means to develop and integrate a
+plug-in. Now its time to do something real. You'll want to use PDE for that, so
+look for that article coming soon.</P>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+
+</BODY></HTML> \ No newline at end of file
diff --git a/Article-small-cup-of-swt/FileDialogMain.java b/Article-small-cup-of-swt/FileDialogMain.java
new file mode 100644
index 0000000..5123775
--- /dev/null
+++ b/Article-small-cup-of-swt/FileDialogMain.java
@@ -0,0 +1,24 @@
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+public class FileDialogMain {
+
+public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("Main");
+ Menu mb = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(mb);
+ shell.open();
+
+ FileDialog dialog = new FileDialog(shell, SWT.OPEN);
+ String name = dialog.open();
+ shell.setText(name);
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
diff --git a/Article-small-cup-of-swt/HelloWorld.java b/Article-small-cup-of-swt/HelloWorld.java
new file mode 100644
index 0000000..447d50f
--- /dev/null
+++ b/Article-small-cup-of-swt/HelloWorld.java
@@ -0,0 +1,35 @@
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+public class HelloWorld {
+
+public static void main(String[] args) {
+ Display display = new Display();
+
+ /*
+ * Create a Shell with the default style
+ * i.e. full screen, no decoration on PocketPC.
+ */
+ Shell shell = new Shell(display);
+
+ /*
+ * Set a text so that the top level Shell
+ * also appears in the PocketPC task list
+ */
+ shell.setText("Main");
+
+ /*
+ * Set a menubar to follow UI guidelines
+ * on PocketPC
+ */
+ Menu mb = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(mb);
+
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
diff --git a/Article-small-cup-of-swt/OkButton.java b/Article-small-cup-of-swt/OkButton.java
new file mode 100644
index 0000000..c1c9cc1
--- /dev/null
+++ b/Article-small-cup-of-swt/OkButton.java
@@ -0,0 +1,27 @@
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+public class OkButton {
+
+public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display, SWT.CLOSE);
+ shell.setText("Main");
+ Menu menu = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(menu);
+ shell.addListener(SWT.Close, new Listener() {
+ public void handleEvent(Event e) {
+ System.out.println("Ok button tapped");
+ }
+ });
+
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
+
diff --git a/Article-small-cup-of-swt/SipResize.java b/Article-small-cup-of-swt/SipResize.java
new file mode 100644
index 0000000..b203f5c
--- /dev/null
+++ b/Article-small-cup-of-swt/SipResize.java
@@ -0,0 +1,28 @@
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.layout.*;
+
+public class SipResize {
+
+public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display, SWT.RESIZE);
+ shell.setLayout(new FillLayout());
+ shell.setText("Main");
+ Menu mb = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(mb);
+ Text text = new Text(shell, SWT.MULTI | SWT.V_SCROLL);
+ String buffer = "";
+ for (int i = 0; i < 100; i++) {
+ buffer += "This is line " + i + "\r\n";
+ }
+ text.setText(buffer);
+
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
diff --git a/Article-small-cup-of-swt/SmallDialog.java b/Article-small-cup-of-swt/SmallDialog.java
new file mode 100644
index 0000000..4201c82
--- /dev/null
+++ b/Article-small-cup-of-swt/SmallDialog.java
@@ -0,0 +1,30 @@
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.graphics.*;
+
+public class SmallDialog {
+
+public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("Main");
+ Menu mb = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(mb);
+
+ Shell dialog = new Shell(shell, SWT.CLOSE);
+ dialog.setText(shell.getText());
+ Rectangle bounds = display.getClientArea();
+ bounds.x += 5; bounds.width -= 10;
+ bounds.y += 5; bounds.height /= 2;
+ dialog.setBounds(bounds);
+
+ shell.open();
+ dialog.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+} \ No newline at end of file
diff --git a/Article-small-cup-of-swt/SmartMinimize.java b/Article-small-cup-of-swt/SmartMinimize.java
new file mode 100644
index 0000000..8c9c10c
--- /dev/null
+++ b/Article-small-cup-of-swt/SmartMinimize.java
@@ -0,0 +1,22 @@
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+public class SmartMinimize {
+
+public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("Main");
+ Menu menu = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(menu);
+
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
+
diff --git a/Article-small-cup-of-swt/StylusHold.java b/Article-small-cup-of-swt/StylusHold.java
new file mode 100644
index 0000000..bb2b98a
--- /dev/null
+++ b/Article-small-cup-of-swt/StylusHold.java
@@ -0,0 +1,28 @@
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+public class StylusHold {
+
+public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("Main");
+ Menu mb = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(mb);
+ shell.addListener(SWT.MenuDetect, new Listener() {
+ public void handleEvent (Event e){}
+ });
+ Menu menu = new Menu(shell, SWT.POP_UP);
+ MenuItem item = new MenuItem(menu, SWT.CASCADE);
+ item.setText("item 1");
+ MenuItem item2 = new MenuItem(menu, SWT.CASCADE);
+ item2.setText("item 2");
+ shell.setMenu(menu);
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
diff --git a/Article-small-cup-of-swt/class_load_j2me_cldc.txt b/Article-small-cup-of-swt/class_load_j2me_cldc.txt
new file mode 100644
index 0000000..4554e2a
--- /dev/null
+++ b/Article-small-cup-of-swt/class_load_j2me_cldc.txt
@@ -0,0 +1,89 @@
+J2ME CLDC / SWT HelloWorld using the j9 2.0 VM
+
+class load: java/lang/Object
+class load: java/lang/Class
+class load: void
+class load: boolean
+class load: boolean[]
+class load: char
+class load: char[]
+class load: float
+class load: float[]
+class load: double
+class load: double[]
+class load: byte
+class load: byte[]
+class load: short
+class load: short[]
+class load: int
+class load: int[]
+class load: long
+class load: long[]
+class load: java/lang/String
+class load: com/ibm/oti/vm/VM
+class load: java/util/Vector
+class load: java/lang/Object[]
+class load: java/lang/System
+class load: java/lang/Runtime
+class load: java/util/Hashtable
+class load: java/util/Enumeration
+class load: java/util/Hashtable$EmptyEnumerator
+class load: java/util/HashMapEntry
+class load: java/util/HashMapEntry[]
+class load: com/ibm/oti/io/CharacterConverter
+class load: java/lang/Character
+class load: java/lang/StringBuffer
+class load: java/lang/Throwable
+class load: java/lang/Exception
+class load: java/lang/ClassNotFoundException
+class load: com/ibm/oti/io/CharacterConverter_ISO8859_1
+class load: java/lang/String[]
+class load: java/io/OutputStream
+class load: java/io/PrintStream
+class load: com/ibm/oti/connection/file/FileOutputStream
+class load: com/ibm/oti/vm/Jxe
+class load: com/ibm/oti/vm/Jxe[]
+class load: java/lang/Error
+class load: java/lang/VirtualMachineError
+class load: java/lang/OutOfMemoryError
+class load: java/lang/Runnable
+class load: java/lang/Thread
+class load: HelloWorld
+class load: org/eclipse/swt/graphics/Drawable
+class load: org/eclipse/swt/graphics/Device
+class load: org/eclipse/swt/widgets/Display
+class load: int[][]
+class load: org/eclipse/swt/widgets/Display[]
+class load: org/eclipse/swt/widgets/Display$1
+class load: org/eclipse/swt/internal/win32/OS
+class load: org/eclipse/swt/internal/Library
+class load: org/eclipse/swt/internal/win32/OSVERSIONINFO
+class load: org/eclipse/swt/internal/Callback
+class load: org/eclipse/swt/internal/win32/TCHAR
+class load: java/lang/Integer
+class load: java/lang/Long
+class load: org/eclipse/swt/internal/win32/WNDCLASS
+class load: org/eclipse/swt/widgets/WidgetTable
+class load: org/eclipse/swt/widgets/Widget
+class load: org/eclipse/swt/widgets/Control
+class load: org/eclipse/swt/widgets/Control[]
+class load: org/eclipse/swt/graphics/Font
+class load: org/eclipse/swt/internal/win32/MSG
+class load: org/eclipse/swt/widgets/Synchronizer
+class load: org/eclipse/swt/widgets/Scrollable
+class load: org/eclipse/swt/widgets/Composite
+class load: org/eclipse/swt/widgets/Canvas
+class load: org/eclipse/swt/widgets/Decorations
+class load: org/eclipse/swt/widgets/Shell
+class load: org/eclipse/swt/internal/win32/DLLVERSIONINFO
+class load: org/eclipse/swt/internal/win32/RECT
+class load: org/eclipse/swt/internal/win32/SHACTIVATEINFO
+class load: org/eclipse/swt/widgets/Menu
+class load: org/eclipse/swt/internal/win32/SHMENUBARINFO
+class load: org/eclipse/swt/widgets/Menu[]
+class load: org/eclipse/swt/internal/win32/LRESULT
+class load: java/lang/Math
+class load: org/eclipse/swt/internal/win32/PAINTSTRUCT
+class load: org/eclipse/swt/graphics/GCData
+class load: org/eclipse/swt/graphics/GC
+class load: org/eclipse/swt/widgets/Event
diff --git a/Article-small-cup-of-swt/class_load_j2se.txt b/Article-small-cup-of-swt/class_load_j2se.txt
new file mode 100644
index 0000000..366f700
--- /dev/null
+++ b/Article-small-cup-of-swt/class_load_j2se.txt
@@ -0,0 +1,240 @@
+J2SE / SWT HelloWorld using the j9 2.0 VM
+
+class load: java/lang/Object
+class load: java/io/Serializable
+class load: java/lang/Class
+class load: void
+class load: boolean
+class load: java/lang/Cloneable
+class load: boolean[]
+class load: char
+class load: char[]
+class load: float
+class load: float[]
+class load: double
+class load: double[]
+class load: byte
+class load: byte[]
+class load: short
+class load: short[]
+class load: int
+class load: int[]
+class load: long
+class load: long[]
+class load: java/lang/Comparable
+class load: java/lang/String
+class load: java/util/Comparator
+class load: java/lang/String$CaseInsensitiveComparator
+class load: java/lang/Throwable
+class load: java/lang/Error
+class load: java/lang/VirtualMachineError
+class load: java/lang/OutOfMemoryError
+class load: java/lang/ThreadDeath
+class load: java/lang/ClassLoader
+class load: java/lang/System
+class load: java/lang/Runtime
+class load: java/util/Dictionary
+class load: java/util/Map
+class load: java/util/Hashtable
+class load: java/util/Properties
+class load: java/util/Enumeration
+class load: java/util/Hashtable$EmptyEnumerator
+class load: java/util/Map$Entry
+class load: java/util/MapEntry
+class load: java/util/HashMapEntry
+class load: java/util/HashMapEntry[]
+class load: com/ibm/oti/io/CharacterConverter
+class load: java/util/AbstractMap
+class load: java/util/HashMap
+class load: java/io/ObjectStreamField
+class load: java/io/ObjectStreamField[]
+class load: java/lang/Number
+class load: java/lang/Float
+class load: com/ibm/oti/vm/VM
+class load: java/util/Collection
+class load: java/util/AbstractCollection
+class load: java/util/List
+class load: java/util/AbstractList
+class load: java/util/Vector
+class load: java/lang/Object[]
+class load: java/security/Guard
+class load: java/security/Permission
+class load: java/security/BasicPermission
+class load: java/lang/RuntimePermission
+class load: java/lang/ClassLoader[]
+class load: java/lang/ref/Reference
+class load: java/lang/ref/WeakReference
+class load: java/lang/Integer
+class load: java/lang/Character
+class load: java/lang/StringBuffer
+class load: java/lang/Exception
+class load: java/lang/ClassNotFoundException
+class load: com/ibm/oti/io/CharacterConverter_ISO8859_1
+class load: java/lang/String[]
+class load: java/io/InputStream
+class load: java/io/FilterInputStream
+class load: java/io/BufferedInputStream
+class load: java/io/FileInputStream
+class load: java/io/FileDescriptor
+class load: java/io/OutputStream
+class load: java/io/FilterOutputStream
+class load: java/io/PrintStream
+class load: java/io/FileOutputStream
+class load: java/security/PrivilegedAction
+class load: java/io/PrintStream$1
+class load: java/security/AccessController
+class load: com/ibm/oti/vm/AbstractClassLoader
+class load: com/ibm/oti/vm/BootstrapClassLoader
+class load: com/ibm/oti/vm/Jxe
+class load: com/ibm/oti/vm/JxeUtil
+class load: com/ibm/oti/vm/JxeMetaData
+class load: java/io/File
+class load: com/ibm/oti/util/BinarySearch
+class load: java/security/cert/Certificate
+class load: java/security/cert/Certificate[]
+class load: com/ibm/oti/vm/Jxe[]
+class load: java/security/SecureClassLoader
+class load: java/net/URLClassLoader
+class load: com/ibm/oti/vm/URLAppClassLoader
+class load: com/ibm/oti/vm/URLExtensionClassLoader
+class load: java/net/URL
+class load: java/net/URL[]
+class load: java/net/NetPermission
+class load: java/net/URLStreamHandler
+class load: java/net/URL$1
+class load: java/util/StringTokenizer
+class load: com/ibm/oti/net/www/protocol/file/Handler
+class load: java/lang/String[][]
+class load: java/lang/String[][][]
+class load: com/ibm/oti/util/IdentityHashtable
+class load: com/ibm/oti/vm/StackFrame
+class load: java/security/AccessControlContext
+class load: java/security/SecurityPermission
+class load: java/security/ProtectionDomain
+class load: java/security/ProtectionDomain[]
+class load: java/util/Hashtable[]
+class load: com/ibm/oti/net/www/protocol/jar/Handler
+class load: java/lang/ThreadGroup
+class load: java/lang/Runnable
+class load: java/lang/Thread
+class load: java/net/URLClassLoader$4
+class load: java/util/zip/ZipConstants
+class load: java/util/zip/ZipFile
+class load: java/util/jar/JarFile
+class load: java/net/URLConnection
+class load: java/net/JarURLConnection
+class load: com/ibm/oti/net/www/protocol/jar/JarURLConnection
+class load: java/util/Set
+class load: java/util/AbstractSet
+class load: java/util/SortedSet
+class load: java/util/TreeSet
+class load: com/ibm/oti/net/www/protocol/jar/JarURLConnection$LRUComparitor
+class load: java/util/SortedMap
+class load: java/util/TreeMap
+class load: com/ibm/oti/net/www/protocol/jar/JarURLConnection$1
+class load: java/net/ContentHandler
+class load: java/net/URLConnection$DefaultContentHandler
+class load: java/lang/ref/ReferenceQueue
+class load: java/lang/ref/Reference[]
+class load: java/util/Locale
+class load: java/util/PropertyPermission
+class load: java/util/Locale$1
+class load: com/ibm/oti/net/www/protocol/file/FileURLConnection
+class load: com/ibm/oti/net/www/protocol/jar/JarURLConnection$CacheEntry
+class load: java/util/zip/ZipEntry
+class load: java/util/zip/ZipFile$ZFEnum
+class load: java/io/IOException
+class load: java/util/jar/JarVerifier
+class load: java/util/zip/ZipEntry[]
+class load: java/util/jar/JarEntry
+class load: java/io/ByteArrayInputStream
+class load: java/util/jar/Manifest
+class load: java/util/jar/Attributes
+class load: java/util/jar/InitManifest
+class load: java/io/ByteArrayOutputStream
+class load: java/util/jar/InitManifest$1
+class load: java/util/ArrayList
+class load: com/ibm/oti/util/Util
+class load: java/util/Iterator
+class load: java/util/AbstractList$SimpleListIterator
+class load: java/util/jar/Attributes$Name
+class load: java/util/Arrays
+class load: java/util/jar/JarFile$JarFileInputStream
+class load: java/security/CodeSource
+class load: java/security/Policy
+class load: java/security/Security
+class load: java/util/Hashtable$HashEnumerator
+class load: com/ibm/oti/vm/DefaultPolicy
+class load: com/ibm/oti/vm/DefaultPolicy$1
+class load: java/lang/Long
+class load: com/ibm/oti/vm/DefaultPolicy$PolicyTokenizer
+class load: com/ibm/oti/vm/DefaultPolicy$GrantHolder
+class load: java/security/AllPermission
+class load: java/lang/Class[]
+class load: java/lang/reflect/AccessibleObject
+class load: java/lang/reflect/Member
+class load: java/lang/reflect/Constructor
+class load: java/lang/reflect/ReflectPermission
+class load: java/security/PermissionCollection
+class load: java/security/Permissions
+class load: java/security/AllPermissionCollection
+class load: java/net/SocketPermission
+class load: java/net/InetAddress
+class load: java/lang/Boolean
+class load: java/lang/Byte
+class load: java/net/InetAddress$1
+class load: java/net/InetAddress$Cache
+class load: java/net/InetAddress$CacheElement
+class load: java/net/SocketPermissionCollection
+class load: java/util/PropertyPermissionCollection
+class load: java/security/UnresolvedPermission
+class load: java/security/UnresolvedPermissionCollection
+class load: java/util/Vector$1
+class load: java/io/FileNotFoundException
+class load: java/security/Permissions$PermissionsEnumeration
+class load: java/security/UnresolvedPermissionCollection$1
+class load: java/io/FilePermission
+class load: java/io/FilePermission$1
+class load: java/io/FilePermissionCollection
+class load: java/security/BasicPermissionCollection
+class load: HelloWorld
+class load: java/lang/Package
+class load: com/ibm/oti/vm/AbstractClassLoader$4
+class load: org/eclipse/swt/graphics/Drawable
+class load: org/eclipse/swt/graphics/Device
+class load: org/eclipse/swt/widgets/Display
+class load: int[][]
+class load: org/eclipse/swt/widgets/Display[]
+class load: org/eclipse/swt/widgets/Display$1
+class load: org/eclipse/swt/internal/win32/OS
+class load: org/eclipse/swt/internal/Library
+class load: org/eclipse/swt/internal/win32/OSVERSIONINFO
+class load: org/eclipse/swt/internal/Callback
+class load: org/eclipse/swt/internal/win32/TCHAR
+class load: org/eclipse/swt/internal/win32/WNDCLASS
+class load: org/eclipse/swt/widgets/WidgetTable
+class load: org/eclipse/swt/widgets/Widget
+class load: org/eclipse/swt/widgets/Control
+class load: org/eclipse/swt/widgets/Control[]
+class load: org/eclipse/swt/graphics/Font
+class load: org/eclipse/swt/internal/win32/MSG
+class load: org/eclipse/swt/widgets/Synchronizer
+class load: org/eclipse/swt/widgets/Scrollable
+class load: org/eclipse/swt/widgets/Composite
+class load: org/eclipse/swt/widgets/Canvas
+class load: org/eclipse/swt/widgets/Decorations
+class load: org/eclipse/swt/widgets/Shell
+class load: org/eclipse/swt/internal/win32/DLLVERSIONINFO
+class load: org/eclipse/swt/internal/win32/RECT
+class load: org/eclipse/swt/internal/win32/SHACTIVATEINFO
+class load: org/eclipse/swt/widgets/Menu
+class load: org/eclipse/swt/internal/win32/SHMENUBARINFO
+class load: org/eclipse/swt/widgets/Menu[]
+class load: org/eclipse/swt/internal/win32/LRESULT
+class load: java/lang/Math
+class load: java/lang/Double
+class load: org/eclipse/swt/internal/win32/PAINTSTRUCT
+class load: org/eclipse/swt/graphics/GCData
+class load: org/eclipse/swt/graphics/GC
+class load: org/eclipse/swt/widgets/Event
+
diff --git a/Article-small-cup-of-swt/images/Idea.jpg b/Article-small-cup-of-swt/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Article-small-cup-of-swt/images/Idea.jpg
Binary files differ
diff --git a/Article-small-cup-of-swt/images/ant_script.png b/Article-small-cup-of-swt/images/ant_script.png
new file mode 100644
index 0000000..a31b1c4
--- /dev/null
+++ b/Article-small-cup-of-swt/images/ant_script.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/linux_only.gif b/Article-small-cup-of-swt/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/Article-small-cup-of-swt/images/linux_only.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/ppc01.png b/Article-small-cup-of-swt/images/ppc01.png
new file mode 100644
index 0000000..035fc3b
--- /dev/null
+++ b/Article-small-cup-of-swt/images/ppc01.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/ppc02.png b/Article-small-cup-of-swt/images/ppc02.png
new file mode 100644
index 0000000..74d21ad
--- /dev/null
+++ b/Article-small-cup-of-swt/images/ppc02.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/ppc03.png b/Article-small-cup-of-swt/images/ppc03.png
new file mode 100644
index 0000000..47f8f5d
--- /dev/null
+++ b/Article-small-cup-of-swt/images/ppc03.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/ppc04.png b/Article-small-cup-of-swt/images/ppc04.png
new file mode 100644
index 0000000..78dfd91
--- /dev/null
+++ b/Article-small-cup-of-swt/images/ppc04.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/ppc05.png b/Article-small-cup-of-swt/images/ppc05.png
new file mode 100644
index 0000000..97236f7
--- /dev/null
+++ b/Article-small-cup-of-swt/images/ppc05.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/ppc06.png b/Article-small-cup-of-swt/images/ppc06.png
new file mode 100644
index 0000000..5f5b017
--- /dev/null
+++ b/Article-small-cup-of-swt/images/ppc06.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/ppc07.png b/Article-small-cup-of-swt/images/ppc07.png
new file mode 100644
index 0000000..6fa9fed
--- /dev/null
+++ b/Article-small-cup-of-swt/images/ppc07.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/ppc08.png b/Article-small-cup-of-swt/images/ppc08.png
new file mode 100644
index 0000000..5ba04f2
--- /dev/null
+++ b/Article-small-cup-of-swt/images/ppc08.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/profiles.gif b/Article-small-cup-of-swt/images/profiles.gif
new file mode 100644
index 0000000..fcb6faf
--- /dev/null
+++ b/Article-small-cup-of-swt/images/profiles.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/profiles.png b/Article-small-cup-of-swt/images/profiles.png
new file mode 100644
index 0000000..e1d71e7
--- /dev/null
+++ b/Article-small-cup-of-swt/images/profiles.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/swtjar.png b/Article-small-cup-of-swt/images/swtjar.png
new file mode 100644
index 0000000..53b1b50
--- /dev/null
+++ b/Article-small-cup-of-swt/images/swtjar.png
Binary files differ
diff --git a/Article-small-cup-of-swt/images/tag_1.gif b/Article-small-cup-of-swt/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/Article-small-cup-of-swt/images/tag_1.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/tag_2.gif b/Article-small-cup-of-swt/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/Article-small-cup-of-swt/images/tag_2.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/tag_3.gif b/Article-small-cup-of-swt/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/Article-small-cup-of-swt/images/tag_3.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/tag_4.gif b/Article-small-cup-of-swt/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/Article-small-cup-of-swt/images/tag_4.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/tag_5.gif b/Article-small-cup-of-swt/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/Article-small-cup-of-swt/images/tag_5.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/tag_6.gif b/Article-small-cup-of-swt/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/Article-small-cup-of-swt/images/tag_6.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/tag_7.gif b/Article-small-cup-of-swt/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/Article-small-cup-of-swt/images/tag_7.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/tip.gif b/Article-small-cup-of-swt/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/Article-small-cup-of-swt/images/tip.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/tryit.gif b/Article-small-cup-of-swt/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/Article-small-cup-of-swt/images/tryit.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/images/win_only.gif b/Article-small-cup-of-swt/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/Article-small-cup-of-swt/images/win_only.gif
Binary files differ
diff --git a/Article-small-cup-of-swt/pocket-PC.html b/Article-small-cup-of-swt/pocket-PC.html
new file mode 100644
index 0000000..31ffc91
--- /dev/null
+++ b/Article-small-cup-of-swt/pocket-PC.html
@@ -0,0 +1,799 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=windows-1252">
+ <title>A small cup of SWT</title>
+ <link rel="stylesheet" href="../default_style.css">
+</head>
+<body link="#0000ff" vlink="#800080">
+<div align="right"><font face="Times New Roman, Times, serif" size="2">
+© Copyright International Business Machines Corporation, 2003. All rights reserved.</font>
+<table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tbody>
+ <tr>
+ <td align="left" valign="top" colspan="2" bgcolor="#0080c0"><b><font
+ face="Arial,Helvetica"><font color="#ffffff"> Eclipse Corner
+Article</font></font></b></td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<div align="left">
+<h1 title="A small cup of SWT"><img src="images/Idea.jpg" height="86"
+ width="120" align="middle"> </h1>
+</div>
+<h1 align="center">A small cup of SWT</h1>
+<div align="center">A bag of hints, tricks and recipes <br>
+for developing SWT apps on the Pocket PC</div>
+<blockquote><b>Summary</b><br>
+ <br>
+Are you interested in developing applications for the Microsoft&reg; Pocket
+PC? Are
+you a desktop developer curious about embedded user interfaces? A
+well-built embedded application is both user and resource friendly.
+User expectations are high. Resources are very limited...<br>
+ <p><b> By Christophe Cornu, IBM OTI Labs</b><br>
+ <font size="-1">September 19, 2003</font></p>
+</blockquote>
+<hr width="100%">
+<h2>Introduction</h2>
+<p>In the first part of the article, we will list some common UI
+guidelines that are followed by native Pocket PC applications. We will
+show
+how they map to the SWT API. In the second part, we will look at ways
+to
+reduce the size of SWT applications. In the last part, we
+will examine how application startup time can be improved by writing an
+SWT application using the Connected Limited Device Configuration (CLDC) Java&trade; profile.</p>
+<h2><a name="section_1"></a> UI guidelines for the Pocket PC</h2>
+A native personal digital assistant (PDA) application follows the rules of its platform. These
+guidelines contribute to the end user experience. They define a common
+look and feel and make the best use of the limited resources. For
+example, PDAs often provide a small screen and
+no
+keyboard. The Pocket PC defines a few essential user interface patterns.
+<h3>Application bringing up a File dialog box</h3>
+On the Pocket PC, the main application window is always full screen.
+The bottom of the screen is reserved for the menu bar. There is no
+border or title. Instead, the title appears at the top of the screen
+along with the Start menu and the clock (Figure 1). Here is a small
+Java program
+that uses the SWT API to create a File dialog box.<br>
+<br>
+<div style="text-align: center;"><img src="images/ppc01.png"
+ alt="native full screen file dialog" border="1"
+ style="width: 240px; height: 320px;"
+ title="native full screen file dialog">&nbsp;</div>
+<div style="text-align: center;">Figure 1 - File dialog box
+</div>
+<br>
+<pre>
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+public class FileDialogMain {
+
+public static void main(String[] args) {
+ Display display = new Display();
+<img src="images/tag_1.gif" alt="tag 1" style="width: 24px; height: 13px;" title=""> Shell shell = new Shell(display);
+<img src="images/tag_2.gif" alt="tag 2" style="width: 24px; height: 13px;" title=""> shell.setText("Main");
+ Menu menu = new Menu(shell, SWT.BAR);
+<img src="images/tag_3.gif" alt="tag 3" style="width: 24px; height: 13px;" title=""> shell.setMenuBar(menu);
+ shell.open();
+ FileDialog dialog = new FileDialog(shell, SWT.OPEN);
+ String name = dialog.open();
+ if (name != null) shell.setText(name);
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
+</pre>
+Use <img src="images/tag_1.gif" alt="tag 1"
+ style="width: 24px; height: 13px;" title=""> to create
+your application window. Two other styles are commonly used by Pocket
+PC applications. If your application is dialog-based, as in Figure 3,
+you
+would invoke the constructor <code>Shell(display, SWT.CLOSE)</code>.
+The style <code>SWT.RESIZE</code> creates a Shell that is
+automatically resized when the virtual keyboard of the Pocket PC is
+used (Figure 4). No other Shell style is relevant to the Pocket PC. <br>
+<br>
+<b>Note about Pocket PC 2002</b>
+The Shell created in <img src="images/tag_1.gif" alt="tag 1"
+ style="width: 24px; height: 13px;" title=""> contains a smart minimize
+button on Pocket PC 2002 (see Figure 2 - upper-right corner). The user
+can tap on the smart minimize button to hide (but not close) the
+current application and to return to the last application used. The
+application can then be restored through the system task list - a
+utility for managing applications currently running. To see the smart
+minimize button in Figure 2, run the previous example and click Cancel
+to close the File dialog.<br>
+<br>
+<div style="text-align: center;"><img src="images/ppc08.png"
+ alt="Pocket PC 2002 smart minimize" border="1"
+ style="width: 240px; height: 320px;"
+ title="Pocket PC 2002 smart minimize"><br>
+</div>
+<div style="text-align: center;">Figure 2 - Smart minimize on Pocket PC
+2002<br>
+</div>
+<br>
+<img src="images/tag_2.gif" alt="tag 2"
+ style="width: 24px; height: 13px;" title=""> <code>Shell.setText </code>specifies
+the text displayed in the navigation bar at the top of the screen
+(Figure 1). This text is also displayed in the system task list.<br>
+<br>
+There is one last important step to accomplish before we get a nice-looking
+Pocket PC application....&nbsp; We need to create a menu bar and
+<img src="images/tag_3.gif" alt="tag 3"
+ style="width: 24px; height: 13px;" title=""> attach it to the Shell.
+The menu bar is a gray rectangular area at the very bottom of the
+screen (Figure 1). Any Pocket PC application must set a menu bar on the
+top-level Shell.<br>
+<br>
+<img src="images/tip.gif" alt="Tip" style="width: 62px; height: 13px;"
+ title=""> PDA users don't explicitly terminate an application prior
+to switching to a new one. Consequently, the menu bar never contains a
+Close menu item. This differs from desktop applications, which often
+define a File menu with a Close menu item.
+<h3>Dialog-based application</h3>
+On the Pocket PC, a dialog-based application is full screen and contains
+a small OK button (see Figure 3, upper-right corner). The following
+Java program creates an SWT-dialog-based application.<br>
+<br>
+<div style="text-align: center;"><img src="images/ppc07.png" alt="ok button" border="1" style="width: 240px; height: 320px;"
+ title="ok button"></div>
+<div style="text-align: center;">Figure 3 - OK button<br>
+</div>
+<pre>
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+public class OkButton {
+
+public static void main(String[] args) {
+ Display display = new Display();
+<img src="images/tag_1.gif" alt="tag 1" style="width: 24px; height: 13px;" title=""> Shell shell = new Shell(display, SWT.CLOSE);
+ shell.setText("Main");
+ Menu menu = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(menu);
+<img src="images/tag_2.gif" alt="tag 2" style="width: 24px; height: 13px;" title=""> shell.addListener(SWT.Close, new Listener() {
+ public void handleEvent(Event e) {
+<img src="images/tag_3.gif" alt="tag 3" style="width: 24px; height: 13px;" title=""> System.out.println("Ok button tapped");
+ }
+ });
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
+</pre>
+The shell style <img src="images/tag_1.gif" alt="tag 1"
+ style="width: 24px; height: 13px;" title=""> <code>SWT.CLOSE </code>creates
+a dialog with a small OK button. The application <img
+ src="images/tag_2.gif" alt="tag 2" style="width: 24px; height: 13px;"
+ title=""> registers the<code> SWT.Close</code> event that is notified
+when the OK button is selected. The shell can then <img
+ src="images/tag_3.gif" alt="tag 3" style="width: 24px; height: 13px;"
+ title=""> process user data before closing.
+<h3>Application resizing when the virtual keyboard shows up</h3>
+The Pocket PC does not have a physical keyboard. Instead it provides an
+input panel (the exact name is soft input panel, or SIP). The input
+panel contains the
+image of a keyboard (see figure 5 - bottom part) or an area to
+interpret hand-written characters. The input panel is either hidden
+(Figure 4) or visible (Figure 5) as controlled by the SIP button
+(Figure 4 - the keyboard icon in the bottom-right corner). Here is a
+simple Java application that creates an SWT application that resizes
+automatically when the input panel is set visible or subsequently
+hidden.<br>
+<br>
+<table cellpadding="2" cellspacing="2" border="0"
+ style="text-align: left; width: 700px; margin-left: auto; margin-right: auto;">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">
+ <div style="text-align: center;"> <img src="images/ppc03.png"
+ alt="hidden input window" border="1" style="width: 240px; height: 320px;"
+ title="hidden input window"><br>
+ </div>
+ <div style="text-align: center;">Figure 4 - Input panel
+hidden<br>
+ </div>
+ </td>
+ <td style="vertical-align: top; text-align: center;"><br>
+ </td>
+ <td style="vertical-align: top;">
+ <div style="text-align: center;"> <img src="images/ppc04.png"
+ alt="visible input window" border="1" style="width: 240px; height: 320px;"
+ title="visible input window"><br>
+ </div>
+ <div style="text-align: center;">Figure 5 - Input panel
+visible<br>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<br>
+<pre>
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.layout.*;
+
+public class SipResize {
+
+public static void main(String[] args) {
+ Display display = new Display();
+<img src="images/tag_1.gif" alt="tag 1" style="width: 24px; height: 13px;" title=""> Shell shell = new Shell(display, SWT.RESIZE);
+ shell.setLayout(new FillLayout());
+ shell.setText("Main");
+ Menu mb = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(mb);
+<img src="images/tag_2.gif" alt="tag 2" style="width: 24px; height: 13px;" title=""> Text text = new Text(shell, SWT.MULTI | SWT.V_SCROLL);
+ String buffer = "";
+ for (int i = 0; i &lt; 100; i++) {
+ buffer += "This is line " + i + "\r\n";
+ }
+ text.setText(buffer);
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
+</pre>
+The style <img src="images/tag_1.gif" alt="tag 1"
+ style="width: 24px; height: 13px;" title=""> <code>SWT.RESIZE</code>
+creates a full-screen shell that is
+resized automatically when the user shows or hides the input panel.
+The shell fills the space left between the navigation menu bar at the
+top
+and the input panel or the menu bar at the bottom (Figure 5). The
+sample adds <img src="images/tag_2.gif" alt="tag 2"
+ style="width: 24px; height: 13px;" title=""> widgets to make the
+transition more visual.<br>
+<br>
+<i><b><img src="images/tip.gif" alt="tip"
+ style="width: 62px; height: 13px;" title=""></b></i>A native Pocket PC
+application is expected to be "friendly" with the input panel. That
+implies:
+<ol>
+ <li>The user must be able to input data with the input panel - every
+time
+the application requires text entry. The input panel should not hide
+text widgets. The first solution is to layout text widgets in
+the first part of the screen. The second solution is to resize the
+window when the input panel is turned on - by using the shell style <code>SWT.RESIZE</code>,
+as shown in the sample above.</li>
+ <li>The application should restore the input panel to the state the
+user left it in the last time this application was used. This state is
+automatically restored by SWT and requires no particular application
+handling.</li>
+</ol>
+<h3>Application using a pop-up menu</h3>
+The Pocket PC uses a
+stylus instead of a mouse. The traditional right-click button is
+replaced with the stylus hold gesture defined as follows. The user taps
+on
+the screen with the stylus and holds it down. The Pocket PC 2002
+provides a visual cue by drawing red circles
+around the stylus during this gesture (Figure 6). After a certain
+amount of time, a popup menu shows up (Figure 7). <br>
+<br>
+<table cellpadding="2" cellspacing="2" border="0"
+ style="text-align: left; width: 700px; margin-left: auto; margin-right: auto;">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">
+ <div style="text-align: center;"> <img src="images/ppc05.png"
+ alt="stylus hold" border="1" style="width: 240px; height: 320px;"
+ title="stylus hold"> </div>
+ <div style="text-align: center;">Figure 6 - Stylus hold animation
+on Pocket PC 2002<br>
+ </div>
+ </td>
+ <td style="vertical-align: top;"><br>
+ </td>
+ <td style="vertical-align: top;">
+ <div style="text-align: center;"> <img src="images/ppc06.png"
+ alt="popup menu activated by stylus hold" border="1"
+ style="width: 240px; height: 320px;"
+ title="popup menu activated by stylus hold"> </div>
+ <div style="text-align: center;">Figure 7 - Pop-up menu activated<br>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<pre>
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+public class StylusHold {
+
+public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("Main");
+ Menu mb = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(mb);
+<img src="images/tag_1.gif" alt="tag 1" style="width: 24px; height: 13px;" title=""> Menu menu = new Menu(shell, SWT.POP_UP);
+ MenuItem item = new MenuItem(menu, SWT.CASCADE);
+ item.setText("item 1");
+ MenuItem item2 = new MenuItem(menu, SWT.CASCADE);
+ item2.setText("item 2");
+ shell.setMenu(menu);
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+}
+}
+</pre>
+The <img src="images/tag_1.gif" alt="tag 1"
+ style="width: 24px; height: 13px;" title=""> pop-up menu uses the same <code>SWT.POP_UP</code>
+style as on the desktop platform.<span style="font-weight: bold;"><br>
+<br>
+</span><i><b><img src="images/tip.gif" alt="tip"
+ style="width: 62px; height: 13px;" title=""></b></i>The event <code>SWT.MenuDetect</code>
+can be registered to detect the
+hold gesture
+on a Shell. The events <code>SWT.MOUSE_UP</code>, <code>SWT.MOUSE_DOWN</code>
+and <code>SWT.MOUSE_MOVE</code> map to the corresponding stylus
+actions on the Pocket PC.
+<h2><a name="section_2"></a> Memory and size</h2>
+This section discusses the size contributed by the SWT library on the
+Microsoft Windows &reg; desktop platform and on an embedded target (Pocket PC). The
+internal architecture of SWT allows parts of the API to be removed.
+Thus the SWT library can be customized to fit within the requirements of
+a
+particular target.
+<h3> Size of different SWT configurations</h3>
+<h4>Structure of the SWT API</h4>
+The full SWT API is divided into the following packages.
+<ul>
+ <li> org.eclipse.swt (constants)</li>
+ <li> org.eclipse.swt.widgets (native widgets)</li>
+ <li> org.eclipse.swt.events (event listeners)</li>
+ <li> org.eclipse.swt.graphics (graphics drawing, image decoders)</li>
+ <li> org.eclipse.swt.layout (layouts)</li>
+ <li> org.eclipse.swt.dnd (drag and drop)</li>
+ <li>org.eclipse.swt.ole (ole)</li>
+ <li> org.eclipse.swt.accessibility (accessibility)</li>
+ <li> org.eclipse.swt.custom (custom widgets)</li>
+ <li> org.eclipse.swt.printing (printing)</li>
+ <li> org.eclipse.swt.program (registry)</li>
+</ul>
+The SWT for Pocket PC supports the embedded SWT API. This
+represents a subset within the following packages.
+<ul>
+ <li> org.eclipse.swt</li>
+ <li>org.eclipse.swt.widgets</li>
+ <li>org.eclipse.swt.events</li>
+ <li>org.eclipse.swt.graphics</li>
+ <li>org.eclipse.swt.layout</li>
+</ul>
+The SWT JAR file provides the public API
+and its implementation for a
+particular platform. The SWT native library defines the mapping between
+internal SWT Java methods and the operating system. It also defines a
+number of callbacks that allow the operating system to call into Java.
+<br><br>
+The standard Windows SWT jar is about 994KB. The class file debug
+information accounts for about 30% (307KB). The full Windows SWT jar
+without debug information uses 687KB. In addition, the Windows SWT native
+shared library takes 276KB.<br>
+<br>
+The standard Pocket PC SWT jar supports a subset of the SWT API. It
+is about 436KB without debug information. In addition, the Pocket PC SWT
+native shared library (ARM processor)
+takes 133KB.<br>
+<br>
+Custom SWT jars and native libraries can be built with all or part of
+the SWT API. Figure 8 provides the size distribution for
+the standard Windows SWT jar library (as shipped with Eclipse 2.1).
+<br>
+<div style="text-align: center;"><img src="images/swtjar.png"
+ title="SWT windows jar" alt="SWT windows jar"
+ style="border: 1px solid ; width: 375px; height: 301px;"></div>
+<div style="text-align: center;">Figure 8 - SWT jar size distribution
+(Windows, SWT version 2.1)
+</div>
+<h3> Tips to reduce the size of the SWT library</h3>
+A custom SWT jar can be built to achieve a particular size requirement.
+The Eclipse Web site provides access to SWT libraries for different
+targets (see the <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/faq.html#pocketpclibrary">SWT FAQ</a>). These different
+versions are built and customized automatically using Ant scripts.
+Follow these steps to build your own custom SWT jar. (The SWT source code is accessible from the Eclipse Web site.)
+<br>
+<ol>
+ <li>Import the two projects org.eclipse.swt and org.eclipse.swt.win32.wce_ppc.arm
+into your Eclipse workspace.</li>
+ <li>Locate the Ant script build_custom.xml. This file is located
+in the project org.eclipse.swt.win32.wce_ppc.arm.</li>
+ <li>Run this Ant script from within Eclipse. Modify the default
+Property targets according to the SWT API you require. The Ant script
+outputs the custom SWT jar to the folder org.eclipse.swt.win32.wce_ppc.arm/ws/win32.</li>
+</ol>
+<div style="text-align: center;"><img src="images/ant_script.png"
+ title="ant script to build custom SWT jar"
+ alt="ant script to build custom SWT jar"
+ style="height: 651px; width: 620px;"> <br>
+Figure 9 - Ant script used to build a custom SWT jar<br>
+</div>
+<br>The standard Pocket PC SWT jar is built with the Property targets
+checked on Figure 9. This configuration includes the first three
+reductions
+discussed below.
+<h4> Exclude Debug Information</h4>
+Excluding debug information is the single most useful optimization to
+be considered. The SWT jar is reduced by 30%. Numbers below assume the
+debug information has been excluded.
+<h4> Exclude Custom Widgets</h4>
+Custom widgets are about 150KB (representing 23% of the SWT JAR file). Write embedded SWT applications
+that only use native widgets (org.eclipse.swt.widgets). Avoid custom
+widgets. This trade-off reduces significantly the size of the SWT
+jar.
+<h4>Exclude Accessibility and DND</h4>
+This option excludes Accessibility and drag-and-drop which together account for about 117KB (or 17% of the SWT JAR file).
+<h4> Exclude Image Decoders</h4>
+The image decoders are 65KB (or 10% of the file). SWT uses run-time introspection
+to search for the available decoders. A decoder can be removed if it is
+not needed. Class file decoders currently reside in the internal
+package
+org.eclipse.swt.internal.image.
+<h4> Exclude Layouts</h4>
+Layouts are 10KB (less than 1% of the file).
+<h4> Use J2ME</h4>
+The J2ME CLDC API is a subset of the standard J2SE API. This option produces an
+SWT jar that is compatible with the J2ME CLDC profile.<br><br>
+<img src="./images/tip.gif" alt="Tip" width="62" height="13"> Layouts,
+graphics and image decoders are very useful even in the context of an
+SWT embedded application. It is desirable to keep these packages
+unless
+size requirements are very tight.
+<h4> To go further</h4>
+Further fine-grained size reduction can be considered to fulfill
+extremely tight requirements.
+<ul>
+ <li> Unused SWT classes can simply be removed. For example, the
+class <code>org.eclipse.swt.widgets.Tree</code> can be removed if the
+SWT
+application is not using the tree widget. SWT is mostly implemented in
+Java. A tool - an obfuscator for example - can be used to exclude
+unused SWT classes.</li>
+ <li>Removing unused JNI OS calls can reduce the size of the native
+SWT library.
+Each JNI call is wrapped with a preprocessor directive <code>#ifndef
+OS_METHODNAME</code>. Special tools can determine which SWT native
+methods
+are not referenced through all possible execution paths of a
+particular SWT application. This information is used to build a header
+file with a list of native methods to exclude. A sample header file
+defines.h is available in the org.eclipse.swt project under the
+folder "Eclipse SWT PI"/win32/library.</li>
+</ul>
+Detailed description of these last two very specialized optimizations
+is beyond the scope of this article. Developers who are interested are invited
+to use the SWT newsgroup
+(<a href="news://news.eclipse.org/eclipse.platform.swt">news://news.eclipse.org/eclipse.platform.swt</a>).
+<h2><a name="section_3"></a> Startup time</h2>
+A PDA user tends to switch quickly between tasks. For instance: “Take a
+note. Update a
+meeting schedule. Read an email. Monitor the GPS position”. Application
+startup time must not interfere with this workflow. Startup time must
+be as short as possible. We will see in this section when an SWT
+application becomes visible on the Pocket PC screen and when it
+becomes responsive to user input. It is then possible to architect an
+SWT application so that lengthy processing code does not freeze the
+application on startup.<br>
+<br>
+Let’s consider a simple application called MyApp. This application
+uses some form of persistent storage (e.g. a local file, a database
+accessed wirelessly etc). Establishing that connection takes in the
+order of five seconds. The user starts the application, performs some
+queries using the UI, and modifies a record in the database. The
+demo goes very well. The application is deployed to the PDAs of each
+sales-person in the company. The team of developers receives hundreds
+of phone calls the next day. The application does not work. The PDA
+is broken. Some users have even hard reset their devices before the
+five-second initialization period ended. Back to the whiteboard…<br>
+<br>
+<i><b> Startup time - bad example with lengthy initialization code
+before the SWT event loop</b></i>
+<pre>
+import org.eclipse.swt.widgets.*;
+
+public class MyApp {
+
+static {
+<img src="images/tag_1.gif" alt="tag 1" width="24" height="13"> connectDataBase();
+}
+
+public static void main(String argv[]) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("MyApp");
+<img src="images/tag_2.gif" alt="tag 2" width="24" height="13"> shell.open();
+<img src="images/tag_3.gif" alt="tag 3" width="24" height="13"> while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ closeDataBase();
+ display.dispose();
+}
+
+static void connectDataBase() {
+ try {
+ Thread.sleep(5000);
+ } catch (Exception e) {}
+}
+
+static void closeDataBase() {
+ try {
+ Thread.sleep(5000);
+ } catch (Exception e) {}
+}
+}
+</pre>
+The application <code>MyApp</code> becomes visible on the Pocket PC
+when the Java
+virtual machine has opened the <img src="images/tag_2.gif" alt="tag 2"
+ width="24" height="13"> shell<code></code>. At this moment, a full-size window is
+opened. The title is visible in the navigation bar. The title
+also appears in the Pocket PC task list. <img src="images/tag_2.gif"
+ alt="tag 2" width="24" height="13"> is the first step providing visual
+feedback to the user. This application will be invisible for at least five
+seconds, time for the <img src="images/tag_1.gif" alt="tag 1"
+ style="width: 24px; height: 13px;" title=""> connection to the
+database to be realized.
+The <img src="images/tag_3.gif" alt="tag 3" width="24" height="13">
+while loop encloses the SWT event loop. No user interaction occurs
+until
+the Java virtual machine (JVM) enters the event loop. No paint callback is
+processed and native widgets don’t draw until this happens. In summary,
+the user does not see the application prior to opening the shell<code></code>.
+The
+application is not usable prior to running the event loop.
+<h3>Reduce application code on startup</h3>
+The call to the method <code>connectDataBase()</code> should be
+executed after the
+<code>Shell</code> is opened and after the event loop is entered. One
+solution is to
+bring up a screen with a message asking the user to tap on a button to
+start the connection. The selection callback for the button is used to
+call <code>connectDataBase()</code>. The startup time is not impacted
+by
+lengthy initialization user code anymore.<br>
+<br>
+Be aware of what application code is actually executed before the event
+loop is entered. It is particularly important to pay attention to
+the application class initializers.<br>
+<br>
+<img src="images/tip.gif" alt="tip" width="62" height="13"> Before the
+event loop is entered:
+<ul>
+ <li> Invoke as few application classes as possible so that the JVM’s
+classloader does not have to resolve them on startup. If your main
+class inherits from a deep hierarchy, all the super classes must be
+resolved and initialized before the Main method actually gets to run.</li>
+ <li>Review each of your class initializers. Lengthy operations
+should not take place inside class initializers. Class initializers are
+often used to load resources and native libraries. This common Java
+idiom may cause here an unacceptable startup time.</li>
+</ul>
+<i><b>Refactoring – move lengthy initialization code to callbacks
+executed after the event loop has been entered</b></i><br>
+<pre>
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public class MyApp {
+
+public static void main(String argv[]) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("MyApp");
+ shell.setLayout(new FillLayout());
+ final Button button = new Button(shell, SWT.PUSH);
+ button.setText("Connect");
+ button.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event e) {
+ button.setText("Connecting");
+<img src="images/tag_1.gif" alt="tag 1" width="24" height="13"> connectDataBase();
+ button.setText("Connected");
+ }
+ });
+ shell.open();
+<img src="images/tag_2.gif" alt="tag 2" width="24" height="13"> while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ closeDataBase();
+ display.dispose();
+}
+
+static void connectDataBase() {
+ try {
+ Thread.sleep(5000);
+ } catch (Exception e) {}}
+
+static void closeDataBase() {
+ try {
+ Thread.sleep(5000);
+ } catch (Exception e) {}
+}
+}
+</pre>
+The <img src="images/tag_1.gif" alt="tag 1" width="24" height="13">
+lengthy call to the <code>connectDataBase()</code> method has moved
+from the class
+constructor to an event callback. This event callback is executed after
+the<img src="images/tag_2.gif" alt="tag 2" width="24" height="13">
+event
+loop is entered. This refactoring improves the startup time of the
+application. This implementation is still very naive. It
+illustrates the need to avoid lengthy initialization code before
+running the event loop. A better solution may use a progress meter and
+a
+separate thread.
+<br>
+<br>
+<i><b><img src="images/tip.gif" alt="tip" width="62" height="13">
+Diagnose if an application runs too much initialization code</b></i><br>
+Follow these two easy steps to evaluate
+application initialization time.<br>
+<br>
+&nbsp;1. Add a line at the beginning of the Main class (If Main extends
+one of your classes, instrument this super class instead. This
+superclass is loaded first).
+<pre>static long start = System.currentTimeMillis();</pre>
+2. Add the following lines before entering the SWT event loop:
+<pre>
+long end = System.currentTimeMillis();
+System.out.println("User init time: " + (end - start));
+</pre>
+Then check the list of application classes loaded on startup by the
+JVM, as indicated below.<br>
+<br>
+Start the application with the Java console (e.g., java.exe instead of
+javaw.exe). Use the VM argument <code>-verbose</code>. Most JVMs
+output the list
+of Java classes as they get loaded. This can yield useful results
+and direct the effort for refactoring.<br>
+<br>
+If overall startup time remains too high, a lighter Java profile needs
+to be considered as discussed below.
+<h3>Reduce Java library code initialization on startup</h3>
+The JVM must resolve a certain number of core Java
+classes before it can execute the Main method of an application. The
+virtual machine must clearly resolve the base class <code>java.lang.Object</code>.
+The actual number of core Java classes depends on which Java profile
+the application runs against.
+The SWT Pocket PC port can be run against the familiar J2SE profile and
+the J2ME CLDC one.
+<h4> Startup time – J2SE</h4>
+This data was collected on a Pocket PC 2002 HP Jornada 565 (with a
+typical CPU ARM 206 Mhz). The JVM used is the IBM J9 VM for ARM Pocket
+PC. The
+program executed is the SWT HelloWorld for Pocket PC. <a
+ href="HelloWorld.java">Source for HelloWorld.java</a><br>
+The first run is used to collect the list of classes loaded by the
+VM until the application shows up. This information is simply obtained
+by passing the VM flag <code>-verbose</code> to the Java console.
+For the second run, the VM was executed without any <code>-verbose </code>flag
+and without console. The time was measured from the moment the
+application shortcut is tapped in the Pocket PC Windows Explorer and
+the moment the HelloWorld application comes up.<br>
+<br>
+Total number of classes loaded: 237 (<a href="class_load_j2se.txt">see
+detailed list</a>)<br>
+Number of core classes loaded prior to reaching the Main class: 197<br>
+Startup time: about 4.3 seconds
+<h4> Startup time – J2ME CLDC</h4>
+The same series of data is collected using the J2ME SWT Pocket PC
+jar. The VM used was the Pocket PC ARM J9 VM, with the J2ME CLDC class
+library. Note that the CLDC Java profile does not contain the Java API
+System.loadLibrary. The SWT jar for CLDC cannot load the native SWT
+library as a result. The IBM J9 VM is instructed to use the CLDC Java
+profile and to load the native SWT library swt-win32-3002.dll with the
+following VM command.
+<pre>-jcl:cldc:loadlibrary=swt-win32-3002</pre>
+
+Total number of classes loaded: 87 (<a href="class_load_j2me_cldc.txt">see
+detailed list</a>)<br>
+Number of core classes loaded prior to reaching the Main class: 48<br>
+Startup time: about 1.9 seconds
+<div style="text-align: center; font-weight: bold;"> </div>
+<div align="center"><img src="./images/profiles.png"
+ alt="Number of classes loaded J2SE versus CLDC"
+ style="border: 1px solid ; width: 421px; height: 239px;"
+ title="CLDC has a smaller overhead than J2SE" hspace="5" vspace="5"> <br>
+Figure 10 -
+Number of classes loaded (J2SE versus CLDC)
+</div>
+<br>
+The number of core classes loaded prior to reaching the Main class
+in the J2ME CLDC profile is about one fourth of the number the JVM needs to
+load for the same program when using the J2SE profile. The startup
+time is roughly cut in half in this example. Application classes
+represent the Main class of the user
+application and all classes subsequently loaded. SWT classes are
+included in this category. The number of application classes does not
+really vary with the Java profile in this example.<br>
+<br>
+The J2ME CLDC profile is a good choice for people developing embedded
+applications. It is possible to write an application that runs on
+either J2SE or J2ME CLDC profiles by following some simple rules.
+Profile-specific calls can be constrained to a particular
+class. This profile class encapsulates the required refactoring when
+porting a J2SE application to CLDC. For example, a stream opened using
+java.io.FileOutputStream in the J2SE profile could be implemented with
+the CLDC Connector.open API.<br>
+<br>
+Further startup time improvement may require using special deployment
+features specific to certain VMs and platforms. For example, the IBM J9
+VM
+can load classes under an optimized format called JXE. This format
+reduces the work required by the classloader at runtime.<br>
+<br>
+In summary, application startup time is dependent on two factors.
+<ul>
+ <li> User initialization code executed before the SWT event loop is
+executed.</li>
+ <li>The type of Java profile. A lightweight profile (which requires
+fewer core classes) is preferable. SWT for the Pocket PC can be used
+against the J2ME CLDC profile.</li>
+</ul>
+Further optimization can be achieved by using a custom deployment format
+such as the J9 JXE format. It is possible to approach the startup time
+of a native Pocket PC application by combining these techniques.
+<h2> Conclusion</h2>
+Each embedded platform presents unique characteristics. Common Pocket
+PC UI features have been reviewed. The examples can serve as a
+guide to write SWT applications that feel and look native on the
+Pocket PC. Storage resources vary greatly and can be very scarce. A
+custom SWT jar can be built with only the portions of the API used by
+an SWT application. Design choices can be made to balance between
+functionality and a size requirement. Application startup time is also an
+important factor of usability. Lengthy initialization code should be
+avoided before the SWT event loop is entered. Writing your SWT
+application over the CLDC Java profile allows you to benefit from the
+reduced overhead of this profile.
+<h2><a name="Quick_Reference"></a>Quick reference<br>
+</h2>
+<a
+ href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/faq.html#pocketpcstart">
+</a>
+<p><a
+ href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/faq.html#pocketpcstart">SWT
+FAQ - What do I need to do to run SWT on the PocketPC?</a><br>
+<a name="SWT_FAQ_2"></a><a
+ href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/faq.html#pocketpclibrary">SWT
+FAQ - Where is the SWT library for the PocketPC?</a>
+</p>
+<p><small>IBM is a registered trademark of International Business Machines
+Corporation in the United States, other countries, or both.</small></p>
+<p><small>Java and all Java-based trademarks are trademarks
+of Sun Microsystems, Inc. in the United
+States,
+other countries, or both.</small></p>
+<p><small>Microsoft and Windows are registered trademarks of Microsoft
+Corporation in the United States, other countries, or both.</small></p>
+<p><small>Other company, product, and service names may be trademarks
+or service marks of others.</small></p>
+</body>
+</html>
diff --git a/GettingStartedWithSWT/swt-getting-started.html b/GettingStartedWithSWT/swt-getting-started.html
new file mode 100644
index 0000000..444912b
--- /dev/null
+++ b/GettingStartedWithSWT/swt-getting-started.html
@@ -0,0 +1,117 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+<TITLE>Getting Started with SWT</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+<body>
+&nbsp;
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+ <tr>
+ <td ALIGN=left VALIGN=top COLSPAN="2" BGCOLOR="#0080c0"><b><font face="Arial,Helvetica"><font color="#ffffff">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+</table>
+<h1> <img SRC="../../images/Idea.jpg" height=86 width=120 align=center></h1>
+<center>
+ <h1> Getting Started with SWT</h1>
+</center>
+<center>
+ <h3> Exploring the features of the Eclipse Standard Widget Toolkit</h3>
+</center>
+<blockquote><b>Summary</b> <br>
+ This article contains several examples that show how to use the features of
+ the Eclipse Widget toolkit, SWT. Each example builds upon the ones before. The
+ first example shows how to create an empty window. The second example adds some
+ buttons to the window. The third example registers a listener for events on
+ one of the buttons.</blockquote>
+<p>
+<hr WIDTH="100%">
+<br>
+<p>The examples below show how to use SWT to create stand-alone applications,
+ and provide a good basis for experimenting with SWT. The Eclipse Workbench defines
+ the UI paradigm and how editors and views are integrated. It provides the display
+ and shell that are created below so you don't need to create them for you Workbench
+ plug-in user interfaces.</p>
+<p>For further details on SWT, take a look at the <a href="swt-widget-hierarchy.html">widget
+ hierarchy</a> and <a href="swt-style-bits.html">supported style bits</a>. Then
+ try modifying the example below with different widgets, styles, and actions.</p>
+<h2> <a NAME="BM2_1_Example_1__Creating_your_first_win"></a>Creating your first
+ window</h2>
+<pre>// Create a shell.&nbsp;
+Display display = new Display(); // The "parent" of a shell is the display it is created on.
+
+Shell shell =
+
+
+
+
+
+ new Shell (display); // Create the top level window.&nbsp;
+shell.open (); // Open it
+
+// This is the event loop.
+
+while (!shell.isDisposed ())&nbsp;
+&nbsp; if (!display.readAndDispatch ()) display.sleep ();</pre>
+<h2> <a NAME="BM2_2_Example_2__Adding_a_widget"></a><b>Adding a widget</b></h2>
+This example builds upon the first example and adds two buttons: A push button
+and a check box. Notice how the constructors in SWT require you to pass the parent
+widget and style bits. Style bits are used to specify values required to create
+the underlying OS resource. In this case it specifies the type of button to create.
+The code added by this example is marked in <i>italic.</i>
+<pre>Display display = new Display();
+
+Shell shell = new Shell (display);
+
+<i>Button b1 = new Button (shell, SWT.PUSH);&nbsp;
+b1.setText ("Button 1");
+b1.setBounds (0, 0, 100, 60);
+Button b2 =
+
+
+
+
+
+ new Button (shell, SWT.CHECK);
+b2.setText ("Button 2");&nbsp;
+b2.setBounds (0, 60, 100, 45);
+
+</i>shell.open ();&nbsp;
+while (!shell.isDisposed ())&nbsp;
+&nbsp; if (!display.readAndDispatch ()) display.sleep ();</pre>
+<h2> <a NAME="BM2_3_Example_3__Adding_Event_Handlers"></a>Adding event handlers</h2>
+Event handling is done by registering listeners in the same way as in AWT. The
+code added by this example is marked in <i>italic.</i>
+<pre>Shell shell = new Shell ();&nbsp;
+Button b1 = new Button (shell, SWT.PUSH);&nbsp;
+b1.setText ("Button 1");&nbsp;
+b1.setBounds (0, 0, 100, 60);
+
+<i>b1.addMouseListener(new MouseListener() {&nbsp;
+&nbsp; public void mouseDown(MouseEvent e) {&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("mouseDown:");&nbsp;
+&nbsp; };&nbsp;
+&nbsp; public void mouseDoubleClick(MouseEvent e) {&nbsp;
+&nbsp;&nbsp;&nbsp; System.out.println("mouseDoubleClick:");&nbsp;
+&nbsp; };&nbsp;
+&nbsp; public void mouseUp(MouseEvent e) {&nbsp;
+&nbsp;&nbsp;&nbsp; System.out.println("mouseUp:");&nbsp;
+&nbsp;};&nbsp;
+});
+
+</i>Button b2 = new Button (shell, SWT.CHECK);&nbsp;
+b2.setText ("Button 2");&nbsp;
+b2.setBounds (0, 60, 100, 45);&nbsp;
+shell.open ();
+&nbsp;&nbsp;<a NAME="BM2_4_LayoutManagers_in_SWT"></a>
+Display display =
+
+ shell.getDisplay ();&nbsp;
+while (!shell.isDisposed ())&nbsp;
+&nbsp; if (!display.readAndDispatch ()) display.sleep ();</pre>
+<br>
+&nbsp;
+</body>
+</html>
diff --git a/GettingStartedWithSWT/swt-style-bits.html b/GettingStartedWithSWT/swt-style-bits.html
new file mode 100644
index 0000000..954e392
--- /dev/null
+++ b/GettingStartedWithSWT/swt-style-bits.html
@@ -0,0 +1,1302 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+<title>SWT Widgets Supported Style Bits</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (Win98; I) [Netscape]">
+ <meta name="Author" content="IBM">
+</head>
+<body>
+
+<h1>
+SWT Widgets<br>
+Supported style bits</h1>
+If you are familiar with AWT you will notice that the way you create widgets
+in SWT is significantly different. In SWT you specify the parent widget.
+This is necessary to create the underlying OS resources. In addition you
+also have the ability to specify initial values for the widget. For example
+to specify what type of button you want to create in the example above
+the values SWT.CHECK and SWT.PUSH are used. All style bits are static integers
+declared by SWT.
+<p>Here is a hierarchical list that identifies which style bits are supported
+by each class. Classes are shown in <b>bold</b>. A widget automatically
+supports all of the style bits supported by its parent(s).
+<br>&nbsp;
+<table BORDER WIDTH="672" cellspacing=0 cellpadding=5>
+<tr>
+<td VALIGN=center WIDTH="9%"><b>Dialog</b></td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">APPLICATION_MODAL</td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">MODELESS</td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">PRIMARY_MODAL</td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">SYSTEM_MODAL</td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%"><b>FileDialog</b></td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">SAVE</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">OPEN</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%"><b>MessageBox</b></td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">OK</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">OK | CANCEL</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">YES | NO</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">YES | NO | CANCEL</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">RETRY | CANCEL</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">ABORT | RETRY | IGNORE</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">ICON_ERROR</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">ICON_INFORMATION</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">ICON_QUESTION</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">ICON_WARNING</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">ICON_WORKING</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%"><b>Caret</b></td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">(No styles)</td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%"><b>Control</b></td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">BORDER</td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%"><b>Button</b></td>
+
+<td VALIGN=center WIDTH="21%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">ARROW</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="20%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="21%">CHECK</td>
+
+<td VALIGN=center WIDTH="12%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="22%">&nbsp;</td>
+
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=center WIDTH="9%">&nbsp;</td>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">FLAT</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD>
+</tr>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">PUSH</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">RADIO</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">TOGGLE</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >Label</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">SEPARATOR |
+HORIZONTAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">SEPARATOR | VERTICAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">SEPARATOR | SHADOW_IN</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">SEPARATOR |
+SHADOW_OUT</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">WRAP</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >ProgressBar</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">SMOOTH</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">HORIZONTAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">VERTICAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >Sash</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">HORIZONTAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">VERTICAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >Scale</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">HORIZONTAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">VERTICAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >Scrollable</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">H_SCROLL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">V_SCROLL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%"><b
+ >Composite</B></TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">NO_MERGE_PAINTS</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">NO_REDRAW_RESIZE</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">NO_FOCUS</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">NO_BACKGROUND</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >Canvas</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%"><b
+ >Decorations</B></TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">BORDER</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">CLOSE</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">MIN</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">MAX</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">NO_TRIM</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">RESIZE</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">TITLE</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%"><b
+ >Shell</B></TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >Combo</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">SIMPLE</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">DROP_DOWN</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">READ_ONLY</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >CoolBar</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">FLAT</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">WRAP</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >Group</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">SHADOW_IN</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">SHADOW_OUT</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">SHADOW_ETCHED_IN</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">SHADOW_ETCHED_OUT</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">SHADOW_NONE</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >OleClientSite</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%"><b
+ >OleControlSite</B></TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >OleFrame</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >TabFolder</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >Table</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">SINGLE</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">MULTI</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">CHECK</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">FULL_SELECTION</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >ToolBar</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">WRAP</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">FLAT</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%"><b
+ >List</B></TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">SINGLE</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">MULTI</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%"><b
+ >TextEditor</B></TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">READ_ONLY</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">WRAP</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">SINGLE</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">MULTI</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >RichText</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%"><b
+ >Text</B></TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%"><b
+ >Tree</B></TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">SINGLE</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">MULTI</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">CHECK</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >Slider</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">VERTICAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">HORIZONTAL</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%"><b
+ >DragSource</B></TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">DROP_NONE</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">DROP_COPY</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">DROP_LINK</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="8%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">DROP_MOVE</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%"><b
+ >DropTarget</B></TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">DROP_NONE</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">DROP_COPY</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">DROP_LINK</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">DROP_MOVE</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%"><b
+ >Item</B></TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >CoolItem</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">(No styles)</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >MenuItem</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">CHECK</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">CASCADE</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">PUSH</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">RADIO</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">SEPARATOR</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >TabItem</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">(No styles)</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >TableColumn</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">(No styles)</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >TableItem</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">(No styles)</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >ToolItem</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">PUSH</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">CHECK</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">RADIO</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">SEPARATOR</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">DROP_DOWN</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%"><b
+ >TreeItem</B></TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">(No styles)</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%"><b
+ >Menu</B></TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">BAR</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">POP_UP</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">DROP_DOWN</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%"><b
+ >ScrollBar</B></TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">VERTICAL</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">HORIZONTAL</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%"><b
+ >Tracker</B></TD>
+ <td vAlign=center width="20%">&nbsp;</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+ <tr>
+ <td vAlign=center width="9%">&nbsp;</TD>
+ <td vAlign=center width="20%">&nbsp;(No styles)</TD>
+ <td vAlign=center width="21%">&nbsp;</TD>
+ <td vAlign=center width="12%">&nbsp;</TD>
+ <td vAlign=center width="22%">&nbsp;</TD>
+ <td vAlign=center width="9%">&nbsp;</TD></TR>
+</table>
+<p>&nbsp;<br>&nbsp; </P>
+</body>
+</html>
diff --git a/GettingStartedWithSWT/swt-widget-hierarchy.html b/GettingStartedWithSWT/swt-widget-hierarchy.html
new file mode 100644
index 0000000..1360892
--- /dev/null
+++ b/GettingStartedWithSWT/swt-widget-hierarchy.html
@@ -0,0 +1,800 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (Win98; I) [Netscape]">
+ <meta name="Author" content="IBM">
+ <title>SWT Widget hierarchy</title>
+</head>
+<body>
+
+<h1>
+SWT Widget hierarchy</h1>
+Here is the hierarchy of widgets in SWT.
+<br>&nbsp;
+<table BORDER CELLSPACING=0 CELLPADDING=5 WIDTH="436" >
+<tr>
+<td VALIGN=CENTER>Dialog</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>ColorDialog</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>DirectoryDialog</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>FileDialog</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>FontDialog</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>MessageBox</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>Display</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>Widget</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Caret</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Control</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Button</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Label</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>ProgressBar</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Sash</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Scale</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Scrollable</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Composite</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Canvas</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Decorations</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Shell</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Combo</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>CoolBar</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Group</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>OleClientSite</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>OleControlSite</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>OleFrame</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>TabFolder</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Table</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>ToolBar</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>List</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>TextEditor</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>RichText</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Text</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Tree</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Slider</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>DragSource</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>DropTarget</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Item</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>CoolItem</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>MenuItem</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>TabItem</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>TableColumn</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>TableItem</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>ToolItem</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>TreeItem</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Menu</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>ScrollBar</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+
+<tr>
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>Tracker</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+
+<td VALIGN=CENTER>&nbsp;</td>
+</tr>
+</table>
+
+<p><i><font size=-1>(c) Copyright IBM Corp. 2000&nbsp; All Rights Reserved.</font></i>
+<br>&nbsp;
+</body>
+</html>
diff --git a/Online Help/Idea.jpg b/Online Help/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/Online Help/Idea.jpg
Binary files differ
diff --git a/Online Help/final.jpg b/Online Help/final.jpg
new file mode 100644
index 0000000..1311ef4
--- /dev/null
+++ b/Online Help/final.jpg
Binary files differ
diff --git a/Online Help/final.zip b/Online Help/final.zip
new file mode 100644
index 0000000..8cb60b5
--- /dev/null
+++ b/Online Help/final.zip
Binary files differ
diff --git a/Online Help/help1.htm b/Online Help/help1.htm
new file mode 100644
index 0000000..546c572
--- /dev/null
+++ b/Online Help/help1.htm
@@ -0,0 +1,470 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.73 [en] (Win98; U) [Netscape]">
+ <meta name="Author" content="Greg Adams">
+ <title>Help Part 1</title>
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+<body>
+
+<div align=right><font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2001 Object Technology International, Inc.</font></font></div>
+<div ALIGN=right><table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table></div>
+
+<h1> <img SRC="Idea.jpg" height=86 width=120></h1>
+
+<center>
+<h1>
+Help – Part 1<br>
+Contributing a little help</h1></center>
+<b>Summary</b>
+<br>The Eclipse platform’s help system defines two extension points (<tt>"contributions"
+</tt>and<tt>"contexts"</tt>)
+that allow individual plug-ins to contribute online help and context-sensitive
+help for their components. In this article we will investigate the “contributions”
+extension point and how you can use it to contribute documentation for
+your plug-in.
+<p><b>By Greg Adams, OTI and Dorian Birsan, IBM</b>
+<br><font size=-1>Updated May 28, 2001</font>
+<center>
+<hr size=2 width="100%" align=center></center>
+
+<h2>
+Introduction</h2>
+The Eclipse platform’s help system allows you to contribute your plug-in’s online
+help using the org.eclipse.help.contributions extension point. You can either
+contribute the online help as part of your code plug-in or provide it separately
+in its own documentation plug-in. This separation is beneficial in those situations
+where the code and documentation teams are different groups or where you want
+to reduce the coupling/dependency between the documentation and code. The platform’s
+help facilities provide you with the raw building blocks to structure and contribute
+your help. It does not dictate structure or granularity of documentation. The
+platform does however provide and control the integrated help viewers thus ensuring
+seamless integration of your documentation.
+<p>The org.eclipse.help.contributions extension point provides four elements
+through which you can contribute your help, they are:
+<ul>
+<li>
+topics</li>
+
+<li>
+infoset (also known as a book)</li>
+
+<li>
+infoview</li>
+
+<li>
+actions (also known as wiring)</li>
+</ul>
+The topics, infoset and actions contributions all specify an associated
+xml file that contains the details of the contribution. In the remainder
+of this article we will create a documentation plug-in that uses all four
+of these elements. By the time we’re done, you’ll have your first online
+help plug-in.
+<h2>
+Making the plug-in and content</h2>
+A content author supplies one or more HTML files containing the actual
+documentation. There are no restrictions imposed by the platform on the
+granularity of the HTML files. That is, the documentation authors can opt
+to use one massive HTML file, or numerous smaller granularity HTML files.
+We will start by assuming that you already have some html files that you
+want to integrate into the Eclipse platform. Let’s assume your content
+is arranged into the following directory tree.
+<blockquote><tt>doc/</tt>
+<br><tt>&nbsp;&nbsp; concepts/</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; concept1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; concept1_1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; concept1_2.html</tt>
+<br><tt>&nbsp;&nbsp; tasks/</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task2.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task3_1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task3_2.html</tt>
+<br><tt>&nbsp;&nbsp; ref/</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref1.html</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref2.html</tt></blockquote>
+Create a plug-in directory called org.eclipse.helparticle and place the above
+<i>doc\ </i>sub-tree into it<i>. </i>Now create an initial plugin.xml file with
+the following content:
+<blockquote><tt>&lt;?xml version="1.0"?></tt>
+<br><tt>&lt;plugin</tt>
+<br><tt>&nbsp;&nbsp; name = "Online Help Sample"</tt>
+<br><tt>&nbsp;&nbsp; id = "org.eclipse.helparticle"</tt>
+<br><tt>&nbsp;&nbsp; version = "0.9"</tt>
+<br><tt>&nbsp;&nbsp; provider-name = "Object Technology International,
+Inc."></tt>
+<br><tt>&lt;/plugin></tt></blockquote>
+To help you get started here is a zip file containing the above <a href="initialstructure.zip">initial
+plug-in structure</a>. This plug-in manifest file doesn't actually integrate anything
+yet but soon we will add our contributions to it. <br>
+&nbsp;
+<br>&nbsp;
+<h2>
+Topics &amp; HTML Content</h2>
+Now that we have our sample content files we are ready to create our <b>topics
+</b>file.
+A topics file defines the key entry points into the HTML content files
+by mapping a topic id and label to a reference in one of the HTML files.
+A topics file acts like a table of contents for a set of html content.
+Teams migrating onto the Eclipse platform can quickly reuse existing documentation
+by defining entry points into their existing documentation via the topics
+file. A plug-in can have one or more topics files. Topics files are sometimes
+referred to as navigation files since they describe how to navigate the
+html content. We have three main content areas, concepts, tasks and reference.
+Our obvious choices are one big topics file, or a topics file for each
+main content area. Keep in mind this decision is ours to make, and is not
+a decision the platform dictates to us. If we were “really” writing our
+documentation we would have a larger number of files so, with that in mind
+we will try and keep things manageable by creating a topics file for each
+of the three content areas as follows:
+
+<p class="MsoNormal"><b>topics_Tasks.xml</b>
+<blockquote><tt>&lt;topics id="tasksAll"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="plainTasks" label="Plain Stuff"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task1"
+href="doc/tasks/task1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task2"
+href="doc/tasks/task2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt>&nbsp;<tt>&nbsp;&nbsp;&nbsp;
+&lt;topic id="funTasks" label="Fun Stuff" ></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_1"
+href="doc/tasks/task3_1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_2"
+href="doc/tasks/task3_2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt>
+<br><tt>&lt;/topics></tt></blockquote>
+<b>topics_Concepts.xml</b>
+<blockquote><tt>&lt;topics id="conceptsAll"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Concept1" href="doc/concepts/concept1.html"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Concept1_1"
+href="doc/concepts/concept1_1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Concept1_2"
+href="doc/concepts/concept1_2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt> <tt>&lt;/topics></tt></blockquote>
+<b>topics_Ref.xml</b>
+<blockquote><tt>&lt;topics id="refAll"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Ref1" href="doc/ref/ref1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic label="Ref2" href="doc/ref/ref2.html"/></tt>
+<br><tt>&lt;/topics></tt></blockquote>
+Topics are contributed as part of the <i>topics</i> container element. A <i>topic</i>
+can be a simple link to content (e.g. Task1) or a hierarchical grouping of sub-topics
+(e.g. Fun Stuff), or both (e.g. Concept1). When we start wiring these topics into
+the overall documentation web we will refer to them by their id. When used as
+a link, the argument to href is assumed to be relative to the current plug-in.
+Only topics with an id can be manipulated. We can also refer to the id associated
+with the topics element if we want to refer to all of its enclosed topic entries.
+Later we will modify the plugin.xml to add the actual contributions pointing to
+these files.
+<h2>
+Creating a book</h2>
+Now that we have our raw content and topic files it’s time to create our
+infoset. An information set (infoset) is a documentation web or book. The
+Eclipse platform can display any number of infosets. An infoset contains
+one or more infoviews. An infoview provides a high-level semantic grouping
+within the infoset. Infoviews could be used to create multiple views onto
+the document web. For example we could use them to create an integrated
+view of documentation supplied by many components, or a component based
+view. We could also use them to create separate views for getting started,
+tasks and concepts, or as we will shortly do, create one infoview to show
+them all. The term infoview is used to avoid collision/confusion with the
+term view in the platform’s user interface. Each infoview contains a collection
+of topics. Sometimes a higher-level component or product team is responsible
+for weaving together the documentation and topics supplied by a number
+of its component teams. For our purposes we’ll assume that our plug-in
+should supply both the topics and the book that integrates the topics.
+Towards the end of the article we will look at how to make your documentation
+plug-in live happily in both a component world and a product world.
+<br>&nbsp;
+<p>The following infoset has id “infoset_SampleGuide” and declares one
+infoview whose id is “view_Contents”. The id of the infoview will become
+important as we start wiring in the high level structure for the infoview,
+and ultimately wiring in the topics we defined earlier.
+<p><b>infoset_SampleGuide.xml</b>
+<blockquote><tt>&lt;infoset id="infoset_SampleGuide" label="Online Help
+Sample" href="<b>doc/splash.html</b>"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;<b>infoview</b> label="Content" id="view_Contents"
+/></tt>
+<br><tt>&lt;/infoset></tt></blockquote>
+Selecting the book called "Online Help Sample" shows one possible infoview
+called "Content". The following figure shows the eventual look of our help.
+If multiple infoviews had been declared by our xml file they would show
+up as additional "infoview tabs" alongside the "Content" tab. Notice that
+our splash page (contained in splash.html&nbsp; and declared above) is
+also displayed.&nbsp;
+<blockquote><img SRC="final.jpg" height=437 width=668></blockquote>
+
+<br>&nbsp;
+<h2>
+Wiring in the top level structure</h2>
+Next on our agenda is to define the top-level structure that a user will
+see within our “Contents” infoview. We start by creating the following
+topics file for the top-level topics:
+<p><b>topics_view_Contents.xml</b>
+<blockquote><tt>&lt;topics id="topics_view_Contents"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="conceptsRoot" label="Concepts"
+/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="tasksRoot" label="Tasks" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="funRoot" label="Fun Things" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="refRoot" label="Reference" /></tt>
+<br><tt>&lt;/topics></tt></blockquote>
+Now comes the fun part, time to “wire in” these topics into our “Contents”
+infoview. Once we’ve done that we can then proceed to wire in all of our
+other topics underneath the above top-level topics. We start by wiring
+in the top-level topics using the following <b>actions
+</b>file.
+<p><b>actions_view_Contents.xml</b>
+<blockquote><tt>&lt;actions infoview="org.eclipse.helparticle.view_Contents"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.topics_view_Contents"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.view_Contents"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt>
+<br><tt>&lt;/actions></tt></blockquote>
+The following snapshot shows what our infoset (Outline Help Sample) will
+look like as a result of wiring in these top-level topics. The title (label)
+of the infoset is only displayed in the combo box if there is more than
+one infoset.
+<blockquote>
+ <div align="left"><img SRC="toplevel.jpg" height=99 width=197></div>
+</blockquote>
+
+<h2>
+Taking a closer look at actions</h2>
+<div align="left">Before we continue let’s take a closer look at the action file
+ and the action elements it contains. The actions file contains scripting actions
+ to be performed on topics and infoviews. Currently there is only one kind of
+ action, the insert action, which is used to wire topics and views together into
+ one integrated information web. The actions are structural actions (insert)
+ and, thus, apply to a certain infoview. So, all the insert actions in an actions
+ file wire their topics into one infoview. If you want to wire into different
+ infoviews, you will need an actions file for each. The insertion points can
+ be topics or infoviews.&nbsp; A topic indicates its willingness to be an insertion
+ point by providing an id. Infoviews are required to have id's.&nbsp; Only fully
+ qualified ids are used as references. For example, the fully qualified topic
+ id of the topic &lt;topic id="conceptsRoot " label="Concepts">&nbsp; in our
+ org.eclipse.helparticle plug-in is org.eclipse.helparticle.conceptsRoot. In
+ the above actions file we took the topics element with fully qualified id "org.eclipse.helparticle.topics_viewContents"&nbsp;
+ and wired it into the infoview with id "org.eclipse.helparticle.view_Contents".
+</div>
+<p>Since the insertion points are sometimes located in other plug-ins,
+and these plug-ins may not be installed, one can specify an alternate insertion
+point. By default, if none of the choices succeed, the topic stays under
+its component hierarchy. The "to" attribute specifies the target insertion
+point. The topic specified by the "from" attribute is the topic being inserted.&nbsp;
+Followings are some possible ways to insert a topic and they are specified
+using the "<b>as</b>" attribute:
+<ul type=disc>
+<li>
+As a child of the insertion point, which is the most common. Attribute:&nbsp;
+as = "child".</li>
+
+<li>
+As the first child of the insertion point. Attribute as = "first-child".</li>
+
+<li>
+As the last child of the insertion point. Attribute as = "last-child".</li>
+
+<li>
+As the previous sibling of the insertion point (i.e., just before the insertion
+point at the same level in the navigation tree). Attribute as = "prev-sib".</li>
+
+<li>
+As the next sibling of the insertion point (i.e., just after the insertion
+point at the same level in the navigation tree). Attribute as = "next-sib".</li>
+</ul>
+Alternative insertion options can be provided. The nested insert sub-elements
+of the insert element provide these alternatives. This can be thought of as a
+"fall-back" mechanism where if an insert action fails, the nested insert action
+will be executed. Once the first choice insertion point has been satisfied, the
+other alternative insertion points are ignored. <br>
+&nbsp;
+<h2>
+Integrating our topics</h2>
+The time has come to finally integrate our topics into the top-level topics of
+the “Contents” infoview. To do this we need another actions file that we will
+call actions_All.xml (since it integrates all of our topics).
+<p><b>actions_All.xml</b>
+<blockquote><tt>&lt;actions infoview="org.eclipse.helparticle.view_Contents"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.conceptsAll"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.conceptsRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.refAll"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.refRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.plainTasks"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.tasksRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.funTasks"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.funRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as="child"/></tt> <tt>&lt;/actions></tt></blockquote>
+Recall that we had a number of task related html files, and the structure/navigation
+of these files was defined by topics_tasks.xml as follows:
+<p><b>topics_Tasks.xml</b>
+<blockquote><tt>&lt;topics id="tasksAll"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="plainTasks" label="Plain Stuff"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task1"
+href="doc/tasks/task1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task2"
+href="doc/tasks/task2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="funTasks" label="Fun Stuff" ></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_1"
+href="doc/tasks/task3_1.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;topic label="Task3_2"
+href="doc/tasks/task3_2.html"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;/topic></tt>
+<br><tt>&lt;/topics></tt></blockquote>
+In the above actions file we use the insert as child action to take the topic
+with id org.eclipse.helparticle.plainTasks and insert it and its sub-topics under
+the topic with id org.eclipse.helparticle.tasksRoot
+<blockquote><tt>&lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.plainTasks"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.tasksRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; as="child"/></tt></blockquote>
+The actions file also takes some of our more entertaining tasks and inserts
+them into the “Fun Things” area of the web using the following action.
+<blockquote><tt>&lt;insert</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; from="org.eclipse.helparticle.funTasks"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; to="org.eclipse.helparticle.funRoot"</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; as="child"/></tt></blockquote>
+
+<h2>
+Finishing our plugin</h2>
+Before we continue a brief recap is in order:
+<ul>
+<li>
+We started by creating our plug-in and document files.</li>
+
+<li>
+Next we created topic files to describe the structure/navigation of our
+content.</li>
+
+<li>
+We then moved up one level above content, to the wiring and integration
+of our book. To do this we created our infoset with its single Contents
+infoview.</li>
+
+<li>
+Next we created another topics file (topics_view_Contents.xml) to define
+the top-level topics.</li>
+
+<li>
+Finally we wired it all together using the action files actions_view_Contents.xml
+(to wire in the top level topics) and actions_All.xml (to wire in the bulk
+of our topics).</li>
+</ul>
+
+<p><br>The one remaining piece of work is to update our plugin.xml to actually
+contribute the action, topics, and infoset files that we created. Start
+with updating the plugin.xml to contribute our infoset:
+<blockquote><tt>&lt;extension point="org.eclipse.help.contributions"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;infoset name="infoset_SampleGuide.xml"/>&lt;/extension></tt></blockquote>
+Next we contribute the top-level topics, and the actions file that wires
+them into our infoset:
+<blockquote><tt>&lt;extension point="org.eclipse.help.contributions"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topics name="topics_view_Contents.xml"/></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;actions name="actions_view_Contents.xml"
+/></tt>
+<br><tt>&lt;/extension></tt></blockquote>
+Lastly we contribute the bulk of our topics and wire them in:
+<blockquote><tt>&lt;extension point="org.eclipse.help.contributions"></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topics name="topics_Concepts.xml" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topics name="topics_Tasks.xml" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topics name="topics_Ref.xml" /></tt>
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;actions name="actions_All.xml" /></tt>
+<br><tt>&lt;/extension></tt></blockquote>
+That’s it, you’re done. Now take your plugin (click here for a <a href="final.zip">zip
+file</a> of the final plugin) and drop it into the platform’s <i>plugins</i> directory,
+start eclipse and choose Help -> Help Contents. Once you expand the topics in
+the “Contents” infoview you will see the following. <br>
+&nbsp;
+<p><img SRC="final.jpg" height=437 width=668> <br>
+ &nbsp;
+<br>&nbsp;
+<h2>
+Non-integrated components</h2>
+What if we expect our plug-in will sometimes be installed by itself, and in other
+cases it will be installed as part of a larger component or product. When deploying
+a free floating plug-in we want to ensure that our infoset is visible. When topics
+from a plug-in are integrated into a larger web it probably doesn’t make sense
+for their standalone book to show up anymore. To support this nonintegrated or
+loosely integrated documentation, a plug-in can define an infoset and associated
+actions and set their <b>standalone</b> attribute to true. This has the effect
+of executing the inserts only when those topics have never been contributed anywhere
+else and only display the infoset if it is not empty. In other words, this behaves
+as: "if this is an independent plug-in, and there are no topics contributed to
+some well-known infoset, then insert the documentation into a standalone info
+set". Empty standalone infosets are not shown. This really says that if the topics
+contributed by the plug-in are inserted into well-known infosets, then the standalone
+actions did not insert anything in the standalone infoset, so just ignore this
+empty infoset. Setting standalone attributes on actions and infosets is useful
+when providing a "Catch all" scenario, when documentation cannot be contributed
+to a well-known infoset but the plug-in documentation should still appear somewhere.
+To support standalone mode we need to make the following additions to our infoset
+and action xml files. The addition is marked in bold.
+<p>infoset_Guide.xml
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;infoset id="infoset_Guide"label="Online
+Help Sample" href="doc/splash.html"
+<b>standalone="true"</b>></tt>
+<p>actions_All.xml
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;actions infoview="org.eclipse.platform.doc.user.view_Contents"
+<b>standalone="true"</b>></tt>
+<p>actions_view_Contents.xml
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;actions infoview="org.eclipse.platform.doc.user.view_Contents"
+<b>standalone="true"</b>></tt>
+<p>Now if someone includes our topics our actions will not be used, and
+consequently our infoset will be empty and not show up.
+<br>&nbsp;
+<h2> Externalizing Strings in your XML files</h2>
+Plugin.xml files externalize their strings by replacing the string with
+a key (e.g. %pluginName) and creating an entry in the plugin.properties
+file of the form:
+<br><tt>&nbsp;&nbsp;&nbsp; pluginName = “Online Help Sample Plugin”</tt>
+<br>The contribution XML files are externalized using a similar approach.
+To externalize &lt;topic id="plainTasks" label="Plain Stuff"> we replace
+its label with a key %plainStuff . Our topic now looks like:
+<br><tt>&nbsp;&nbsp;&nbsp; &lt;topic id="plainTasks" label="%plainStuff"></tt>
+<br>Create an entry in the document.properties file containing the entry:
+<br><tt>&nbsp;&nbsp;&nbsp; plainStuff = Plain Stuff</tt>
+<br>The help system will use document.properties when looking up strings
+externalized by our online help contributions.
+<br>&nbsp;
+<h2>
+Server and zip files</h2>
+The platform utilizes its own documentation server to provide the actual web pages
+from within the document web.&nbsp; A custom server allows the platform to handle
+the wide variety of web browsers in a browser independent way while also providing
+plugin aware support. The platform's help server allows the documentation to also
+be deliver in a zip file thus avoiding problems that may result when a large number
+of files are present. In our example plugin we created a sub-directory called
+"doc". Alternatively we could have placed our html files into a zip file called
+"doc.zip". <br>
+&nbsp;
+<h2>
+Conclusions</h2>
+We have seen how we can use the infoset, infoview to declare books the
+user can see. We then used the actions contribution and the topics contribution
+to declare and integrate our topics. The platform’s mechanisms can be used
+to integrate new documentation, or to quickly wire in existing html based
+documentation without rewriting it. The mechanisms allow you to create
+multiple different views onto your documentation web. In our plug-in we
+only created a single infoview but additional infoviews could easily be
+created. Component documentation can either be written to be a standalone
+book, or optionally marked such that if it is integrated into a larger
+document web, the individual component book will automatically be hidden.
+Lastly, we observed that the platform provides the building blocks for
+doc integration but does not set out any style or structuring guidelines.
+<br>&nbsp;
+<br>&nbsp;
+</body>
+</html>
diff --git a/Online Help/initialstructure.zip b/Online Help/initialstructure.zip
new file mode 100644
index 0000000..8cb60b5
--- /dev/null
+++ b/Online Help/initialstructure.zip
Binary files differ
diff --git a/Online Help/readme.txt b/Online Help/readme.txt
new file mode 100644
index 0000000..9230c80
--- /dev/null
+++ b/Online Help/readme.txt
@@ -0,0 +1,12 @@
+Aug. 9/2002
+
+The help articles has been revised for Eclipse 2.0.
+The new version of the article is in the folder named "Article-Online Help for 2_0".
+The old version of the article is in the folder named "Article-Online Help for 1_0".
+
+This folder has been left in place for the benefit of anyone that has linked to
+"articles/Online%20Help/help1.html".
+
+This folder should be deleted 1Q2003.
+
+---jeem \ No newline at end of file
diff --git a/Online Help/toplevel.jpg b/Online Help/toplevel.jpg
new file mode 100644
index 0000000..aea95df
--- /dev/null
+++ b/Online Help/toplevel.jpg
Binary files differ
diff --git a/PropertyContribution.html b/PropertyContribution.html
new file mode 100644
index 0000000..db6c998
--- /dev/null
+++ b/PropertyContribution.html
@@ -0,0 +1,52 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Dejan Glozic">
+ <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+ <title>A Tale of Three Notifier</title>
+</head>
+<body>
+&nbsp;
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table>
+
+<h1>
+<img SRC="../images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+Contributing to the&nbsp;</h1>
+<h1>
+Properties View</h1></center>
+
+<center>
+<h3>
+How Views and editors can use the properties view to show and edit properties of
+the current selection</h3></center>
+
+<blockquote><b>Summary</b>
+<br>Most editors and views have
+ the concept of a current selection. It is often useful to display information,
+ or properties, about this selection. Rather than have each editor or view
+ provide its own custom way of displaying properties, the Workbench provides a
+ properties view that can listen for the selection of the currently active
+ part, and then display and possibly edit its properties. In this article we'll
+ take a look at how a tool contributes to the properties view, and various ways
+ of adapting its model to provide the required interfaces.</blockquote>
+<b>By <a href="mailto:jamsden@us.ibm.com">Jim Amsden</a></b>
+<p>
+<hr WIDTH="100%">
+<br>
+<h3>
+Conclusion</h3>
+This article explained the importance of change notification in the Eclipse
+platform and the challenges of doing it with so many different aspects
+of the platform. It ain't pretty, but it works. If you have a better idea,
+we would definitely like to hear it.
+</body>
+</html>
diff --git a/SolvingTheSoftwareParadox.html b/SolvingTheSoftwareParadox.html
new file mode 100644
index 0000000..58c4ddd
--- /dev/null
+++ b/SolvingTheSoftwareParadox.html
@@ -0,0 +1,296 @@
+<html>
+<head>
+<title>Solving the Software Paradox with Tool Integration</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<body bgcolor="#FFFFFF" text="#000000">
+&nbsp;
+<table border=0 cellspacing=0 cellpadding=2 width="100%" >
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+</table>
+<h1> <img src="../images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+<center>
+ <h1> Solving the Software Paradox<br>
+ With Tool Integration</h1>
+</center>
+<center>
+ <h3> How a Workspace with integrated tools can facilitate<br>
+ application development of all resource types and for <br>
+ the whole team</h3>
+</center>
+<blockquote><b>Summary</b> <br>
+ Developing Web applications is difficult due to conflicting demands for high
+ quality applications built in Web time, and to immature, unintegrated, and constantly
+ changing technologies. Web application design patterns help manage this complexity
+ and indicate the required tools. Tools need to be integrated and manage the
+ relationships between their associated artifacts. A tool integration platform
+ provides the required &quot;integration-ware&quot; enabling the development
+ of products consisting of integrated, configurable, roles appropriate, and end-to-end
+ development tools based on best practice design patterns. To reduce acceptance
+ barriers, this integration-ware must be based on open standards as much as possible
+ and Open Source where standards don't exist. To be effective, tools need to
+ be integrated into a common workbench. The workbench and integration-ware must
+ support flexible tool integration appropriate to vendor business objectives
+ by providing various conformance levels of integration. Conformance levels define
+ what any vendor must do to integrate at a level, what technologies are required,
+ and any integration expectations.<br>
+</blockquote>
+<b>By: <a href="mailto:Jim_Amsden@oti.com">Jim Amsden</a></b>
+<p>
+<hr width="100%">
+<h3>The Web is changing everything</h3>
+<p>Customers are discovering the opportunities and challenges of e-business applications.
+ Current integrated suites of office tools like Microsoft Office and Lotus SmartSuite
+ set high expectations for integrated application development tools. The Internet
+ is changing the face of business integration resulting in rapidly changing business
+ models due to BPR in order to leverage the Web. These e-business applications
+ can be complex, difficult to maintain, and demand interoperability. Interoperable
+ applications consisting of highly integrated artifacts demand integrated tools
+ supporting a prescriptive methodology in order for application development to
+ be a rational, controllable, and repeatable process.</p>
+<h3> Web Application development results in the need for layered tools<br>
+</h3>
+<p>The explosion of Web technologies including client display architectures, communication
+ protocols, application servers, and backend systems has resulted in rapidly
+ changing and complex application architectures. The Web represents a complex,
+ highly dynamic, rapidly changing application development problem space. A Web
+ application incorporates many resource types representing diverse, highly interrelated
+ components including: HTML, GIF, JPEG, DHTML, scripting, Java Applets, ActiveX
+ controls, servlets, EJBs, connectors to legacy systems, etc. In most cases,
+ these resources are never collectively compiled in order to validate the intended
+ relationships. This can result in applications that are fragile, difficult to
+ test, scale, and maintain. </p>
+<p>Because of these diverse content types, and their contents, building a Web
+ application requires diverse, highly specialized development skills including:
+ GUI programmers, server programmers, graphic designers, database designers,
+ business experts, and document designers. Client web browsers and HTTP web servers
+ establish the overall architecture of Web applications. The resulting distributed
+ applications require compromises between accessibility, availability, integrity,
+ ease of use, performance, and footprint. Web applications are targeted at a
+ broad audience, which requires emphasis on ease of use, appealing look and feel,
+ and masking resource and distribution technologies. Web application development
+ is pushed from two conflicting directions: the need so support high quality
+ applications, and the need to develop them very fast on emerging and un-integrated
+ technologies.</p>
+<p>The techniques for developing Web applications are changing fast. This often
+ results in new and immature technologies and many tools: new tools, new revisions
+ of old tools, and beta releases of emerging tools. As a result, there is a significant
+ opportunity for point tools supporting these new emerging technologies that
+ facilitate the development of Web applications. However, these tools must be
+ effectively integrated in order to speed Web application development, provide
+ end-to-end debugging, minimize gaps and overlaps between tools, and provide
+ a positive developer experience.<br>
+</p>
+<h3>Patterns help manage the complexity<br>
+</h3>
+<p>Fortunately, web application development choices tend to fit into patterns
+ based on application functionality and network, middleware, and runtime topologies.
+ Patterns help focus on customer needs, the technologies, tools, and techniques
+ that are used to build web applications. Each pattern is instantiated through
+ the creation or reuse of a number of web resources. Each resource requires a
+ tool to author the resource and a repository for storage. Resources are integrated
+ and linked together to support relationships existing in the target business
+ application. Tools must be integrated in order to facilitate development of
+ an application built from integrated artifacts. Otherwise the developer must
+ maintain these relationships manually. This is both tedious and error prone.
+</p>
+<p>Effective tool integration requires open standards, a component and programming
+ model, frameworks, APIs, file formats, etc., collectively called &quot;integration-ware&quot;.
+ Integration-ware provides the base platform in which extensions can be applied
+ to provide domain specific tooling. All these components must be integrated
+ with a central workbench that provides access and control of the entire site
+ across all resource types and application development roles. The benefits are
+ reduced gaps and overlaps between tools, elimination of repetitive, manual,
+ tedious, and expensive on-site tool integration, less redundant data input,
+ and a more positive user experience. <br>
+</p>
+<h3>Realizing the Tools Opportunity<br>
+</h3>
+<p>Web and e-business application development, and a tool integration platform
+ result in a significant opportunity for ISVs to develop application development
+ tools. In order to be successful, tool vendors need to focus on the value added
+ by their tools while minimizing their investment in infrastructure, porting
+ to other operating systems, browsers, and/or web servers. ISVs also need to
+ minimize the amount of ancillary functionality they must be develop in order
+ for their tools to be accessible and useful. Minimizing this investment involves
+ integrating tools with other complementary tools and IDEs in such a way that
+ the integrated result provides more value to the end user than the individual
+ tools by themselves. However, integrating tools can require a significant investment.
+ Each tool or IDE that is a candidate for integration provides its own set of
+ extensibility and integration mechanisms. In order to achieve maximum market
+ penetration, a tool vendor will want to integrate with as many other tools and
+ IDEs as possible, and in such a way that the tools compliment each other without
+ creating undue redundancies and coupling.</p>
+<h3>Eclipse provides the required tool integration framework<br>
+</h3>
+<p>A tool integration platform is required to exploit this tooling opportunity
+ by providing a platform for deploying integrated, configurable, roles appropriate
+ tools for developing end-to-end, Web-based, e-business applications. As well
+ as enabling tool integration, a platform helps minimize the cost of tool integration
+ by providing a large number of reusable libraries, APIs, and frameworks that
+ enable provide common services. This minimizes the tool vendors development
+ costs and allows them to focus on their value add. <br>
+ Wherever possible, the platform must use open standards like WebDAV, XMI, JavaBeans,
+ etc. to remove barriers to acceptance, limit tool vendor investment, and reduce
+ time to market. In those cases where there either is no standard, or there are
+ multiple conflicting standards, Open Source can be exploited to establish momentum
+ within the development and tool communities to define defacto standards. <br>
+</p>
+<h3>A Workbench Provides Flexibility and Centralized Project Control<br>
+</h3>
+<p>The tools required to build an application must vary in order to match the
+ customer's preferred application patterns. There are three ways developers can
+ use tools to develop applications:<br>
+</p>
+<ol>
+ <li>Simple applications can be built using independent, specialized tools with
+ all component relationships and publication managed by the developer. <br>
+ </li>
+ <li>An IDE can be used to provide all the integrated tools required to build
+ the entire application. <br>
+ </li>
+ <li>Use a workbench to integrate tools matching customer needs.<br>
+ </li>
+</ol>
+<p>The first approach has the advantage that it provides hands on development
+ where the developer knows everything. Developers can choose any tool they want
+ to build any resources they want. However, this approach doesn't scale to larger,
+ more complex, highly linked projects requiring multiple versions, and a larger
+ development team. It becomes increasingly difficult for a single individual
+ to comprehend the complete project. Taking this approach can often result in
+ applications that are hard to understand, extend, validate, and maintain.<br>
+</p>
+<p>The second approach is appealing because all the tools required for building
+ and maintaining applications are incorporated into a single product. The developer
+ gets everything needed in a single product from a single vendor. This presumably
+ results in well-integrated tools. However, these IDEs are extremely difficult
+ to build because there are so many component types, and technologies are changing
+ too fast. IDEs can be sufficiently complex that they cannot keep up with changes
+ in application domains, deployment architectures, technologies, or development
+ processes. It is difficult for an IDE to match the features of a best-of-breed
+ point tool resulting in mediocre tools and poor user experience. Users do not
+ have the flexibility to choose and integrate the tools in a manner that best
+ matches their preferred development style and e-business application pattern.<br>
+</p>
+<p>The workbench approach solves these problems by providing a central integration
+ point for project control and an integration mechanism to include resource-specific
+ tools. This approach allows a user to build applications using any components
+ they want with any tools while at the same time providing a common view of the
+ complete application across all components and the entire team. This allows
+ flexibility and choice necessary to select and integrate tools that meet different
+ e-business patterns and developer roles but still keeps the application under
+ control. The workbench can provide services common to, or across tools including
+ reporting capabilities, managing relationships or dependencies between components,
+ component management, and publishing services. Using a workbench simplifies
+ tool integration by allowing tools to integrate with the central workbench instead
+ of each other. This may significantly reduce the number of integrations that
+ must be developed, and provides a more consistent environment for the end user.
+ The workbench can be configured with the tools that best map to the e-business
+ development patterns.<br>
+</p>
+<p>The combination of a workbench and integration-ware for developing integrated
+ tools is a win-win situation for platform vendors, ISVs, and application developers.
+ Platform vendor(s) provide integration-ware and services enabling the efficient
+ development of integrated tools. ISVs contribute to the portfolio of integrated
+ tools while minimizing their costs through reuse of the platform and complimentary
+ components produced by other ISVs. Business application developers have best-of-breed
+ tools integrated together supporting their development process.<br>
+</p>
+<h3>Integration Conformance Levels<br>
+</h3>
+<p>In order to provide flexible tool integration, a tool integration platform
+ must define a number of conformance levels that tool vendors can target based
+ on the desired level of investment, time to market, and specific tool needs.
+ Each level specifies what tool vendors must do to achieve that level of integration,
+ and the required technologies that must be employed. By defining these integration
+ conformance levels, tool vendors have choices while at the same time specific
+ rules for advertising conformance to a particular level. This makes it easier
+ for tool vendors to determine what they must do to integrate their tools with
+ the platform, what technologies have to be supported, and establishes a consistent,
+ deterministic end-user experience. The integration conformance levels are:<br>
+</p>
+<p>None: No integration, tools are separate and independent. This is fine for
+ situations where tools operate on independent resources that are not linked
+ or otherwise integrated. It is typical of tool integration today, and often,
+ no further integration is needed.</p>
+<p>Invocation: Integration is through invocation of registered applications on
+ resource types. Most operating systems and IDE provide this level of integration.
+ A user or installation program can register an application on a particular resource
+ type, and when that resource is selected, the application is invoked on the
+ selected resource in a separate window. There is no further integration. Invocation
+ integration is better than none because it allows the user to browse a collection
+ of artifacts in a file browser, Web browser, or other tool and invoke the correct
+ application to author the resource.</p>
+<p>Data: Integration is achieved through data sharing between tools. This is the
+ type of integration that was attempted in the past with technologies like IRDS,
+ PCTE+, and the IBM ADCycle program. In this level of integration, tools share
+ each other's data. This provides much better integration than simple tool invocation
+ because now the tools know about each other's resources and can manage relationships
+ between them. Data integration consists of there basic concepts: access, interchange,
+ and transformation. Access is the protocol or API used by the tool to physically
+ access the data. Interchange is the form the data takes once it is accessed,
+ i.e., its schema. Transformation is concerned with modifying the data to meet
+ the needs of the target tool when the interchange format or schema isn't in
+ the form the tool requires. Transformation can also be used to integrate date
+ from many tools into a new single data model meeting the needs of some new tool.
+</p>
+<p>Data integration between tools creates a combinatoric explosion of access,
+ interchange, and transformation protocols. In the past, we tried to solve this
+ problem by specifying a repository and schema for all tools to integrate with.
+ This turned out to be impossible because tool vendors couldn't let a single
+ vendor (often a competitor) control such strategic aspects of their infrastructure,
+ and no one repository or extensible schema was sufficient to meet all vendor
+ needs. A better solution is exploit open standards that isolate tools from each
+ other and their underlying repositories and schemas. Fortunately there are a
+ number of standards that exactly meet our needs. WebDAV (Web Distributed Authoring
+ and Versioning)</p>
+<p> using WebDAV for data access, XML/XMI/MOF for data interchange, and XSLT for
+ data transformation and integration.<br>
+ API: Tools interact with other tools through JavaBeans that abstract tool behavior
+ and make it publicly available.<br>
+ UI: Tools and their user interfaces are dynamically integrated at runtime with
+ a common desktop.<br>
+ The Workbench Tool Integration Platform is Different<br>
+ Then we need to establish a set of patterns that describe typical architectures
+ used by ISV tools. These might include:</p>
+<p>Java/Swing application using files in the file system for persistence<br>
+ OLE Document editor<br>
+ Java/Swing application using a non-file based repository (object repository
+ or relational, doesn't really matter which)<br>
+ C++ client/server application with proprietary client/server communication protocol
+ and proprietary repository<br>
+ etc.</p>
+<p>Then we look at each one of these patterns and explore how they can transition
+ to Workbench technologies through the levels of integration. What we'll see
+ is that there are patterns here too. Things like:<br>
+ Launching the application client on a resource type<br>
+ File based tools can use the workbench resource management model versioning,
+ access control, synchronization, disconnected work, etc.<br>
+ OLE Document editors can easily integrate their UIs, but need to do additonal
+ adaptor work to integrated with the outline, properties, and task views.<br>
+ Java/Swing applications can run in the same JVM so they can access other plug-in
+ API (other tools' busines models). <br>
+ Java/Swing applications can be easily converted to Desktop editors by modifying
+ their menu contribution to use either Swing menus or desktop contribution depending
+ on who launches them. They can also put their top-level component in an SWT
+ container so they can easily integrate with the rest of the workbench, similar
+ to ActiveX controls.<br>
+ Tools with proprietary repositories can start by exporting data out of their
+ repositories as XMI document through queries that represent typical units of
+ work. These XMI documents can be consumed by new tools integrated with the workbench
+ while existing C++ based clients work on the same repository.<br>
+ The next step for these tools would be to provide an interfact to their tools
+ model in a Java plug-in. The Java model could use the XMI documents, the repository
+ directly, or both for persistence. Using the new editor extension-points, this
+ Java model could be used to develop new editors on the tool's model while maintaining
+ the same repository.<br>
+ The repository could implement a WebDAV interface to provide a standard protocol
+ for accessing the XMI documents.<br>
+ and so on.</p>
+<p></p>
+</body>
+</html>
diff --git a/StyledText 1/Idea.jpg b/StyledText 1/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/StyledText 1/Idea.jpg
Binary files differ
diff --git a/StyledText 1/Image0.gif b/StyledText 1/Image0.gif
new file mode 100644
index 0000000..eaf7231
--- /dev/null
+++ b/StyledText 1/Image0.gif
Binary files differ
diff --git a/StyledText 1/Image1.gif b/StyledText 1/Image1.gif
new file mode 100644
index 0000000..a36a3da
--- /dev/null
+++ b/StyledText 1/Image1.gif
Binary files differ
diff --git a/StyledText 1/Image2.gif b/StyledText 1/Image2.gif
new file mode 100644
index 0000000..1c3b441
--- /dev/null
+++ b/StyledText 1/Image2.gif
Binary files differ
diff --git a/StyledText 1/Image3.gif b/StyledText 1/Image3.gif
new file mode 100644
index 0000000..b121aa2
--- /dev/null
+++ b/StyledText 1/Image3.gif
Binary files differ
diff --git a/StyledText 1/Image4.gif b/StyledText 1/Image4.gif
new file mode 100644
index 0000000..61eae82
--- /dev/null
+++ b/StyledText 1/Image4.gif
Binary files differ
diff --git a/StyledText 1/Image5.gif b/StyledText 1/Image5.gif
new file mode 100644
index 0000000..57ee861
--- /dev/null
+++ b/StyledText 1/Image5.gif
Binary files differ
diff --git a/StyledText 1/Image6.gif b/StyledText 1/Image6.gif
new file mode 100644
index 0000000..8634819
--- /dev/null
+++ b/StyledText 1/Image6.gif
Binary files differ
diff --git a/StyledText 1/TextChanges.gif b/StyledText 1/TextChanges.gif
new file mode 100644
index 0000000..77a99b6
--- /dev/null
+++ b/StyledText 1/TextChanges.gif
Binary files differ
diff --git a/StyledText 1/article1.html b/StyledText 1/article1.html
new file mode 100644
index 0000000..1d32b32
--- /dev/null
+++ b/StyledText 1/article1.html
@@ -0,0 +1,957 @@
+<html>
+<head>
+<title>Getting Your Feet Wet with the SWT StyledText Widget</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+<body>
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2001-2004 International Business Machines Corp.</font> </div>
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table>
+
+<h1><img SRC="Idea.jpg" width="120" height="86"></h1>
+
+<h1 ALIGN="CENTER">Getting Your Feet Wet with the SWT<br>
+StyledText Widget </h1>
+<b>
+
+<blockquote>
+ <p>Summary</p>
+</blockquote>
+</b>
+
+<blockquote>
+ <p>The<i> StyledText</i> widget is a customizable widget that can be used to display and
+ edit text with different colors and font styles. This article presents an overview of the
+ concepts, issues, and rules that you should be aware of when using the <i>StyledText</i>
+ widget.</p>
+<p><b>By Lynne Kues and Knut Radloff, OTI</b>
+<br>
+ May 7, 2001; updated July 19, 2004 for Eclipse 3.0</p>
+</blockquote>
+
+<hr width="100%">
+
+<h2>Overview</h2>
+
+<p>The<i> StyledText</i> widget provides a fast and easy to use means to display and edit
+text. Within the StyledText widget, the following attributes can be specified:</p>
+
+<blockquote>
+ <blockquote>
+ <ul>
+ <li>text foreground color </li>
+ <li>text background color </li>
+ <li>text font style (i.e., normal, bold or italic) </li>
+ <li>line background color </li>
+ </ul>
+ </blockquote>
+</blockquote>
+
+<p>These attributes are referred to as &quot;styles&quot;. In addition, the <i>StyledText</i>
+widget provides standard navigation/editing keyboard behavior, allows for user-defined key
+bindings, and will perform word wrapping. Note that support for fonts with italic style was
+added as of version 3.0. However, the <i>StyledText</i> widget does not support mixing of
+multiple fonts.
+
+<p>The <i>StyledText</i> widget can be customized using pluggable objects to manage
+ text content and styles. You can provide your own implementation of these objects
+ in order to tailor the widget to your needs. Or if you have no need to customize
+ the widget, easy to use API for managing styles and text content is available,
+ making the pluggable nature of the widget completely transparent. How to customize
+ the <em>StyledText</em> widget and why you might want to do so will be discussed
+ in our other article, <a href="../StyledText%202/article2.html">Into the Deep
+ End of the StyledText Widget</a>.</p>
+
+<p>The <i>StyledText</i> widget is used by the JFace Text Framework, which is part of the Eclipse Platform.
+The JFace Text Framework provides a layer of abstraction on top of the <i>StyledText</i> widget.
+The layer is pluggable and supports text formatting, content code assist capabilities, and
+a source viewer. </p>
+
+<h3>A Simple Example </h3>
+
+<p>The following is a simple example that shows how to create a <i>StyledText</i> widget
+and set text. This example will be built upon in subsequent sections of this article.</p>
+
+<p align="center"><img border="0" src="Image0.gif" width="200" height="100"></p>
+
+<pre><font COLOR="#000084">import</font><font COLOR="#000000"> org.eclipse.swt.*;</font><font
+COLOR="#000084">
+import</font><font COLOR="#000000"> org.eclipse.swt.custom.*;
+</font><font
+COLOR="#000084">import<font COLOR="#000000"> org.eclipse.swt.graphics.*;
+</font>import</font><font
+COLOR="#000000"> org.eclipse.swt.widgets.*;</font><font COLOR="#000084">
+import</font><font
+COLOR="#000000"> org.eclipse.swt.layout.*;
+</font><font COLOR="#000084">
+public</font><font
+COLOR="#000000"> </font><font COLOR="#000084">class</font><font COLOR="#000000"> StyledTextExample {
+ </font><font
+COLOR="#000084">public</font><font COLOR="#000000"> </font><font COLOR="#000084">static</font><font
+COLOR="#000000"> </font><font COLOR="#000084">void</font><font COLOR="#000000"> main(String [] args) {
+ </font><font
+COLOR="#840000">// create the widget's shell</font><font COLOR="#000000">
+ Shell shell = </font><font
+COLOR="#000084">new</font><font COLOR="#000000"> Shell();
+ shell.setLayout(</font><font
+COLOR="#000084">new</font><font COLOR="#000000"> FillLayout());
+ shell.setSize(200, 100);
+ Display display = shell.getDisplay();
+ </font><font
+COLOR="#840000">// create the styled text widget</font><font COLOR="#000000">
+ StyledText widget = </font><font
+COLOR="#000084">new</font><font COLOR="#000000"> StyledText(shell, SWT.BORDER);
+ widget.setText(</font><font
+COLOR="#008484">&quot;This is the StyledText widget.&quot;</font><font COLOR="#000000">);
+
+ shell.open();
+ </font><font
+COLOR="#000084">while</font><font COLOR="#000000"> (!shell.isDisposed())
+ </font><font
+COLOR="#000084">if</font><font COLOR="#000000"> (!display.readAndDispatch()) display.sleep();
+ }
+}</font></pre>
+
+<h3>Character, Line and Caret Offsets</h3>
+
+<p>Within the <i>StyledText</i> widget, both character offsets and line indexes are zero
+based. For example, in the StyledText widget below, the line at index 0 is
+&quot;abcde&quot; and the character at offset 0 is &quot;a&quot;.</p>
+<div align="center"><center>
+
+<pre>widget.setText(<font color="#008080">&quot;abcde\r\nfghij&quot;</font>);
+</pre>
+</center></div><div align="center"><center>
+
+<pre><img border="0" src="Image2.gif" width="200" height="100"></pre>
+</center></div>
+
+<p>When specifying offsets within the <em>StyledText</em> widget, line delimiter
+characters are included.&nbsp; In the above example, the line delimiter is CR/LF (i.e.,
+&quot;\r\n&quot;).&nbsp; Therefore, the character at offset five is CR and the
+character at offset six is LF.&nbsp; Similarly, <strong>getLineAtOffset(6)</strong>
+returns 0 and <strong>getLineAtOffset(7)</strong> returns 1. If there was another CR/LF
+line break at the end of the second line, <strong>getLineAtOffset(14)</strong> would
+return 2. </p>
+
+<p>Caret offsets are also zero based.&nbsp; Calling <strong>setCaretOffset(4) </strong>for
+the above widget places the caret between 'd' and 'e'.&nbsp; And, like character offsets,
+caret offsets take line delimiters into account.&nbsp; In order to place the caret at the
+beginning of the second line (i.e., in front of the 'f') you would call <strong>setCaretOffset(7)</strong>.
+Also note that <strong>setCaretOffset(12)</strong> is a valid call and places the caret at
+the end of the text, after the 'j'.&nbsp; The range of valid caret offset values is one
+more than the range of valid character offset values.</p>
+
+<h3>Text Ranges</h3>
+
+<p>Generally, the <i>StyledText</i> widget uses the start offset and the length to specify
+a text range. Specifying the length of a text range, instead of the end offset, is less
+error prone because there is no doubt as to whether or not the end offset is included in
+the range. For example, a start offset of &quot;0&quot; and an end offset of &quot;2&quot;
+may or may not include the character at offset 2 (in SWT it doesn&#146;t). Expressing the
+equivalent using a start offset and a length (i.e., 0 and 2 respectively) is unambiguous.
+It is clear that this describes the characters at offsets 0 and 1. </p>
+
+<p>To maintain consistency with other SWT widgets, API methods that use the start offset
+and end offset semantics are also provided. For example, SWT uses &quot;start&quot; and
+&quot;end&quot; when selecting items in a <i>List</i>, <i>Tree</i> or <i>Table</i>. The
+table below shows the API that uses start offset and end offset (non-range based) and the
+equivalent API with start offset and length semantics (range based). </p>
+<div align="center"><center>
+
+<table BORDER="1" CELLSPACING="2" CELLPADDING="7" WIDTH="560">
+ <tr>
+ <td WIDTH="235" VALIGN="TOP" align="center"><b><font size="2" face="Courier New">Start
+ Offset, End Offset</font></b></td>
+ <td WIDTH="285" VALIGN="TOP" align="center"><b><font size="2" face="Courier New">Start
+ Offset, Length</font></b></td>
+ </tr>
+ <tr>
+ <td WIDTH="235" VALIGN="TOP"><font size="2" face="Courier New">getSelection()</font></td>
+ <td WIDTH="285" VALIGN="TOP"><font size="2" face="Courier New">getSelectionRange()</font></td>
+ </tr>
+ <tr>
+ <td WIDTH="235" VALIGN="TOP"><font size="2" face="Courier New">getText(int, int)</font></td>
+ <td WIDTH="285" VALIGN="TOP"><font size="2" face="Courier New">getTextRange(int, int)</font></td>
+ </tr>
+ <tr>
+ <td WIDTH="235" VALIGN="TOP"><font size="2" face="Courier New">n/a</font></td>
+ <td WIDTH="285" VALIGN="TOP"><font size="2" face="Courier New">redrawRange(int, int)</font></td>
+ </tr>
+ <tr>
+ <td WIDTH="235" VALIGN="TOP"><font size="2" face="Courier New">n/a</font></td>
+ <td WIDTH="285" VALIGN="TOP"><font size="2" face="Courier New">replaceTextRange(int, int,
+ String)</font></td>
+ </tr>
+ <tr>
+ <td WIDTH="235" VALIGN="TOP"><font size="2" face="Courier New">setSelection(int, int)</font></td>
+ <td WIDTH="285" VALIGN="TOP"><font size="2" face="Courier New">setSelectionRange(int, int)</font></td>
+ </tr>
+</table>
+</center></div>
+
+<p ALIGN="left"><i>StyledText</i> API that uses a start offset and a length will always
+end with &quot;Range&quot;. For example, <b>getSelectionRange </b>will return the
+selection as a start offset and a length. </p>
+
+<p ALIGN="left">You can mix non-range based and range based <i>StyledText</i> API, as
+demonstrated by the code below.&nbsp; The behavior is the same. However, for the sake of
+clarity you should decide which kind of API to use and then use it consistently. </p>
+
+<pre><font COLOR="#000000"> widget.setText(</font><font COLOR="#008484">&quot;This is the StyledText widget.&quot;</font><font
+COLOR="#000000">);
+
+ widget.getText(</font>5, 7<font COLOR="#000000">); </font><font
+color="#800000">// returns &quot;is&quot;</font><font COLOR="#000000">
+ widget.getTextRange(</font>5, 2<font
+COLOR="#000000">); </font><font color="#800000">// returns &quot;is&quot;
+</font><font
+COLOR="#000000">
+ widget.setSelection(</font>8, 11<font COLOR="#000000">); </font><font
+color="#800000">// selects &quot;the&quot;</font><font COLOR="#000000">
+ Point sel = widget.getSelectionRange(); </font><font
+color="#800000">// returns Point with x=8, y=3</font><font COLOR="#000000">
+ widget.setSelectionRange(</font>8, 3<font
+COLOR="#000000">); </font><font color="#800000">// selects &quot;the&quot;</font><font
+COLOR="#000000">
+ Point sel = widget.getSelection(); </font><font color="#800000">// returns Point with x=8, y=11</font><font
+COLOR="#000000">
+</font><font SIZE="2" COLOR="#000000"> </font></pre>
+
+<h3>Style Specification</h3>
+
+<p>The <i>StyledText</i> widget uses <i>StyleRanges</i> to specify text styles. The fields
+of the <i>StyleRange</i> class are defined as follows:</p>
+
+<pre> <font COLOR="#00007f">public</font> <font COLOR="#00007f">int</font> start; <font
+COLOR="#7f0000">// start offset of the style, zero-based
+</font> <font COLOR="#00007f">public</font> <font
+COLOR="#00007f">int</font> length; <font COLOR="#7f0000">// length of the style
+</font> <font
+COLOR="#00007f">public</font> Color foreground; <font COLOR="#7f0000">// text foreground color
+</font> <font
+COLOR="#00007f">public</font> Color background; <font COLOR="#7f0000">// test background color
+</font> <font
+COLOR="#00007f">public int</font> fontStyle = SWT.NORMAL; <font
+COLOR="#7f0000">// may be SWT.NORMAL, SWT.BOLD or SWT.ITALIC</font></pre>
+
+
+<p>If the <b>foreground</b> and <b>background</b> fields for a <i>StyleRange</i> are null,
+the <i>StyledText</i> widget will use the default widget colors for these fields.</p>
+
+<p>The <i>StyleRange</i> class also includes helper methods for managing and manipulating
+style ranges. For example, the <b>similarTo(StyleRange)</b> method will return whether or
+not two style ranges have the same style attributes and only differ in the start and
+length values.</p>
+
+<p>You define style ranges for the <i>StyledText</i> widget by using the following
+methods:</p>
+
+ <pre>
+ <font COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> setStyleRange(StyleRange range)
+ <font COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> setStyleRanges(StyleRange[] ranges)
+ <font COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> replaceStyleRanges(<font COLOR="#00007f">int</font> start, <font COLOR="#00007f">int</font> length, StyleRange[] ranges)
+ </pre>
+
+<p>The <b>setStyleRange</b> API applies the specified style to the text range specified in the
+<b>StyleRange</b>. If the new style overlaps existing styles, the text outside the new style range
+will keep its existing style information.</p>
+<p>The <b>setStyleRanges</b> API simply replaces all styles in the widget with the new ones.
+</p>
+<p>The <b>replaceStyleRanges</b> API is provided to improve performance.
+ It replaces any styles in the given range with the specified new styles. All
+ existing styles in the range will be deleted, so the new styles need not cover
+ the entire replaced range. Note that <b>replaceStyleRanges</b> could be implemented
+ by calling <b>setStyleRange</b> multiple times to cover the entire replace range. StyleRanges
+ with null colors would delete existing styles that have no replacement. However,
+ the new API makes this task a lot easier and more efficient. </p>
+
+<p>When text changes occur in the <i>StyledText</i> widget, styles that are set using any of the above
+API are updated to reflect the text changes. Styles are always maintained relative to the text to which they
+are assigned and not to a fixed position. If text is inserted in front of a style, the style ranges after the inserted
+text are updated to move with their associated text. If text is inserted at a location that is within a style range, the
+style range is split to accommodate the new text. If new text replaces existing text and some or all of the existing
+text has a style assigned to it, only the non-replaced text will maintain its styles. In short, new text will never
+be automatically styled.
+</p>
+
+<p>The following is a simple example of how to use style ranges in the StyledText widget.</p>
+
+<blockquote>
+ <blockquote>
+ <blockquote>
+ <blockquote>
+ <blockquote>
+ <blockquote>
+ <blockquote>
+ <blockquote>
+ <font size="2"><dl>
+ <div align="center"><center>
+ <dt><img SRC="Image1.gif" width="200" height="100"></dt>
+ </center></div>
+ <dd>&nbsp;</dd>
+ </dl></font>
+ </blockquote>
+ </blockquote>
+ </blockquote>
+ </blockquote>
+ </blockquote>
+ </blockquote>
+ </blockquote>
+</blockquote>
+
+<pre><font COLOR="#000000"> widget.setText(</font><font COLOR="#008484">&quot;This is the StyledText widget.&quot;</font><font
+COLOR="#000000">);
+</font> StyleRange styleRange = <font COLOR="#00007f">new</font> StyleRange();
+ styleRange.start = 0;
+ styleRange.length = text.length();
+ styleRange.fontStyle = SWT.BOLD;
+ styleRange.foreground = display.getSystemColor(SWT.COLOR_BLUE);
+ widget.setStyleRange(styleRange);</pre>
+
+<p>In addition to styles, the <b>setLineBackground (int,int,Color)</b> API can be used to customize the display of the text in the <i>StyledText</i>
+widget. The color specified when using this API will be applied to the display area of the given lines (e.g., line background colors extend the
+width of the StyledText widget). If line background colors and styles with background colors are used in conjunction with each other, the
+style background colors will be displayed after the line background colors are displayed (i.e., the style background color will take precedence for
+its given text range).</p>
+
+<p>When text changes occur in the <i>StyledText</i> widget, line background colors that are specified via the <b>setLineBackground</b>
+API are maintained relative to the text lines to which they are assigned and not to a fixed position. Line background colors are updated in
+a fashion similar to style ranges. New lines of text will never be assigned line background colors and if an existing text line has an associated
+line background color, the association will be maintained.
+</p>
+
+<h3>Resource Life Cycle</h3>
+
+<p>SWT <i>Color</i> objects are used to specify styles for the <i>StyledText</i> widget.
+It is your responsibility to manage the life cycle of these objects. The colors must be
+disposed when they are no longer used by the widget. </p>
+
+<p>The <i>StyledText</i> widget references colors that are set using the <b>replaceStyleRanges</b>,
+<b>setLineBackground</b>, <b>setStyleRange</b> and <b>setStyleRanges</b>
+API methods.&nbsp; Since the widget does not
+copy <em>Color</em> objects, a color set using these API methods can only be considered
+unused when all the character ranges and line ranges that use the color have been reset to
+use the default widget colors. The same is true for the <b>setBackground</b> and <b>setForeground</b> API.
+Colors set using this API are referenced by StyledText and can only be disposed when no longer set in the
+widget or when the widget has been disposed.
+</p>
+
+<p>The following code example illustrates the correct way to manage <em>Color</em>
+objects.&nbsp; Two <em>Colors</em>, lime and orange, are created and used by the widget.. </p>
+
+<p align="center"><img border="0" src="Image3.gif" width="200" height="100"> </p>
+
+<pre><font COLOR="#000000"> widget.setText(</font><font COLOR="#008484">&quot;This is the StyledText widget.&quot;</font><font
+COLOR="#000000">);
+</font><font color="#800000"> // create the Colors</font><font
+COLOR="#000000">
+</font> <font COLOR="#000000">Color orange = </font><font COLOR="#000084">new</font><font
+COLOR="#000000"> Color(display, 255, 127, 0);
+</font> <font COLOR="#000000">Color lime = </font><font
+COLOR="#000084">new</font><font COLOR="#000000"> Color(display, 127, 255, 127);
+
+</font><font
+color="#800000"> // make &quot;This&quot; bold and orange</font><font COLOR="#000000">
+</font> <font
+COLOR="#000000">StyleRange styleRange = </font><font COLOR="#000084">new</font><font
+COLOR="#000000"> StyleRange();
+</font> <font COLOR="#000000">styleRange.start = 0
+ styleRange.length = 4;
+</font> <font
+COLOR="#000000">styleRange.fontStyle = SWT.BOLD;
+</font> <font COLOR="#000000">styleRange.foreground = orange;
+ widget.setStyleRange(styleRange);
+
+</font><font
+color="#800000"> // make &quot;StyledText&quot; bold and lime
+</font><font COLOR="#000000"> styleRange = </font><font
+COLOR="#000084">new</font><font COLOR="#000000"> StyleRange();
+ styleRange.start = 12;
+</font> <font
+COLOR="#000000">styleRange.length = 10;
+ styleRange.fontStyle = SWT.BOLD;
+</font> <font
+COLOR="#000000">styleRange.foreground = lime;
+</font> <font COLOR="#000000">widget.setStyleRange(styleRange);
+
+</font><font
+color="#800000">// styleRange = new StyleRange(12, 10, null, null, SWT.NORMAL);
+// widget.setStyleRange(styleRange); // set the bold, lime colored text back to normal
+// lime.dispose(); // lime is no longer used by the widget so it can be disposed
+</font><font
+COLOR="#000000">
+ shell.open();
+ </font><font COLOR="#000084">while</font><font
+COLOR="#000000"> (!shell.isDisposed())
+ </font><font COLOR="#000084">if</font><font
+COLOR="#000000"> (!display.readAndDispatch()) display.sleep();
+
+ orange.dispose();
+ lime.dispose(); </font><font
+color="#800000">// make sure you comment out this line if you dispose lime above</font><font
+COLOR="#000000">
+</font></pre>
+
+<p><font COLOR="#000000">If you decide that the lime colored text looks ugly, you can use
+the code that is commented out to reset that text to the widget's default foreground
+color. The example would then look like this:</font></p>
+
+<p align="center"><img border="0" src="Image4.gif" width="200" height="100"></p>
+
+<p><font COLOR="#000000">Since you reset the only style range that uses the lime color,
+the lime <i>Color</i> object can be disposed. The orange color can only be disposed when
+the application terminates because it is still used by the first style range that was set.
+Note that we use a different <i>StyleRange</i> constructor for resetting the lime style to
+simplify the style range creation.</font></p>
+
+<p><font COLOR="#000000">The following code resets all style ranges to the widget's
+default colors.</font></p>
+
+<pre> <font COLOR="#000000">widget.setStyleRange(</font><font color="#000080">null</font><font
+COLOR="#000000">);
+ orange.dispose();
+ lime.dispose();</font></pre>
+
+<p><font COLOR="#000000">Once you have called <b>setStyleRange(null)</b> all colors can be
+disposed of safely.</font></p>
+
+<p><font COLOR="#000000">The <b>setLineBackground</b> API works exactly like the <b>setStyleRange</b>
+API. You can only dispose <i>Color</i> objects after you have reset the line backgrounds
+that use the colors or after you dispose the <i>StyledText</i> widget. For example:</font></p>
+
+<p align="center"><img border="0" src="Image5.gif" width="200" height="100"></p>
+
+<pre><font COLOR="#000000"> widget.setText(</font><font COLOR="#008484">&quot;This is the StyledText widget.&quot;</font><font
+COLOR="#000000">);
+</font> <font COLOR="#000000">Color orange = </font><font
+COLOR="#000084">new</font><font COLOR="#000000"> Color(display, 255, 127, 0);
+ widget.</font>setLineBackground<font
+COLOR="#000000">(0, 1, orange);</font></pre>
+
+<p><font COLOR="#000000">You can dispose the orange color only after you have reset the
+line background color of the first line by calling:</font></p>
+
+<pre><font COLOR="#000000"> widget.</font>setLineBackground<font COLOR="#000000">(0, 1, </font><font
+color="#000080">null</font><font COLOR="#000000">);
+ orange.dispose();</font></pre>
+
+<p>It is advisable for you to cache <i>Color</i> objects and dispose them when
+ you dispose the <i>StyledText</i> widget. Caching colors will improve performance
+ and minimize the number of allocated resources. An in-depth discussion of SWT
+ color resources can be found in the <a
+href="../SWT%20Color%20Model/swt-color-model.htm">SWT Color Model</a> article.</p>
+
+<h3><a NAME="TextChange"></a>Text Change Notification</h3>
+
+<p>Text changes within the <i>StyledText</i> widget can occur via user input or
+programmatically. User input changes occur when keyboard input is received. Programmatic
+changes occur when the <i>StyledText</i> API is executed. Four API methods exist for
+performing programmatic changes:</p>
+<pre>
+ <font COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> append(String text)
+ <font COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> insert(String text)
+ <font COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> replaceTextRange(<font
+COLOR="#00007f">int</font> start, <font COLOR="#00007f">int</font> length, String text)
+ <font COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> setText(String text)</pre>
+
+<p>When text changes occur, the <i>StyledText</i> widget generates four kinds of
+notification events:<dfn>
+
+<dl>
+ <dd>verify key event</dd>
+ <dd>verify event</dd>
+ <dd>modify event</dd>
+ <dd>extended modify event </dd>
+</dl>
+</dfn>
+
+<h4><a name="VerifyKeyEvent"></a>Verify Key Event</h4>
+
+<p>The <b>verify key event </b>is sent immediately after a key has been pressed.&nbsp; The
+fields of the <i>VerifyEvent</i> that are used when sending the <strong>verify key event</strong>
+are defined as follows: </p>
+
+<pre><font COLOR="#000084"> public boolean</font> doit; <font color="#800000">// flag indicating whether the keystroke should be processed</font><font
+COLOR="#000084">
+ public</font> <font COLOR="#000084">char</font> character; <font
+color="#800000">// characte</font><font COLOR="#840000">r represented by the key that was typed
+ </font><font
+COLOR="#000084">public</font> <font COLOR="#000084">int</font> keyCode; <font
+color="#800000">// key code</font><font COLOR="#840000"> of the key that was typed. Used for special keys (e.g., CTRL).
+</font> <font
+COLOR="#000084">public</font> <font COLOR="#000084">int</font> stateMask; <font
+color="#800000">// sta</font><font COLOR="#840000">te of the keyboard modifier keys (e.g., SHIFT) </font><font
+color="#800000">at the tim</font><font COLOR="#840000">e the
+</font> <font
+color="#800000">// </font><font COLOR="#840000">event was generated</font></pre>
+
+<p>You can use the <strong>verify key event </strong>to filter out a key stroke before it
+is processed by the <i>StyledText</i> widget. To do so, you would set the <b>doit </b>field
+of the <i>VerifyEvent</i> to false. </p>
+
+<p>To listen to verify key events add a <i>VerifyKeyListener</i> to the <i>StyledText</i>
+widget and implement the <b>verifyKey(VerifyEvent) </b>method in the listener. Following
+is an example of a <i>VerifyKeyListener</i> that prevents the user from deleting text by
+filtering out the backspace and delete keystrokes.</p>
+
+
+<pre><font COLOR="#7f0000"> // This handler will filter out the backspace and delete keys to prevent deleting characters.
+</font> <font
+COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> verifyKey(VerifyEvent event) {
+ <font
+COLOR="#00007f">if</font> ((event.character == <font COLOR="#007f7f">'\u0008'</font>) || (event.character == <font
+COLOR="#007f7f">'\u007F'</font>)) {
+ event.doit = <font COLOR="#00007f">false</font>;
+ }
+ }</pre>
+
+<h4>Verify Event</h4>
+
+<p>The<b> verify event<font COLOR="#00007f"> </font></b>is sent when a text change is
+about to occur because of user input. It is sent before the text content change is made
+and before the change is reflected in the widget.&nbsp; The fields of the <i>VerifyEvent</i>
+that are used when sending the <strong>verify event</strong> are defined as follows: </p>
+
+<pre><font COLOR="#000084">
+public int</font> start, end; <font
+color="#800000">// range of text being modified</font><font COLOR="#000084">
+ public</font> String text; <font color="#800000">// new text that will be inserted or empty string</font><font COLOR="#000084">
+ public boolean</font> doit; <font color="#800000">// flag indicating whether the text change should be processed</font></pre>
+
+<p>The <i>VerifyEvent </i>contains the start offset and end offset of the replaced text as
+well as the new text. You should register a <i>VerifyListener</i> when you want to make
+changes to the replace range or to the new text before the widget is updated. You can
+force the widget to ignore the text change altogether by setting the <b>doit </b>field of
+the <i>VerifyEvent</i> to false. </p>
+
+<p>You can use the <b>verify event</b> to perform operations such as automatic word
+completion. Following is an example of a <i>VerifyListener</i> that performs word
+completion. When you listen for <b>verify events</b>, you must implement the <b>verifyText(VerifyEvent)</b>
+method.</p>
+
+
+<pre> <font COLOR="#7f0000">// This handler will automatically expand the character &quot;S&quot; to &quot;StyledText&quot;.</font>
+ <font
+COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> verifyText(VerifyEvent event) {
+<font
+COLOR="#7f0000"> // Only expand when text is inserted.
+</font> <font COLOR="#00007f">if</font> (event.end - event.start == 0) {
+ <font
+COLOR="#00007f">if</font> (event.text.equals(<font COLOR="#007f7f">&quot;S&quot;</font>)) {
+ event.text = <font
+COLOR="#007f7f">&quot;StyledText&quot;</font>;
+ }
+ }
+ }</pre>
+
+<p>Note that the <b>verify event</b> that is sent by the <i>StyledText</i> widget is the
+same event that is sent by the SWT <i>Text</i> and <i>Combo</i> widgets.</p>
+
+<h4>Modify Event</h4>
+
+<p>The <b>modify event</b><font COLOR="#00007f"> </font>is sent after the widget's text
+content has been updated. It does not contain any information about the text change. It
+serves as a light weight notification that a text change of some sort has occurred. Use it
+if all you want to know is if the widget text has been modified. For example, to determine
+whether or not to display a &quot;Save Changes?&quot; prompter when an edited file is
+closed. To listen to modify events add a <i>ModifyListener</i> to the <i>StyledText</i>
+widget.</p>
+
+<p>The <b>modify event</b> that is sent by the <i>StyledText</i> widget is the same event
+that is sent by the SWT <i>Text</i> and <i>Combo</i> widgets.</p>
+
+<h4>Extended Modify Event</h4>
+
+<p>The <b>extended modify event</b>, which is sent after the modify event, contains the
+start offset and length of the new text as well as the replaced text. It is the mirror
+image of the <b>verify event</b>.&nbsp; The <b>extended modify event</b> is sent after the
+widget has changed and when the text model reflects the actual text change. It, therefore,
+does not have a <b>doit</b> field like the <b>verify key event</b> and <b>verify event</b>
+do.<b> </b></p>
+
+<p>Register an <i>ExtendedModifyListener</i> if you need to update data after a text
+change occurred and when you need to know the actual text change. For example, if you are
+developing an editor for word processing that supports text styles, when a user types a
+character you will probably want that character to take on the styles of the characters
+around it. In order to implement this behavior, you will need to know where the text
+change occurred, so that you can:
+
+<ol>
+ <li>query the styles of the characters around the new character</li>
+ <li>change the style of the new character</li>
+</ol>
+
+<p>The <b>extended modify event</b> will give you this information. Note that you cannot
+use the <b>verify event</b> to implement the above scenario since the text content change
+has not occurred yet when the <b>verify event</b> event is sent, so changing the style of
+the new character will be impossible. Similarly, you cannot use the <b>modify event</b> to
+implement the above scenario because it does not contain information about the text change
+(e.g., where the text change occurred). </p>
+
+<p>Note that a new event was introduced instead of enhancing the existing<b> modify event </b>in
+order to maintain compatibility with SWT. Not all SWT widgets that send a <b>modify event</b>
+can get the data that is necessary to send an <b>extended modify event</b>. </p>
+
+<h4>Flow of Text Change Notifications&nbsp; </h4>
+
+<p>The following diagram depicts when the events described above occur within the <i>StyledText</i>
+widget. The &quot;Process Input?&quot; and &quot;Process Change?&quot; decisions are
+determined by the value of the boolean <b>VerifyEvent.doit</b> field as described above.
+The key binding processing shown in gray in the diagram is described in more detail <a
+href="#KeyBindings">below</a>. </p>
+
+<p>As shown in the diagram by the &quot;Key Bound?&quot; decision, if a key action is
+defined for user input, text change processing will stop and the key action will be
+processed instead. In the <strong>verify key event</strong> example above, the backspace
+and delete keys are editing actions.&nbsp; So you must use a <em>VerifyKeyListener</em>
+vs. a <em>VerifyListener</em> to filter out these keystrokes.&nbsp; <em>VerifyListeners</em>
+are only notified about content changes, not editing actions.</p>
+
+<p>The Text Content/Styles Update process is also shown in gray.&nbsp; This portion of the
+diagram will be discussed in depth in our second article, <b>Into the Deep End of the
+StyledText Widget</b>. For this article, knowing that the widget applies the text
+change and updates its styles during this step is sufficient. </p>
+
+<p align="center"><img border="0" src="TextChanges.gif" width="519" height="995"> </p>
+
+<h4>Text Notification Examples for User Input </h4>
+
+<p>The following table shows the event data that is sent when you type a character, when
+you delete a character and when you replace two characters with another character.
+&nbsp; There is one column for each event object that is sent. The column header shows the
+event object class and the Step number shown in the flow chart above. </p>
+
+<p>When text changes occur, the <i>VerifyEvent</i> will contain the location of the
+replaced text (as a start and end offset) and the new text, while the <i>ExtendedModifyEvent</i>
+will contain the location of the new text (as start and length) and the replaced text. The
+<i>ModifyEvent</i> is not shown since it does not have any data. </p>
+
+<p>Note that when the <strong>verify key event</strong> is sent in Step 1, the <b>start</b>,
+<b>end</b> and <b>text </b>fields of its <i>VerifyEvent</i> are not used and are,
+therefore, not shown in the table. Likewise the <b>character</b>, <b>keyCode</b> and <b>stateMask</b>
+fields are not used in the <em>VerifyEvent</em> that is created for Step 3. </p>
+
+<p>The second scenario demonstrates that the <i>VerifyKeyListener</i> receives raw
+keyboard input in the <i>VerifyEvent</i>. The <b>VerifyEvent.character</b> field is set to
+\u0008, which is the Unicode value of the backspace key. </p>
+
+<table BORDER="1" CELLSPACING="2" CELLPADDING="7" width="801">
+ <tr>
+ <td WIDTH="149" VALIGN="TOP"><p align="center"><font face="Courier New, Courier, mono"><b>Scenario</b></font></td>
+ <td WIDTH="267" VALIGN="TOP"><p align="center"><font face="Courier New, Courier, mono"><b>VerifyEvent
+ Data (1)<br>
+ sent to VerifyKeyListener</b></font></td>
+ <td WIDTH="247" VALIGN="TOP"><p align="center"><font face="Courier New, Courier, mono"><b>VerifyEvent
+ Data (3)<br>
+ sent to VerifyListener</b></font></td>
+ <td WIDTH="311" VALIGN="TOP"><p align="center"><font face="Courier New, Courier, mono"><b>ExtendedModifyEvent
+ Data (6)</b></font></td>
+ </tr>
+ <tr>
+ <td VALIGN="top" width="149"><font face="Courier New, Courier, mono">User
+ types&nbsp;<br>
+ character 'A'&nbsp;</font> </td>
+ <td WIDTH="267" VALIGN="TOP"><font face="Courier New, Courier, mono">doit
+ = true<br>
+ character = 'A'<br>
+ keyCode = 0<br>
+ stateMask = 0</font> </td>
+ <td WIDTH="247" VALIGN="TOP"><font face="Courier New, Courier, mono">start
+ = 0<br>
+ end = 0<br>
+ text = &quot;A&quot;<br>
+ doit = true</font></td>
+ <td WIDTH="311" VALIGN="TOP"><font face="Courier New, Courier, mono">start
+ = 0<br>
+ length = 1<br>
+ replacedText = &quot;&quot;</font> </td>
+ </tr>
+ <tr>
+ <td VALIGN="top" width="149"><font face="Courier New, Courier, mono">User
+ deletes&nbsp;<br>
+ character 'A'&nbsp;</font> </td>
+ <td WIDTH="267" VALIGN="TOP"><font face="Courier New, Courier, mono">doit
+ = true<br>
+ character = \u0008 (backspace)<br>
+ keyCode = 0<br>
+ stateMask = 0</font> </td>
+ <td WIDTH="247" VALIGN="TOP"><font face="Courier New, Courier, mono">start
+ = 0<br>
+ end = 1<br>
+ text = &quot;&quot;<br>
+ doit = true</font></td>
+ <td WIDTH="311" VALIGN="TOP"><font face="Courier New, Courier, mono">start
+ = 0<br>
+ length = 0<br>
+ replacedText = &quot;A&quot;</font> </td>
+ </tr>
+ <tr>
+ <td VALIGN="top" width="149"><font face="Courier New, Courier, mono">User
+ replaces&nbsp;<br>
+ &quot;AA&quot;<br>
+ with 'B'&nbsp;<br>
+ </font></td>
+ <td WIDTH="267" VALIGN="TOP"><font face="Courier New, Courier, mono">doit
+ = true<br>
+ character = 'B'<br>
+ keyCode = 0<br>
+ stateMask = 0</font> </td>
+ <td WIDTH="247" VALIGN="TOP"><font face="Courier New, Courier, mono">start
+ = 0<br>
+ end = 2<br>
+ text = &quot;B&quot;<br>
+ doit = true</font></td>
+ <td WIDTH="311" VALIGN="TOP"><font face="Courier New, Courier, mono">start
+ = 0<br>
+ length = 1<br>
+ replacedText = &quot;AA&quot;</font> </td>
+ </tr>
+</table>
+
+<h4><a NAME="TextRendering"></a>Text Notification Examples for API Text Changes</h4>
+
+<p>The following table illustrates the data for the change notification events under
+various API text change scenarios. The Initial Text column shows the text before the
+change is made. The initial text of one scenario is the changed text of the previous
+scenario. There is one column for each event object that is sent. The column header for
+these columns shows the event object class and the Step number shown in the flow chart
+above. &nbsp; A ^ character shows the insert point for new text, if any. The text replace
+range, if any, is highlighted using white text on a blue background.</p>
+
+<p>When text changes occur, the <i>VerifyEvent</i> will contain the location of the
+replaced text (as a start and end offset) and the new text, while the <i>ExtendedModifyEvent</i>
+will contain the location of the new text (as start and length) and the replaced text. The
+<i>ModifyEvent</i> is not shown since it does not have any data.</p>
+<div align="center"><center>
+
+ <table BORDER="1" CELLSPACING="2" CELLPADDING="7" width="856">
+ <tr>
+ <td WIDTH="192" VALIGN="TOP"><p align="center"><b><font face="Courier New">Scenario</font></b></td>
+ <td WIDTH="243" VALIGN="TOP"><p align="center"><b><font face="Courier New">Initial
+ Text</font></b></td>
+ <td WIDTH="202" VALIGN="TOP"> <p align="center"><b><font face="Courier New">VerifyEvent
+ Data (3)</font></b></td>
+ <td WIDTH="272" VALIGN="TOP"> <p align="center"><b><font face="Courier New">ExtendedModifyEvent
+ Data (6)</font></b></td>
+ </tr>
+ <tr>
+ <td VALIGN="top" width="192"><font face="Courier New">Insert &quot;sopping
+ &quot;&nbsp;<br>
+ before &quot;wet&quot;&nbsp;</font> </td>
+ <td WIDTH="243" VALIGN="TOP"><pre><font face="Courier New">Getting your feet wet
+ ^</font></pre></td>
+ <td WIDTH="202" VALIGN="TOP"><font face="Courier New">start = 18<br>
+ end = 18<br>
+ text = &quot;sopping &quot;</font></td>
+ <td WIDTH="272" VALIGN="TOP"><font face="Courier New">start = 18<br>
+ length = 8<br>
+ replacedText = &quot;&quot;</font></td>
+ </tr>
+ <tr>
+ <td VALIGN="top" width="192"><font face="Courier New">Delete &quot;y&quot;</font></td>
+ <td WIDTH="243" VALIGN="TOP"><font face="Courier New">Getting <span
+ style="background-color: #000080"><font color="#FFFFFF">y</font></span>our
+ feet sopping wet<br>
+ </font></td>
+ <td WIDTH="202" VALIGN="TOP"><font face="Courier New">start = 8<br>
+ end = 9<br>
+ text = &quot;&quot;</font></td>
+ <td WIDTH="272" VALIGN="TOP"><font face="Courier New">start = 8<br>
+ length = 0<br>
+ replacedText = &quot;y&quot;</font></td>
+ </tr>
+ <tr>
+ <td VALIGN="top" width="192"><font face="Courier New">Replace &quot;our&quot;&nbsp;<br>
+ with &quot;my&quot;</font></td>
+ <td WIDTH="243" VALIGN="TOP"><pre><font face="Courier New">Getting <font
+color="#FFFFFF"><span style="background-color: #000080">our</span></font> feet sopping wet
+ ^</font></pre></td>
+ <td WIDTH="202" VALIGN="TOP"><font face="Courier New">start = 8<br>
+ end = 11<br>
+ text = &quot;my&quot;</font></td>
+ <td WIDTH="272" VALIGN="TOP"><font face="Courier New">start = 8<br>
+ length = 2<br>
+ replacedText = &quot;our&quot;</font></td>
+ </tr>
+ </table>
+</center></div>
+
+<p>Note that, as discussed above, you could change the replace range and the new text that
+are passed in the <i>Veri</i><em>fyE</em><i>vent</i>. For example, in the first scenario
+you could change the end offset of the replace range to 21 in order to replace the word
+&quot;wet&quot; and change the new text to &quot;damp&quot;. The result would be
+&quot;Getting your feet damp&quot;.&nbsp;</p>
+
+<pre><font COLOR="#7f0000"> // This handler will change feet that are about to get &quot;sopping&quot; wet to &quot;damp&quot; feet.
+</font> <font
+COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> verifyText(VerifyEvent event) {
+ <font
+COLOR="#00007f">if</font> ((event.start == 18) &amp;&amp; (event.end == 18) &amp;&amp; (event.text.equals(<font
+COLOR="#007f7f">&quot;sopping&quot;)</font>)) {
+ event.end = 21;
+ event.text = <font
+color="#008080">&quot;damp&quot;</font>;
+ }
+ }</pre>
+
+<p>You could also set the <b>VerifyEvent.doit</b> field to false if you don't want to get
+sopping feet at all.</p>
+
+<pre> // This handler will prevent attempts to insert the word &quot;sopping&quot;.
+ <font
+COLOR="#00007f">public</font> <font COLOR="#00007f">void</font> verifyText(VerifyEvent event) {
+ <font
+COLOR="#00007f">if</font> (event.text.equals(<font COLOR="#007f7f">&quot;sopping&quot;</font>)) {
+ event.doit = <font
+color="#000080">false</font>;
+ }
+ }</pre>
+
+<h3>Text Refresh</h3>
+
+<p>Whenever the same text is redrawn at the same location in the <i>StyledText</i> widget,
+you will see flashing. Flash occurs because the <i>StyledText</i> widget first clears the
+area to be drawn and then draws the text and its styles. Since nothing has changed, the
+redraw operation is perceived as a flash.</p>
+
+<p>In order to avoid flash, you should minimize the amount of redrawing that occurs in the
+widget. Unnecessary redrawing can occur when you use the <b>setStyleRange</b> API if the
+style you specify overlaps existing styles with the same colors and font style. The <em>StyledText</em>
+widget does not check for duplicate styles, so the entire style range will be redrawn and
+unchanged text will be refreshed. For the same reason you should also avoid replacing existing styles
+with the same styles when using the <b>replaceStyleRanges</b> API.</p>
+
+<p>For efficiency reasons, the <i>StyledText</i> widget does not perform duplicate style
+optimizations.&nbsp; Users of the <em>StyledText</em> widget will most likely set styles
+in the <i>ExtendedModifyListener</i>.&nbsp; Since this listener is time-sensitive (i.e.,
+it is called every time a keystroke is entered), the <em>StyledText</em> widget avoids
+superfluous processing when styles are specified. Duplicate style optimizations could also
+mask application problems.&nbsp; If an application is creating duplicate styles, this
+could be a symptom of a larger problem with the application&#146;s logic. </p>
+
+<p>Similar refresh rules apply to the <b>setLineBackground</b> API. If you specify line
+background colors that already exist, you will see flash when unnecessary redrawing
+occurs. Besides reducing flash, avoiding unnecessary redrawing will also improve
+performance since less text will be rendered.</p>
+
+<h3><a name="KeyBindings"></a>Key Bindings</h3>
+
+<p>You can change and query the default key bindings using the <b>setKeyBinding</b>(<b>int
+key, int action) </b>and<b> getKeyBinding(int key)</b> methods. The <b>setKeyBinding</b>
+method takes a key code or character ORed with one or more of the modifiers <b>SWT.CTRL</b>,
+<b>SWT.SHIFT</b> or <b>SWT.ALT</b> as the first argument. SWT.java defines constants for
+some of the frequently used key codes (e.g., <b>SWT.BS</b> for the backspace key). The
+second argument is one of the actions defined in ST.java (e.g.,&nbsp;<dfn><b>ST.
+DELETE_PREVIOUS</b></dfn>). Thus, to map &lt;CTRL&gt;+&lt;b&gt; to work like the backspace
+key and delete the character in front of the caret you would use </p>
+
+<pre> widget.setKeyBinding(SWT.CTRL | <font color="#008080">&#145;b&#146;</font>, ST.DELETE_PREVIOUS)</pre>
+
+<p>You can map more than one&nbsp; key to a single action, but one key can never trigger
+more than one action. If you use an already bound key combination to trigger a different
+action, the existing binding will be removed. </p>
+
+<p>To remove a key binding you specify <b>SWT.NULL</b> as the action. For example, if you
+want to remove the default key binding for &lt;CTRL&gt;+&lt;PAGE UP&gt;, which by default
+moves the caret in front of the first character of the current page, you would use </p>
+
+<pre> widget.setKeyBinding(SWT.CTRL | SWT.PAGE_UP, SWT.NULL)</pre>
+
+<p>To find out which action is triggered by default when &lt;CTRL&gt;+&lt;HOME&gt; is
+pressed you would use </p>
+
+<pre> widget.getKeyBinding(SWT.CTRL | SWT.HOME)</pre>
+
+<p>which returns ST.TEXT_START (sets the caret in front of the first character of the
+text). </p>
+
+<p>In addition to the <b>setKeyBinding</b> API, you can use the <b>invokeAction </b>method
+with one of the actions defined in <em>ST.java</em> to invoke an action independent of
+keyboard input or to handle multi-key actions. For example, to implement Emacs style
+multi-key actions you could use a <i>VerifyKeyListener</i> to listen for a key sequence
+and call <b>invokeAction</b> to perform the desired action. Multi-key actions are actions
+that require two separate keystrokes, where the first keystroke establishes the context
+for the second keystroke. The following code snippet demonstrates how to implement a
+multi-key action. We assume that there is a boolean class variable called<strong>
+previousCtrlX</strong> that we use to store whether the most recent keystroke was a
+&lt;CTRL&gt;+&lt;X&gt;.</p>
+
+<pre><font color="#840000"> // </font><font color="#7f0000">This </font><font
+color="#800000">VerifyKeyListener </font><font color="#7f0000">implements multi-keystrokes using &lt;CTRL&gt;+&lt;X&gt; as the
+</font><font
+color="#840000"> // first keystroke and &lt;P&gt; as the second</font><font
+color="#7f0000"> keystroke. These keystroke are ignore
+</font><font color="#840000"> <font
+color="#7f0000">// by the StyledText widget</font> since we set the VerifyEvent.doit field to false.
+ </font><font
+color="#7f0000"><font COLOR="#000000">widget.addVerifyKeyListener(</font><font
+COLOR="#000084">new</font> VerifyKeyListener() {
+</font><font COLOR="#000000"> </font><font
+color="#7f0000"><font COLOR="#000084">public</font> <font COLOR="#000084">void</font> </font>verifyKey(VerifyEvent event) {
+<font
+color="#800000"> // check whether the current keystroke is a &lt;CTRL&gt;+&lt;X&gt;</font>
+ <font
+COLOR="#000084">boolean</font><font COLOR="#000000"> isCtrlX = (event.stateMask == SWT.CTRL) &amp;&amp; (event.character == </font><font
+COLOR="#008484">'\u0018'</font>)<font COLOR="#000000">;
+</font>
+<font COLOR="#7f0000"> </font> <font
+COLOR="#840000">// select one page if the previous keystroke was &lt;CTRL&gt;+&lt;X&gt; and
+ // the current keystroke is 'P'
+ </font><font
+COLOR="#7f0000"><font COLOR="#000084">if</font><font COLOR="#000000"> (</font></font>previousCtrlX<font
+COLOR="#7f0000"><font COLOR="#000000"> &amp;&amp; Character.toUpperCase(event.character) == </font><font
+COLOR="#008484">'P'</font>) {
+</font><font COLOR="#000000"> widget.invokeAction(ST.SELECT_PAGE_DOWN);
+ </font><font
+COLOR="#7f0000">// ignore the second key of a multi-keystroke</font><font COLOR="#000000">
+</font><font
+COLOR="#7f0000"> <font COLOR="#000000">event.doit = </font><font COLOR="#000084">false</font>;</font>
+<font
+COLOR="#7f0000"> </font>} <font color="#000080">else</font><font COLOR="#000084"> if</font><font
+COLOR="#7f0000"> (</font><font COLOR="#000000">isCtrlX) {
+ </font><font COLOR="#840000"><font
+COLOR="#7f0000">// ignore </font>&lt;CTRL&gt;+&lt;X&gt; <font COLOR="#7f0000">key stroke</font>s</font><font
+color="#000000">
+ <font COLOR="#7f0000"> </font></font> <font COLOR="#7f0000"><font
+color="#000000">event.doit = </font><font COLOR="#000084">false</font>; </font><font
+color="#000000"> </font><font COLOR="#7f0000"><font COLOR="#840000">
+</font><font
+color="#000000"> </font></font> <font color="#000000">}
+ previousCtrlX = isCtrlX;
+</font> }
+ });</pre>
+
+<p>When pressing &lt;CTRL&gt;+&lt;X&gt; followed by hitting &lt;P&gt; the example
+application looks like this</p>
+
+<p align="center"><img border="0" src="Image6.gif" width="200" height="100"></p>
+
+<p align="left">Any other &lt;CTRL&gt;+&lt;X&gt; multi-keystroke will result in the second
+key being inserted in the widget since we only filter out the &lt;P&gt; key combination.</p>
+
+<h3><a name="KeyBindings"></a>Conclusion</h3>
+
+<p>In this article we've covered how to do the following within the <em>StyledText</em>
+widget:
+
+<ul>
+ <li>create the widget</li>
+ <li>define and set text styles</li>
+ <li>handle text changes</li>
+ <li>manage <em>Color</em> objects</li>
+ <li>define key bindings</li>
+</ul>
+
+<p>These functions cover basic text editing and rendering behavior.&nbsp; However, if your
+application has specialized editing or rendering needs, the <em>StyledText</em> widget can
+be customized.&nbsp; In our next article, we will go into depth about why you may want to
+customize the <em>StyledText</em> widget and how you would do this.</p>
+</body>
+</html>
diff --git a/StyledText 2/Idea.jpg b/StyledText 2/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/StyledText 2/Idea.jpg
Binary files differ
diff --git a/StyledText 2/Image8.gif b/StyledText 2/Image8.gif
new file mode 100644
index 0000000..f4bc34b
--- /dev/null
+++ b/StyledText 2/Image8.gif
Binary files differ
diff --git a/StyledText 2/StyledTextContentSpec.java b/StyledText 2/StyledTextContentSpec.java
new file mode 100644
index 0000000..7038f60
--- /dev/null
+++ b/StyledText 2/StyledTextContentSpec.java
@@ -0,0 +1,976 @@
+package org.eclipse.swt.custom;
+/**
+ * Use this test class to validate an implementation of the StyledTextContent
+ * interface. To perform the validation, copy this class to the package where
+ * your StyledTextContent implementation lives. Then specify the fully qualified
+ * name of your StyledTextContent class as an argument to the main method of this
+ * class.
+ *
+ * NOTE: This test class assumes that your StyledTextContent implementation
+ * handles the following delimiters:
+ *
+ * /r
+ * /n
+ * /r/n
+ */
+
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.layout.*;
+import java.io.*;
+import java.lang.reflect.*;
+
+public class StyledTextContentSpec implements TextChangeListener {
+ static String contentClassName;
+ static int failCount = 0;
+ static int errorCount = 0;
+ Class contentClass = null;
+ StyledTextContent contentInstance = null;
+ int verify = 0;
+ Method currentMethod = null;
+ boolean failed = false;
+ StyledText widget = null;
+ Shell shell = null;
+
+public StyledTextContentSpec() {
+}
+public void assert(String message, boolean condition) {
+ System.out.print("\t" + currentMethod.getName() + " " + message);
+ if (!condition)
+ fail(message);
+ else
+ System.out.println(" passed");
+
+}
+public void fail(String message) {
+ failed = true;
+ System.out.println(" FAILED");
+ failCount++;
+}
+public StyledTextContent getContentInstance() {
+ contentInstance.setText("");
+ widget.setContent(contentInstance);
+ return contentInstance;
+}
+public static String getTestText() {
+ return
+ "This is the first line.\r\n" +
+ "This is the second line.\r\n" +
+ "This is the third line.\r\n" +
+ "This is the fourth line.\r\n" +
+ "This is the fifth line.\r\n" +
+ "\r\n" +
+ "This is the first line again.\r\n" +
+ "This is the second line again.\r\n" +
+ "This is the third line again.\r\n" +
+ "This is the fourth line again.\r\n" +
+ "This is the fifth line again.\r\n" +
+ "\r\n" +
+ "This is the first line once again.\r\n" +
+ "This is the second line once again.\r\n" +
+ "This is the third line once again.\r\n" +
+ "This is the fourth line once again.\r\n" +
+ "This is the fifth line once again.";
+}
+public static void main(String[] args) {
+ StyledTextContentSpec spec = new StyledTextContentSpec();
+ if (args.length > 0) {
+ contentClassName = args[0];
+ } else {
+ MessageBox box = new MessageBox(Display.getDefault().getActiveShell(), SWT.ICON_ERROR);
+ box.setMessage("Content class must be specified as an execution argument."); //$NON-NLS-1$
+ box.open();
+ return;
+ }
+ spec.run();
+ System.out.println();
+ System.out.println(failCount + " TEST FAILURES.");
+ System.out.println(errorCount + " UNEXPECTED ERRORS.");
+}
+public void run() {
+ if (contentClassName.equals("")) {
+ MessageBox box = new MessageBox(Display.getDefault().getActiveShell(), SWT.ICON_ERROR);
+ box.setMessage("Content class must be specified as an execution argument."); //$NON-NLS-1$
+ box.open();
+ return;
+ }
+ if (contentClass == null) {
+ try {
+ contentClass = Class.forName(contentClassName);
+ } catch (ClassNotFoundException e) {
+ MessageBox box = new MessageBox(Display.getDefault().getActiveShell(), SWT.ICON_ERROR);
+ box.setMessage("Content class:\n" + contentClassName + "\nnot found"); //$NON-NLS-1$
+ box.open();
+ return;
+ }
+ }
+ try {
+ contentInstance = (StyledTextContent)contentClass.newInstance();
+ } catch (IllegalAccessException e) {
+ MessageBox box = new MessageBox(Display.getDefault().getActiveShell(), SWT.ICON_ERROR);
+ box.setMessage("Unable to access content class:\n" + contentClassName); //$NON-NLS-1$
+ box.open();
+ return;
+ } catch (InstantiationException e) {
+ MessageBox box = new MessageBox(Display.getDefault().getActiveShell(), SWT.ICON_ERROR);
+ box.setMessage("Unable to instantiate content class:\n" + contentClassName); //$NON-NLS-1$
+ box.open();
+ return;
+ }
+ Class clazz;
+ clazz = this.getClass();
+ Method[] methods = clazz.getDeclaredMethods();
+ for (int i=0; i<methods.length; i++) {
+ setUp();
+ currentMethod = methods[i];
+ failed = false;
+ try {
+ if (currentMethod.getName().startsWith("test_")) {
+ System.out.println();
+ System.out.println(currentMethod.getName() + "...");
+ currentMethod.invoke(this, new Object[0]);
+ if (!failed) {
+ System.out.println("PASSED.");
+ } else {
+ System.out.println("FAILED");
+ }
+ }
+ } catch (InvocationTargetException ex) {
+ System.out.println("\t" + currentMethod.getName() + " ERROR ==> " + ex.getTargetException().toString());
+ System.out.println("FAILED");
+ errorCount++;
+ } catch (Exception ex) {
+ System.out.println("\t" + currentMethod.getName() + " ERROR ==> " + ex.toString());
+ System.out.println("FAILED");
+ errorCount++;
+ }
+ if (verify != 0) {
+ verify = 0;
+ contentInstance.removeTextChangeListener(this);
+ }
+ tearDown();
+ }
+}
+public void textSet(TextChangedEvent event) {
+}
+public void textChanged(TextChangedEvent event) {
+}
+public void textChanging(TextChangingEvent event) {
+ switch (verify) {
+ case 1 : {
+ assert(":1a:", event.replaceLineCount == 0);
+ assert(":1b:", event.newLineCount == 1);
+ break;
+ }
+ case 2 : {
+ assert(":2a:", event.replaceLineCount == 2);
+ assert(":2b:", event.newLineCount == 0);
+ break;
+ }
+ case 3 : {
+ assert(":3a:", event.replaceLineCount == 0);
+ assert(":3b:", event.newLineCount == 2);
+ break;
+ }
+ case 4: {
+ assert(":4:", false);
+ break;
+ }
+ case 5 : {
+ assert(":5a:", event.replaceLineCount == 0);
+ assert(":5b:", event.newLineCount == 1);
+ break;
+ }
+ case 6 : {
+ assert(":6a:", event.replaceLineCount == 1);
+ assert(":6b:", event.newLineCount == 0);
+ break;
+ }
+ case 8 : {
+ assert(":8a:", event.replaceLineCount == 1);
+ assert(":8b:", event.newLineCount == 0);
+ break;
+ }
+ case 9 : {
+ assert(":9a:", event.replaceLineCount == 1);
+ assert(":9b:", event.newLineCount == 0);
+ break;
+ }
+ case 10:{
+ assert(":10:", false);
+ break;
+ }
+ case 11: {
+ assert(":11:", false);
+ break;
+ }
+ case 12: {
+ assert(":12a:", event.replaceLineCount == 0);
+ assert(":12b:", event.newLineCount == 1);
+ break;
+ }
+ case 13: {
+ assert(":13a:", event.replaceLineCount == 0);
+ assert(":13b:", event.newLineCount == 1);
+ break;
+ }
+ case 14: {
+ assert(":14:", false);
+ break;
+ }
+ case 15: {
+ assert(":15a:", event.replaceLineCount == 1);
+ assert(":15b:", event.newLineCount == 2);
+ break;
+ }
+ case 16:{
+ assert(":16:", false);
+ break;
+ }
+ case 17: {
+ assert(":17:", false);
+ break;
+ }
+ case 18: {
+ assert(":18a:", event.replaceLineCount == 0);
+ assert(":18b:", event.newLineCount == 2);
+ break;
+ }
+ case 19: {
+ assert(":19a:", event.replaceLineCount == 0);
+ assert(":19b:", event.newLineCount == 3);
+ break;
+ }
+ case 20: {
+ assert(":20:", false);
+ break;
+ }
+ }
+}
+public void test_Insert() {
+ StyledTextContent content = getContentInstance();
+ String newText;
+
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(0, 0, "test\n ");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":1a:", newText.equals("test\n This\nis a test\r"));
+ assert(":1b:", content.getLineCount() == 4);
+ assert(":1c:", content.getLine(0).equals("test"));
+ assert(":1d:", content.getLine(1).equals(" This"));
+ assert(":1e:", content.getLine(2).equals("is a test"));
+ assert(":1f:", content.getLine(3).equals(""));
+
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(5, 0, "*** ");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":2a:", newText.equals("This\n*** is a test\r"));
+ assert(":2b:", content.getLineCount() == 3);
+ assert(":2c:", content.getLine(0).equals("This"));
+ assert(":2d:", content.getLine(1).equals("*** is a test"));
+ assert(":2e:", content.getLine(2).equals(""));
+
+ content.setText("Line 1\r\nLine 2");
+ content.replaceTextRange(0, 0, "\r");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":3a:", newText.equals("\rLine 1\r\nLine 2"));
+ assert(":3b:", content.getLineCount() == 3);
+ assert(":3c:", content.getLine(0).equals(""));
+ assert(":3d:", content.getLine(1).equals("Line 1"));
+ assert(":3e:", content.getLine(2).equals("Line 2"));
+ content.replaceTextRange(9, 0, "\r");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":3f:", newText.equals("\rLine 1\r\n\rLine 2"));
+ assert(":3g:", content.getLineCount() == 4);
+ assert(":3h:", content.getLine(0).equals(""));
+ assert(":3i:", content.getLine(1).equals("Line 1"));
+ assert(":3j:", content.getLine(2).equals(""));
+ assert(":3k:", content.getLine(3).equals("Line 2"));
+
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(0, 0, "\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":4a:", newText.equals("\nThis\nis a test\r"));
+ assert(":4b:", content.getLineCount() == 4);
+ assert(":4c:", content.getLine(0).equals(""));
+ assert(":4d:", content.getLine(1).equals("This"));
+ assert(":4e:", content.getLine(2).equals("is a test"));
+ assert(":4f:", content.getLine(3).equals(""));
+
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(7, 0, "\r\nnewLine");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":5a:", newText.equals("This\nis\r\nnewLine a test\r"));
+ assert(":5b:", content.getLineCount() == 4);
+ assert(":5c:", content.getLine(0).equals("This"));
+ assert(":5d:", content.getLine(1).equals("is"));
+ assert(":5e:", content.getLine(2).equals("newLine a test"));
+ assert(":5f:", content.getLine(3).equals(""));
+
+ content.setText("");
+ content.replaceTextRange(0, 0, "This\nis\r\nnewLine a test\r");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":6a:", newText.equals("This\nis\r\nnewLine a test\r"));
+ assert(":6b:", content.getLineCount() == 4);
+ assert(":6c:", content.getLine(0).equals("This"));
+ assert(":6d:", content.getLine(1).equals("is"));
+ assert(":6e:", content.getLine(2).equals("newLine a test"));
+ assert(":6f:", content.getLine(3).equals(""));
+
+ // insert at end
+ content.setText("This");
+ content.replaceTextRange(4, 0, "\n ");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":7a:", newText.equals("This\n "));
+ assert(":7b:", content.getLineCount() == 2);
+ assert(":7c:", content.getLine(0).equals("This"));
+ assert(":7d:", content.getLine(1).equals(" "));
+ content.setText("This\n");
+ content.replaceTextRange(5, 0, "\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":7e:", newText.equals("This\n\n"));
+ assert(":7f:", content.getLineCount() == 3);
+ assert(":7g:", content.getLine(0).equals("This"));
+ assert(":7h:", content.getLine(1).equals(""));
+ assert(":7i:", content.getLine(2).equals(""));
+
+ // insert at beginning
+ content.setText("This");
+ content.replaceTextRange(0, 0, "\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":8a:", newText.equals("\nThis"));
+ assert(":8b:", content.getLineCount() == 2);
+ assert(":8c:", content.getLine(0).equals(""));
+ assert(":8d:", content.getLine(1).equals("This"));
+
+ // insert text
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(5, 0, "*** ");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":9a:", newText.equals("This\n*** is a test\r"));
+ assert(":9b:", content.getLineCount() == 3);
+ assert(":9c:", content.getLine(0).equals("This"));
+ assert(":9d:", content.getLine(1).equals("*** is a test"));
+ assert(":9e:", content.getLine(2).equals(""));
+
+ content.setText("This\n");
+ content.replaceTextRange(5, 0, "line");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":10a:", newText.equals("This\nline"));
+ assert(":10b:", content.getLineCount() == 2);
+ assert(":10c:", content.getLine(0).equals("This"));
+ assert(":10d:", content.getLine(1).equals("line"));
+ assert(":10e:", content.getLineAtOffset(8) == 1);
+ assert(":10f:", content.getLineAtOffset(9) == 1);
+
+ // insert at beginning
+ content.setText("This\n");
+ content.replaceTextRange(0, 0, "line\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":11a:", newText.equals("line\nThis\n"));
+ assert(":11b:", content.getLineCount() == 3);
+ assert(":11c:", content.getLine(0).equals("line"));
+ assert(":11d:", content.getLine(1).equals("This"));
+ assert(":11e:", content.getLineAtOffset(5) == 1);
+
+ content.setText("Line 1\r\nLine 2\r\nLine 3");
+ content.replaceTextRange(0, 0, "\r");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":12a:", newText.equals("\rLine 1\r\nLine 2\r\nLine 3"));
+ assert(":12b:", content.getLineCount() == 4);
+ assert(":12c:", content.getLine(0).equals(""));
+ assert(":12d:", content.getLine(1).equals("Line 1"));
+ assert(":12e:", content.getLine(2).equals("Line 2"));
+ assert(":12f:", content.getLine(3).equals("Line 3"));
+
+ content.setText("Line 1\nLine 2\nLine 3");
+ content.replaceTextRange(7, 0, "Line1a\nLine1b\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":13a:", newText.equals("Line 1\nLine1a\nLine1b\nLine 2\nLine 3"));
+ assert(":13b:", content.getLineCount() == 5);
+ assert(":13c:", content.getLine(0).equals("Line 1"));
+ assert(":13d:", content.getLine(1).equals("Line1a"));
+ assert(":13e:", content.getLine(2).equals("Line1b"));
+ assert(":13f:", content.getLine(3).equals("Line 2"));
+ assert(":13g:", content.getLine(4).equals("Line 3"));
+
+ content.setText("Line 1\nLine 2\nLine 3");
+ content.replaceTextRange(11, 0, "l1a");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":14a:", newText.equals("Line 1\nLinel1a 2\nLine 3"));
+ assert(":14b:", content.getLineCount() == 3);
+ assert(":14c:", content.getLine(0).equals("Line 1"));
+ assert(":14d:", content.getLine(1).equals("Linel1a 2"));
+ assert(":14e:", content.getLine(2).equals("Line 3"));
+
+ content.setText("Line 1\nLine 2 is a very long line that spans many words\nLine 3");
+ content.replaceTextRange(19, 0, "very, very, ");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":15a:", newText.equals("Line 1\nLine 2 is a very, very, very long line that spans many words\nLine 3"));
+ assert(":15b:", content.getLineCount() == 3);
+ assert(":15c:", content.getLine(0).equals("Line 1"));
+ assert(":15d:", content.getLine(1).equals("Line 2 is a very, very, very long line that spans many words"));
+ assert(":15e:", content.getLine(2).equals("Line 3"));
+}
+
+public void test_Empty() {
+ StyledTextContent content = getContentInstance();
+ assert(":1a:", content.getLineCount() == 1);
+ assert(":1b:", content.getLine(0).equals(""));
+
+ content.setText("test");
+ content.replaceTextRange(0,4,"");
+ assert(":2a:", content.getLineCount() == 1);
+ assert(":2b:", content.getLine(0).equals(""));
+}
+public void test_Line_Conversion() {
+ StyledTextContent content = getContentInstance();
+
+ content.setText("This\nis a test\rrepeat\nend\r");
+ assert(":1a:", content.getLineCount() == 5);
+ assert(":1b:", content.getLine(0).equals("This"));
+ assert(":1c:", content.getOffsetAtLine(0) == 0);
+ assert(":1d:", content.getLine(1).equals("is a test"));
+ assert(":1e:", content.getLineAtOffset(4) == 0);
+ assert(":1f:", content.getOffsetAtLine(1) == 5);
+ assert(":1g:", content.getLine(2).equals("repeat"));
+ assert(":1h:", content.getOffsetAtLine(2) == 15);
+ assert(":1i:", content.getLine(3).equals("end"));
+ assert(":1j:", content.getOffsetAtLine(3) == 22);
+ assert(":1k:", content.getLine(4).equals(""));
+ assert(":1l:", content.getOffsetAtLine(4) == 26);
+
+ content.setText("This\r\nis a test");
+ assert(":2a:", content.getLineCount() == 2);
+ assert(":2b:", content.getLine(1).equals("is a test"));
+ assert(":2c:", content.getLineAtOffset(4) == 0);
+ assert(":2d:", content.getLineAtOffset(5) == 0);
+
+ content.setText("This\r\nis a test\r");
+ assert(":3a:", content.getLineCount() == 3);
+ assert(":3b:", content.getLine(1).equals("is a test"));
+ assert(":3c:", content.getLineAtOffset(15) == 1);
+
+ content.setText("\r\n");
+ assert(":4a:", content.getLineCount() == 2);
+ assert(":4b:", content.getLine(0).equals(""));
+ assert(":4c:", content.getLine(1).equals(""));
+ assert(":4d:", content.getLineAtOffset(0) == 0);
+ assert(":4e:", content.getLineAtOffset(1) == 0);
+ assert(":4f:", content.getLineAtOffset(2) == 1);
+
+ content.setText("\r\n\n\r\r\n");
+ assert(":5a:", content.getLineCount() == 5);
+ assert(":5b:", content.getLine(0).equals(""));
+ assert(":5c:", content.getOffsetAtLine(0) == 0);
+ assert(":5d:", content.getLine(1).equals(""));
+ assert(":5e:", content.getOffsetAtLine(1) == 2);
+ assert(":5f:", content.getLine(2).equals(""));
+ assert(":5g:", content.getOffsetAtLine(2) == 3);
+ assert(":5h:", content.getLine(3).equals(""));
+ assert(":5i:", content.getOffsetAtLine(3) == 4);
+ assert(":5j:", content.getLine(4).equals(""));
+ assert(":5k:", content.getOffsetAtLine(4) == 6);
+
+ content.setText("test\r\rtest2\r\r");
+ assert(":6a:", content.getLineCount() == 5);
+ assert(":6b:", content.getLine(0).equals("test"));
+ assert(":6c:", content.getOffsetAtLine(0) == 0);
+ assert(":6d:", content.getLine(1).equals(""));
+ assert(":6e:", content.getOffsetAtLine(1) == 5);
+ assert(":6f:", content.getLine(2).equals("test2"));
+ assert(":6g:", content.getOffsetAtLine(2) == 6);
+ assert(":6h:", content.getLine(3).equals(""));
+ assert(":6i:", content.getOffsetAtLine(3) == 12);
+ assert(":6j:", content.getLine(4).equals(""));
+ assert(":6k:", content.getOffsetAtLine(4) == 13);
+}
+public void test_Offset_To_Line() {
+ StyledTextContent content = getContentInstance();
+
+ content.setText("This\nis a test\rrepeat\nend\r");
+ assert(":1a:", content.getLineAtOffset(0) == 0);
+ assert(":1b:", content.getLineAtOffset(3) == 0);
+ assert(":1c:", content.getLineAtOffset(4) == 0);
+ assert(":1d:", content.getLineAtOffset(25) == 3);
+ assert(":1e:", content.getLineAtOffset(26) == 4);
+
+ content.setText("This\r\nis a test");
+ assert(":2a:", content.getLineAtOffset(5) == 0);
+ assert(":2b:", content.getLineAtOffset(6) == 1);
+ assert(":2c:", content.getLineAtOffset(10) == 1);
+
+ content.setText("\r\n");
+ assert(":3a:", content.getLineAtOffset(0) == 0);
+ assert(":3b:", content.getLineAtOffset(1) == 0);
+ assert(":3c:", content.getLineAtOffset(2) == 1);
+
+ content.setText("\r\n\n\r\r\n");
+ assert(":4a:", content.getLineAtOffset(0) == 0);
+ assert(":4b:", content.getLineAtOffset(1) == 0);
+ assert(":4c:", content.getLineAtOffset(2) == 1);
+ assert(":4d:", content.getLineAtOffset(3) == 2);
+ assert(":4e:", content.getLineAtOffset(4) == 3);
+ assert(":4f:", content.getLineAtOffset(5) == 3);
+ assert(":4g:", content.getLineAtOffset(6) == 4);
+
+ content.setText("\r\n\r\n");
+ assert(":5a:", content.getLineAtOffset(0) == 0);
+ assert(":5b:", content.getLineAtOffset(1) == 0);
+ assert(":5c:", content.getLineAtOffset(2) == 1);
+ assert(":5d:", content.getLineAtOffset(3) == 1);
+ assert(":5e:", content.getLineAtOffset(4) == 2);
+
+ content.setText("\r\r\r\n\r\n");
+ assert(":6a:", content.getLineAtOffset(0) == 0);
+ assert(":6b:", content.getLineAtOffset(1) == 1);
+ assert(":6c:", content.getLineAtOffset(2) == 2);
+ assert(":6d:", content.getLineAtOffset(4) == 3);
+
+ content.setText("");
+ assert(":7a:", content.getLineAtOffset(0) == 0);
+
+ content = getContentInstance();
+ assert(":8a:", content.getLineAtOffset(0) == 0);
+}
+
+public void test_Line_To_Offset() {
+ StyledTextContent content = getContentInstance();
+
+ content.setText("This\nis a test\rrepeat\nend\r");
+ assert(":1a:", content.getOffsetAtLine(0) == 0);
+ assert(":1b:", content.getOffsetAtLine(1) == 5);
+ assert(":1c:", content.getOffsetAtLine(2) == 15);
+ assert(":1d:", content.getOffsetAtLine(3) == 22);
+ assert(":1e:", content.getOffsetAtLine(4) == 26);
+
+ content.setText("This\r\nis a test");
+ assert(":2a:", content.getOffsetAtLine(0) == 0);
+ assert(":2b:", content.getOffsetAtLine(1) == 6);
+
+ content.setText("\r\n");
+ assert(":3a:", content.getOffsetAtLine(0) == 0);
+ assert(":3b:", content.getOffsetAtLine(1) == 2);
+
+ content.setText("\r\n\n\r\r\n");
+ assert(":4a:", content.getOffsetAtLine(0) == 0);
+ assert(":4b:", content.getOffsetAtLine(1) == 2);
+ assert(":4c:", content.getOffsetAtLine(2) == 3);
+ assert(":4d:", content.getOffsetAtLine(3) == 4);
+ assert(":4e:", content.getOffsetAtLine(4) == 6);
+
+ content.setText("\r\ntest\r\n");
+ assert(":5a:", content.getOffsetAtLine(0) == 0);
+ assert(":5b:", content.getOffsetAtLine(1) == 2);
+ assert(":5c:", content.getOffsetAtLine(2) == 8);
+}
+
+public void test_Delete() {
+ StyledTextContent content = getContentInstance();
+ String newText;
+
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(6, 2, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":1a:", newText.equals("This\nia test\r"));
+ assert(":1b:", content.getLine(0).equals("This"));
+ assert(":1c:", content.getLine(1).equals("ia test"));
+
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(5, 9, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":2a:", newText.equals("This\n\r"));
+ assert(":2b:",content.getLineCount() == 3);
+ assert(":2c:", content.getLine(0).equals("This"));
+ assert(":2d:", content.getLine(1).equals(""));
+ assert(":2e:", content.getLine(2).equals(""));
+
+ content.setText("This\nis a test\nline 3\nline 4");
+ content.replaceTextRange(21, 7, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":3a:", newText.equals("This\nis a test\nline 3"));
+ assert(":3b:", content.getLineCount() == 3);
+ assert(":3c:", content.getLine(0).equals("This"));
+ assert(":3d:", content.getLine(1).equals("is a test"));
+ assert(":3e:", content.getLine(2).equals("line 3"));
+
+ content.setText("This\nis a test\nline 3\nline 4");
+ content.replaceTextRange(0, 5, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":4a:", newText.equals("is a test\nline 3\nline 4"));
+ assert(":4b:", content.getLineCount() == 3);
+ assert(":4c:", content.getLine(0).equals("is a test"));
+ assert(":4d:", content.getLine(1).equals("line 3"));
+ assert(":4e:", content.getLine(2).equals("line 4"));
+ content.replaceTextRange(16, 7, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":4f:", newText.equals("is a test\nline 3"));
+ assert(":4g:", content.getLine(0).equals("is a test"));
+ assert(":4h:", content.getLine(1).equals("line 3"));
+ content.replaceTextRange(9, 7, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":4i:", newText.equals("is a test"));
+ assert(":4j:", content.getLine(0).equals("is a test"));
+ content.replaceTextRange(1, 8, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":4k:", newText.equals("i"));
+ assert(":4l:", content.getLine(0).equals("i"));
+ content.replaceTextRange(0, 1, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":4m:", newText.equals(""));
+ assert(":4n:", content.getLine(0).equals(""));
+
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(5, 9, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":5a:", newText.equals("This\n\r"));
+ assert(":5b:",content.getLineCount() == 3);
+ assert(":5c:", content.getLine(0).equals("This"));
+ assert(":5d:", content.getLine(1).equals(""));
+ assert(":5e:", content.getLine(2).equals(""));
+
+ content.setText("L1\r\nL2\r\nL3\r\nL4\r\n");
+ content.replaceTextRange(4, 8, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":6a:", newText.equals("L1\r\nL4\r\n"));
+ assert(":6b:",content.getLineCount() == 3);
+ assert(":6c:", content.getLine(0).equals("L1"));
+ assert(":6d:", content.getLine(1).equals("L4"));
+ assert(":6e:", content.getLine(2).equals(""));
+
+ content.setText("\nL1\r\nL2");
+ content.replaceTextRange(0, 1, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":7a:", newText.equals("L1\r\nL2"));
+ assert(":7b:",content.getLineCount() == 2);
+ assert(":7c:", content.getLine(0).equals("L1"));
+ assert(":7d:", content.getLine(1).equals("L2"));
+
+ content.setText("\nL1\r\nL2\r\n");
+ content.replaceTextRange(7, 2, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":8a:", newText.equals("\nL1\r\nL2"));
+ assert(":8b:",content.getLineCount() == 3);
+ assert(":8c:", content.getLine(0).equals(""));
+ assert(":8d:", content.getLine(1).equals("L1"));
+ assert(":8e:", content.getLine(2).equals("L2"));
+
+ content.setText("\nLine 1\nLine 2\n");
+ content.replaceTextRange(0, 7, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":9a:", newText.equals("\nLine 2\n"));
+ assert(":9b:", content.getLineCount() == 3);
+ assert(":9c:", content.getLine(0).equals(""));
+ assert(":9d:", content.getLine(1).equals("Line 2"));
+ assert(":9e:", content.getLine(2).equals(""));
+
+ content.setText("Line 1\nLine 2\n");
+ content.replaceTextRange(6, 8, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":10a:", newText.equals("Line 1"));
+ assert(":10b:", content.getLineCount() == 1);
+ assert(":10c:", content.getLine(0).equals("Line 1"));
+
+ content.setText("Line one is short\r\nLine 2 is a longer line\r\nLine 3\n");
+ content.replaceTextRange(12, 17, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":11a:", newText.equals("Line one is a longer line\r\nLine 3\n"));
+ assert(":11b:", content.getLineCount() == 3);
+ assert(":11c:", content.getLine(0).equals("Line one is a longer line"));
+ assert(":11d:", content.getLine(1).equals("Line 3"));
+ assert(":11e:", content.getLine(2).equals(""));
+
+}
+public void test_Replace() {
+ StyledTextContent content = getContentInstance();
+ String newText;
+
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(5, 4, "a");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":1a:", newText.equals("This\na test\r"));
+ assert(":1b:",content.getLineCount() == 3);
+ assert(":1c:", content.getLine(0).equals("This"));
+ assert(":1d:", content.getLine(1).equals("a test"));
+ assert(":1e:", content.getLine(2).equals(""));
+
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(5, 2, "was");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":2a:", newText.equals("This\nwas a test\r"));
+ assert(":2b:",content.getLineCount() == 3);
+ assert(":2c:", content.getLine(0).equals("This"));
+ assert(":2d:", content.getLine(1).equals("was a test"));
+ assert(":2e:", content.getLine(2).equals(""));
+
+ content.setText("This is a test\r");
+ content.replaceTextRange(5, 2, "was");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":3a:", newText.equals("This was a test\r"));
+ assert(":3b:",content.getLineCount() == 2);
+ assert(":3c:", content.getLine(0).equals("This was a test"));
+ assert(":3d:", content.getLineAtOffset(15) == 0);
+
+ content.setText("Line 1\nLine 2\nLine 3");
+ content.replaceTextRange(0, 7, "La\nLb\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":4a:", newText.equals("La\nLb\nLine 2\nLine 3"));
+ assert(":4b:", content.getLine(0).equals("La"));
+ assert(":4c:", content.getLine(1).equals("Lb"));
+ assert(":4d:", content.getLine(2).equals("Line 2"));
+ assert(":4e:", content.getLine(3).equals("Line 3"));
+
+ content.setText(getTestText());
+ newText = content.getTextRange(0, content.getCharCount());
+ int start = content.getOffsetAtLine(6);
+ int end = content.getOffsetAtLine(11);
+ content.replaceTextRange(start, end - start, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":5a:", content.getLineCount() == 12);
+ assert(":5a:", content.getLine(5).equals(""));
+ assert(":5a:", content.getLine(6).equals(""));
+ start = content.getOffsetAtLine(7);
+ content.replaceTextRange(start, content.getCharCount() - start, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":5a:", content.getLineCount() == 8);
+ assert(":5a:", content.getLine(5).equals(""));
+ assert(":5a:", content.getLine(6).equals(""));
+ assert(":5a:", content.getLine(7).equals(""));
+
+}
+public void test_Special_Cases() {
+ String newText;
+ StyledTextContent content = getContentInstance();
+ assert(":0a:", content.getLineCount() == 1);
+ assert(":0b:", content.getOffsetAtLine(0) == 0);
+
+ content.setText("This is the input/output text component.");
+ content.replaceTextRange(0, 0, "\n");
+ assert(":1a:", content.getLine(0).equals(""));
+ content.replaceTextRange(1, 0, "\n");
+ assert(":1b:",content.getLine(0).equals(""));
+ content.replaceTextRange(2, 0, "\n");
+ assert(":1c:",content.getLine(0).equals(""));
+ content.replaceTextRange(3, 0, "\n");
+ assert(":1d:",content.getLine(0).equals(""));
+ content.replaceTextRange(4, 0, "\n");
+ assert(":1e:",content.getLine(0).equals(""));
+ content.replaceTextRange(5, 0, "\n");
+ assert(":1f:",content.getLine(0).equals(""));
+ content.replaceTextRange(6, 0, "\n");
+ assert(":1g:",content.getLine(0).equals(""));
+ content.replaceTextRange(7, 0, "\n");
+ assert(":1h:",content.getLine(0).equals(""));
+
+ content.setText("This is the input/output text component.");
+ content.replaceTextRange(0, 0, "\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":2a:", newText.equals("\nThis is the input/output text component."));
+ assert(":2b:", content.getLine(0).equals(""));
+ assert(":2c:", content.getLine(1).equals("This is the input/output text component."));
+ content.replaceTextRange(1, 0, "\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":2d:", newText.equals("\n\nThis is the input/output text component."));
+ assert(":2e:", content.getLine(0).equals(""));
+ assert(":2f:", content.getLine(1).equals(""));
+ assert(":2g:", content.getLine(2).equals("This is the input/output text component."));
+
+ content.replaceTextRange(2, 0, "\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":3a:", newText.equals("\n\n\nThis is the input/output text component."));
+ assert(":3b:", content.getLine(0).equals(""));
+ assert(":3c:", content.getLine(1).equals(""));
+ assert(":3d:", content.getLine(2).equals(""));
+ assert(":3e:", content.getLine(3).equals("This is the input/output text component."));
+ content.replaceTextRange(3, 0, "\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":3f:", newText.equals("\n\n\n\nThis is the input/output text component."));
+ assert(":3g:", content.getLine(0).equals(""));
+ assert(":3h:", content.getLine(1).equals(""));
+ assert(":3i:", content.getLine(2).equals(""));
+ assert(":3j:", content.getLine(3).equals(""));
+ assert(":3k:", content.getLine(4).equals("This is the input/output text component."));
+
+ content.replaceTextRange(3, 1, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":4a:", newText.equals("\n\n\nThis is the input/output text component."));
+ assert(":4b:", content.getLine(0).equals(""));
+ assert(":4c:", content.getLine(1).equals(""));
+ assert(":4d:", content.getLine(2).equals(""));
+ assert(":4e:", content.getLine(3).equals("This is the input/output text component."));
+ content.replaceTextRange(2, 1, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":4f:", newText.equals("\n\nThis is the input/output text component."));
+ assert(":4g:", content.getLine(0).equals(""));
+ assert(":4h:", content.getLine(1).equals(""));
+ assert(":4i:", content.getLine(2).equals("This is the input/output text component."));
+
+ content.replaceTextRange(2, 0, "a");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":5a:", newText.equals("\n\naThis is the input/output text component."));
+ assert(":5b:", content.getLine(0).equals(""));
+ assert(":5c:", content.getLine(1).equals(""));
+ assert(":5d:", content.getLine(2).equals("aThis is the input/output text component."));
+
+ content.setText("abc\r\ndef");
+ content.replaceTextRange(1, 1, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":6a:", newText.equals("ac\r\ndef"));
+ assert(":6b:", content.getLineCount() == 2);
+ assert(":6c:", content.getLine(0).equals("ac"));
+ assert(":6d:", content.getLine(1).equals("def"));
+ content.replaceTextRange(1, 1, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":6e:", newText.equals("a\r\ndef"));
+ assert(":6f:", content.getLineCount() == 2);
+ assert(":6g:", content.getLine(0).equals("a"));
+ assert(":6h:", content.getLine(1).equals("def"));
+ content.replaceTextRange(1, 2, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":6i:", newText.equals("adef"));
+ assert(":6j:", content.getLineCount() == 1);
+ assert(":6k:", content.getLine(0).equals("adef"));
+ content.replaceTextRange(1, 1, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":6l:", newText.equals("aef"));
+ assert(":6m:", content.getLineCount() == 1);
+ assert(":6n:", content.getLine(0).equals("aef"));
+ content.replaceTextRange(1, 1, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":6o:", newText.equals("af"));
+ assert(":6p:", content.getLineCount() == 1);
+ assert(":6q:", content.getLine(0).equals("af"));
+
+ content.setText("abc");
+ content.replaceTextRange(0, 1, "1");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":7a:", content.getLineCount() == 1);
+ assert(":7b:", newText.equals("1bc"));
+ assert(":7c:", content.getLine(0).equals("1bc"));
+ content.replaceTextRange(0, 0, "\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":7d:", newText.equals("\n1bc"));
+ assert(":7e:", content.getLineCount() == 2);
+ assert(":7f:", content.getLine(0).equals(""));
+ assert(":7g:", content.getLine(1).equals("1bc"));
+
+ content = getContentInstance();
+ content.replaceTextRange(0,0,"a");
+
+ content.setText("package test;\n/* Line 1\n * Line 2\n */\npublic class SimpleClass {\n}");
+ content.replaceTextRange(14, 23, "\t/*Line 1\n\t * Line 2\n\t */");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":8a:", newText.equals("package test;\n\t/*Line 1\n\t * Line 2\n\t */\npublic class SimpleClass {\n}"));
+ assert(":8b:", content.getLineCount() == 6);
+ assert(":8c:", content.getLine(0).equals("package test;"));
+ assert(":8d:", content.getLine(1).equals("\t/*Line 1"));
+ assert(":8e:", content.getLine(2).equals("\t * Line 2"));
+ assert(":8f:", content.getLine(3).equals("\t */"));
+ assert(":8g:", content.getLine(4).equals("public class SimpleClass {"));
+ assert(":8h:", content.getLine(5).equals("}"));
+}
+public void test_Text_Changed_Event() {
+ StyledTextContent content = getContentInstance();
+ content.addTextChangeListener(this);
+ verify = 1;
+ content.setText("testing");
+ content.replaceTextRange(0, 0, "\n");
+
+ verify = 2;
+ content.setText("\n\n");
+ content.replaceTextRange(0, 2, "a");
+
+ verify = 3;
+ content.setText("a");
+ content.replaceTextRange(0, 1, "\n\n");
+
+ verify = 5;
+ content.setText("Line 1\r\nLine 2");
+ content.replaceTextRange(0, 0, "\r");
+
+ verify = 6;
+ content.setText("This\nis a test\nline 3\nline 4");
+ content.replaceTextRange(21, 7, "");
+
+ verify = 7;
+ content.setText("This\nis a test\r");
+ content.replaceTextRange(5, 9, "");
+
+ verify = 8;
+ content.setText("\nL1\r\nL2\r\n");
+ content.replaceTextRange(7, 2, "");
+
+ verify = 9;
+ content.setText("L1\r\n");
+ content.replaceTextRange(2, 2, "test");
+
+ verify = 12;
+ content.setText("L1\r");
+ content.replaceTextRange(3, 0, "\n");
+
+ verify = 13;
+ content.setText("L1\n");
+ content.replaceTextRange(2, 0, "\r");
+
+ verify = 15;
+ content.setText("L1\r\n");
+ content.replaceTextRange(2, 2, "test\n\n");
+
+ verify = 18;
+ content.setText("L1\r");
+ content.replaceTextRange(3, 0, "\ntest\r\n");
+
+ verify = 19;
+ content.setText("L1\n");
+ content.replaceTextRange(2, 0, "test\r\r\r");
+
+ verify = 0;
+ content.removeTextChangeListener(this);
+}
+public void test_Delimiter_Special_Cases() {
+ StyledTextContent content = getContentInstance();
+ String newText;
+
+ content.setText("\nL1\r\nL2\r\n");
+ content.replaceTextRange(7, 2, "");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":1:", newText.equals("\nL1\r\nL2"));
+
+ content.setText("L1\r\n");
+ content.replaceTextRange(2, 2, "test\n\n");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":2:", newText.equals("L1test\n\n"));
+
+ content.setText("L1\n");
+ content.replaceTextRange(2, 0, "test\r\r\r");
+ newText = content.getTextRange(0, content.getCharCount());
+ assert(":3:", newText.equals("L1test\r\r\r\n"));
+
+}
+protected void setUp() {
+ // create shell
+ shell = new Shell ();
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ shell.setSize(500, 300);
+ shell.setLayout(layout);
+ // create widget
+ widget = new StyledText (shell, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
+ GridData spec = new GridData();
+ spec.horizontalAlignment = spec.FILL;
+ spec.grabExcessHorizontalSpace = true;
+ spec.verticalAlignment = spec.FILL;
+ spec.grabExcessVerticalSpace = true;
+ widget.setLayoutData(spec);
+ shell.open ();
+}
+protected void tearDown() {
+ if (shell != null && !shell.isDisposed ())
+ shell.dispose ();
+ shell = null;
+
+}
+
+
+}
diff --git a/StyledText 2/TextChanges.gif b/StyledText 2/TextChanges.gif
new file mode 100644
index 0000000..02bda3b
--- /dev/null
+++ b/StyledText 2/TextChanges.gif
Binary files differ
diff --git a/StyledText 2/TextUpdate.gif b/StyledText 2/TextUpdate.gif
new file mode 100644
index 0000000..8f8b477
--- /dev/null
+++ b/StyledText 2/TextUpdate.gif
Binary files differ
diff --git a/StyledText 2/article2.html b/StyledText 2/article2.html
new file mode 100644
index 0000000..882d3dc
--- /dev/null
+++ b/StyledText 2/article2.html
@@ -0,0 +1,829 @@
+<html>
+
+<head>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<title>Into the Deep End of the SWT StyledText Widget</title>
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+
+<body LINK="#0000ff" VLINK="#800080">
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2001,2002 International Business Machines Corp.</font>
+ <table border=0 cellspacing=0 cellpadding=2 width="100%">
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+ Corner Article</font></font></b></td>
+ </tr>
+ </table>
+</div>
+<div align="left">
+ <h1><img src="Idea.jpg" height=86 width=120 align=CENTER></h1>
+</div>
+<p>&nbsp;</p>
+
+<h1 ALIGN="CENTER">Into the Deep End of the</h1>
+
+<h1 ALIGN="CENTER">SWT StyledText Widget</h1>
+
+
+<blockquote>
+<b>Summary</b>
+
+<p>The<i> StyledText</i> widget is a customizable widget that can be used to display and
+ edit text with different colors and font styles. In this article we discuss why you might
+ want to customize the <i>StyledText</i> widget and how you would do that. The article
+ assumes you are familiar with the concepts presented in our other article, <a
+ HREF="http://www.eclipsecorner.org/articles/StyledText%201/article1.html">&quot;Getting
+ Your Feet Wet With the SWT StyledText Widget&quot;</a>.</p>
+<p><b>By Lynne Kues and Knut Radloff, OTI</b>
+<br>
+ October 17, 2001; updated September 18, 2002 for Eclipse 2.0</p>
+</blockquote>
+
+<hr width="100%">
+<h2>Overview</h2>
+
+<p>The <i>StyledText</i> widget is designed as a pluggable widget. You can supply any or
+all of the following components in order to customize the widget to your needs:
+
+<ul>
+ <li>
+ <i>StyledTextContent</i> for storing and manipulating the widget&#146;s text. The <i>StyledText</i>
+ widget interacts with its <i>StyledTextContent</i> in order to access and update the text
+ that is being displayed and edited in the widget. </li>
+ <li>
+ <i>LineStyleListener</i> for answering the style information that is associated with the
+ widget&#146;s text. When the <i>StyledText</i> widget displays a line of text, it will ask
+ its <i>LineStyleListener</i> for the line&#146;s style information. </li>
+ <li>
+ <i>LineBackgroundListener</i> for answering background colors for the lines that are
+ displayed by the widget. When the <i>StyledText</i> widget displays a line, it will ask
+ its <i>LineBackgroundListener</i> for the line&#146;s background color. </li>
+</ul>
+
+<p>The <i>StyledText</i> widget supplies default implementations for all of the above
+objects. Therefore, you can supply any combination of the above components. For example,
+you could supply just a <i>StyledTextContent</i> implementation and use the <i>StyledText</i>
+widget&#146;s default <i>LineStyleListener</i> and <i>LineBackgroundListener</i>.</p>
+
+<h2>Implementing a StyledTextContent</h2>
+
+<h3>StyledTextContent Applicability</h3>
+
+<p>One of the main reasons to provide a content implementation for the <i>StyledText</i>
+widget is to avoid data duplication. If the text that is to be displayed by the <i>StyledText</i>
+widget is already stored and maintained in an object, you can eliminate data duplication
+by providing a content implementation. </p>
+
+<p>Providing your own <i>StyledTextContent</i> implementation will also give you more
+flexibility since you will have direct access to the text content. For example, you may
+want to manipulate the text independently of the widget. </p>
+
+<h3>StyledTextContent Method Overview</h3>
+
+<p>The <i>StyledTextContent </i>interface defines the protocol that is used by the <i>StyledText</i>
+widget to get information about the text content it should display. The interface contains
+all the methods that must be implemented in order to supply your own content
+implementation. </p>
+<i>
+
+<p>void addTextChangeListener(TextChangeListener listener)</i>
+
+<dir>
+ <p>This method is called by the <i>StyledText </i>widget in order to register itself as a
+ listener for content changes. The <i>StyledTextContent</i> implementer must store <i>TextChangeListeners
+ </i>and notify these listeners when content changes occur. Notification occurs in two
+ steps. First a <i>TextChangingEvent</i> should be sent when text content is about to
+ change and then a <i>TextChangedEvent</i> should be sent when the text content has
+ changed. Notification should occur in the <b>replaceTextRange</b> method (discussed
+ below).</p>
+</dir>
+
+<address>
+ int getCharCount()
+</address>
+
+<dl>
+ <dd>This method should return the number of characters in the text content. </dd>
+</dl>
+<i>
+
+<p>String getLine(int lineIndex)</i>
+
+<dir>
+ <p>This method should return the line at the given <i>lineIndex</i> without the line
+ delimiter.&nbsp; Line indexes are zero-based. For example:</p>
+ <pre><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line delimiter = &quot;\r\n&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; text content = &quot;Line 1\r\nLine2\r\nLine 3&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><i>getLine(0)</i><tt> should answer &quot;Line 1&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><i>getLine(2)</i><tt> should answer &quot;Line 3&quot;</tt></pre>
+</dir>
+<i>
+
+<p>int getLineAtOffset(int offset)</i>
+
+<dir>
+ <p>This method should return the index of the line at the given character <i>offset</i>.
+ Character offsets are zero-based.&nbsp; For example:</p>
+ <pre><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line delimiter = &quot;\n&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; text content = &quot;Line 1\nLine2\nLine 3&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><i>getLineAtOffset(6)</i><tt> should answer 0
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><i>getLineAtOffset(7)</i><tt> should answer 1</tt></pre>
+</dir>
+<i>
+
+<p>int getLineCount()</i>
+
+<dir>
+ <p>This method should return the number of lines in the text content.&nbsp;
+ For example:</p>
+ <pre><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line delimiter = &quot;\n&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; text content = &quot;Line 1\nLine2\nLine 3&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><i>getLineCount()</i><tt> should answer 3</tt></pre>
+</dir>
+<i>
+
+<p>String getLineDelimiter()</i>
+
+<dir>
+ <p>This method should return the line delimiter that should be used when
+ inserting new lines (i.e., via the keyboard) into the text content.</p>
+</dir>
+<i>
+
+<p>int getOffsetAtLine(int lineIndex)</i>
+
+<dir>
+ <p>This method should return the character offset of the first character
+ for the given <i>lineIndex</i>. Character offsets are zero-based.&nbsp; For example:</p>
+ <pre><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line delimiter = &quot;\r\n&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; text content = &quot;Line 1\r\nLine2\r\nLine 3&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><i>getOffsetAtLine(1)</i><tt> should answer 8
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><i>getOffsetAtLine(2)</i><tt> should answer 15</tt></pre>
+</dir>
+<i>
+
+<p>String getTextRange(int start, int length)</i>
+
+<dir>
+ <p>This method should return the text for the given range. The range begins
+ at character offset <i>start</i> and continues <i>length</i> characters. For example:</p>
+ <pre><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; text content = &quot;Line 1\r\nLine2\r\nLine 3&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><i>getTextRange(3,8)</i><tt> should answer &quot;e 1\r\nLin&quot;</tt></pre>
+</dir>
+<i>
+
+<p>void removeTextChangeListener(TextChangeListener listener)</i>
+
+<ul>
+ <p>This method should remove a registered <i>TextChangeListener.</i> The
+ listener will no longer be notified of content changes.</p>
+</ul>
+<i>
+
+<p>void replaceTextRange(int start, int length, String newText)</i>
+
+<dir>
+ <p>This method should replace the given text range (beginning at offset <i>start</i>
+ and continuing for <i>replaceLength</i> characters) with <i>newText</i>. Before
+ the text update occurs, the <i>StyledTextContent</i> implementor should notify
+ its registered <i>TextChangeListeners</i> of the pending change. Notification
+ should occur via the <i>TextChangingEvent</i>.</p>
+ <dir> <tt>
+ <pre><font COLOR="#000080">public class</font> TextChangingEvent <font COLOR="#000080">extends</font> TypedEvent {
+<font
+COLOR="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int</font> newCharCount; <font
+COLOR="#800000">// the length of the new text
+</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font
+COLOR="#000080">public int</font> newLineCount; <font COLOR="#800000">// the number of new lines to be inserted
+</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font
+COLOR="#000080">public</font> String newText;&nbsp;&nbsp;&nbsp;&nbsp; <font COLOR="#800000">// the text to be inserted
+</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font
+COLOR="#000080">public int</font> replacedCharCount; <font COLOR="#800000">// the length of the text to be replaced
+</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font
+COLOR="#000080">public int</font> replacedLineCount; <font COLOR="#800000">// the number of lines to be replaced
+</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font
+COLOR="#000080">public int</font> start; <font COLOR="#800000">// the start offset of the text to be replaced
+</font>}</pre>
+ </tt></dir>
+ <p>Note that <i>newLineCount<b> </b></i>and <i>replacedLineCount<b>
+ </b></i>should indicate the number of lines in the text to be inserted and the number of lines
+ in the text to be replaced, respectively. For example:</p>
+</dir>
+<div align="center"><center>
+
+<table BORDER="1" CELLSPACING="2" BORDERCOLOR="#000000" CELLPADDING="7" WIDTH="576">
+ <tr>
+ <td WIDTH="22%" VALIGN="TOP"><p ALIGN="CENTER"><font FACE="Courier New" SIZE="2"><i>replaced
+ text</i></font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><i><p ALIGN="CENTER">inserted
+ text</i></font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><i><p ALIGN="CENTER">replacedLineCount</i></font></td>
+ <td WIDTH="22%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><i><p ALIGN="CENTER">newLineCount</i></font></td>
+ </tr>
+ <tr>
+ <td WIDTH="22%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">&quot;&quot;</font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">&quot;\n&quot;</font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">0</font></td>
+ <td WIDTH="22%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">1</font></td>
+ </tr>
+ <tr>
+ <td WIDTH="22%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">&quot;\n\n&quot;</font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">&quot;a&quot;</font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">2</font></td>
+ <td WIDTH="22%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">0</font></td>
+ </tr>
+ <tr>
+ <td WIDTH="22%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">&quot;a&quot;</font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">&quot;\n\n&quot;</font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">0</font></td>
+ <td WIDTH="22%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">2</font></td>
+ </tr>
+ <tr>
+ <td WIDTH="22%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">&quot;\n&quot;</font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">&quot;&quot;</font></td>
+ <td WIDTH="28%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">1</font></td>
+ <td WIDTH="22%" VALIGN="TOP"><font FACE="Courier New" SIZE="2"><p ALIGN="CENTER">0</font></td>
+ </tr>
+</table>
+</center></div>
+
+<dir>
+ <p>After the text content is updated, the <i>StyledTextContent </i>implementor
+ should notify its registered <i>TextChangeListeners</i> that the change is complete.
+ Notification should occur via the <i>TextChangedEvent. </i>When the StyledText widget
+ receives this event, it will update the widget to reflect the change. The <i>TextChangedEvent</i>
+ does not contain any data since all the information about the change is included in the <i>TextChangingEvent</i>.
+</p>
+</dir>
+
+<p><em>void setText(String newText)</em><font FACE="Courier New"
+SIZE="2"> </font>
+
+<dir>
+ <p>This method replaces the entire existing text with <i>newText</i>. Use
+ this method to initially specify the text content.</p>
+</dir>
+
+<p>Note that the <i>StyledTextContent</i> implementation does not deal with
+text styles. It is only responsible for managing the text content.
+The <i>LineStyleListener</i> and <i>LineBackgroundListener </i>objects manage style information. When
+you implement a <i>StyledTextContent</i>, you are not required to implement a <i>LineStyleListener</i>
+or a <i>LineBackgroundListener</i>. &nbsp; <em>StyledText's</em> default implementations
+of <em>LineStyleListener</em> and <em>LineBackgroundListener</em> will not change style
+information when a content change occurs.&nbsp; Styles for existing text will remain as
+before the content change and new text will not be assigned any styles. If a content
+change requires style changes, you can use the <b>replaceStyleRanges</b> (new since Eclipse 2.0) and
+<b>setStyleRange</b> API to update the style information. When to update style information is
+discussed below in the &quot;Text
+Content/Style Update Processing&quot; section</p>
+
+
+<h3>StyledTextContent Rules</h3>
+
+<p>It is up to the <i>StyledTextContent</i> implementation to decide which
+line delimiters it will recognize in order to determine the lines that are represented in
+a text string. The default <i>StyledTextContent</i> implementation that is supplied with
+the <i>StyledText</i> widget recognizes any combination of &quot;\n&quot;,
+&quot;\r\n&quot;, and &quot;\r&quot; as line delimiters. Doing so ensures that strings
+created with different line delimiters are interpreted correctly. Note that the delimiter
+for a specific platform comes into play when new lines are inserted. When inserting text,
+you want the new lines to be created with the platform line delimiter so that copy and
+paste operations between platform applications work properly. You specify the delimiter to
+use when inserting new text via the <b>getLineDelimiter </b>method. </p>
+
+
+<p>As discussed above, when a text change occurs, the <i>StyledTextContent</i>
+needs to send a <i>TextChangingEvent</i> and a <i>TextChangedEvent</i> to notify the <i>StyledText</i>
+widget about the text change. Text changes can occur in one of three ways:
+
+<ol TYPE="A">
+ <li>via the <i>StyledText</i> widget because of user input (e.g., keyboard
+ entry)</li>
+ <li>via the <i>StyledText</i> widget because API was called (e.g., <b>replaceTextRange
+ </b>or <b>paste</b>)</li>
+ <li>via your <i>StyledTextContent</i> implementation (i.e., your application
+ changes text independent of the <i>StyledText</i> widget)</li>
+</ol>
+
+<p>The following diagram indicates how these text changes occur within the <em>StyledText</em>
+widget.&nbsp; The boxes in gray are discussed in length in our <a
+HREF="http://www.eclipsecorner.org/articles/StyledText%201/article1.html">first article</a>,
+&quot;Getting Your Feet Wet With the SWT StyledText Widget&quot;.&nbsp; For this article,
+we will expand upon the processing that occurs in Step 4, &quot;Text Content/Style Update&quot;.</p>
+
+<p ALIGN="CENTER"><img src="TextChanges.gif" width="420" height="995"
+alt="TextChanges.gif (12968 bytes)"></p>
+<div align="center"><b>Figure 1 &#150; Text Change Processing</b> </div>
+
+<h4>Text Content/Style Update Processing </h4>
+
+
+<p>The Text Content/Style Update process begins with the <em>StyledText</em>
+widget or your application (for Case C) calling the<strong> replaceTextRange(int, int,
+String)</strong> method.&nbsp; This method is the time and place to send the text change
+events and to update your text content.&nbsp;&nbsp; How processing should occur is
+depicted in the diagram below. The light gray boxes represent the processing that your <i>StyledTextContent</i>
+implementation should perform, while the dark gray boxes represent the processing that
+occurs in the <i>StyledText</i> widget.</p>
+<font FACE="Courier New" SIZE="2">
+
+<p ALIGN="CENTER">&nbsp;<img src="TextUpdate.gif" width="607" height="796"
+alt="TextUpdate.gif (11618 bytes)"></p>
+</font>
+<div align="center"><b>Figure 2 &#150; Text Content/Style Update Processing</b> </div>
+<p>The text content/style update process is started by sending the <i>TextChangingEvent</i>
+(1). In response to this event, the <i>StyledText</i> widget prepares for the text change
+by posting screen update operations for the area of the text change (2). After the <i>TextChangingEvent</i>
+is sent, the application should update its text content to reflect the change (3), apply
+style changes (4), and send the <i>TextChanged</i> event (5). When the <i>StyledText</i>
+widget receives the <i>TextChangedEvent</i> it will update itself in accordance with the
+change (e.g., scroll bars will be adjusted) and the text change will be visibly presented
+in the <i>StyledText</i> widget (6). If you don't supply a <i>LineStyleListener</i>
+as described below, part of the text change process will include updating the
+style ranges to accommodate the text change (occurs in Step 2). As discussed in the first article
+<a HREF="http://www.eclipsecorner.org/articles/StyledText%201/article1.html">
+&quot;Getting Your Feet Wet With the SWT StyledText Widget&quot;</a>, the StyledText widget maintains
+styles for existing text and does not apply styles for any new text. If the new text requires
+styles or the existing styles need to be modified, this should be done in Step 4. </p>
+
+<p>Note that the rules that apply to updating styles also apply to updating line background colors. If you do
+not supply a <i>LineBackgroundListener</i> as described below, part of the text change process will
+include updating line background colors if the text change includes adding or removing lines. As with styles,
+the <i>StyledText</i> widget maintains existing line background colors. If the line
+background colors need to be updated as a result of the text change, this should be done in Step 4.
+</p>
+
+<p>Note that between the time that your <em>StyledTextContent</em>
+implementation sends the <i>TextChangingEvent</i> and the <i>TextChangedEvent</i>, your
+implementation should not use API that will cause a scroll operation to occur or that will
+cause posted paints to be flushed. The <i>StyledText</i> widget also does not handle
+nested text content updates, so when processing text content changes, the application
+should not use API that will cause text updates to occur.</p>
+
+<p>The <i>StyledText</i> widget only modifies the cursor location when text
+is changed via user input. In all other instances (i.e., Case B and Case C in Figure 1
+above), if the application wishes the cursor location to change as a result of the text
+content change, the following methods can be used to set the cursor location to an offset
+and to make that offset visible: </p>
+<tt>
+
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setSelection(offset, 0)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; showSelection()</pre>
+</tt>
+
+<h3>StyledTextContent Considerations</h3>
+
+<p>When implementing a <i>StyledTextContent</i>, the algorithm for updating
+the text content when modifications occur must be fast. If it is not, you will experience
+sluggishness during typing (i.e., as your <i>StyledTextContent</i> attempts to deal with
+the text change). Similarly, the algorithm for returning the text for a line should be
+fast. If it is not, you will experience sluggishness during scrolling. It is also
+important to ensure that your implementation scales well. When the text content gets
+larger, handling of text replace operations and answering lines should not be adversely
+affected from a performance standpoint. </p><p>
+
+For an example of a <i>StyledTextContent</i> implementation, refer to the class <i>org.eclipse.swt.custom.DefaultContent</i>.
+<i>DefaultContent</i> is the content implementation that the <i>StyledText</i> widget uses
+by default. </p>
+
+
+<h3>StyledTextContent Implementation Validation</h3>
+
+<p>The following Java&trade; class can be used to test a <i>StyledTextContent</i>
+implementation. When executed, the class will run through a number of test scenarios that
+exercise the <i>StyledTextContent</i> interface. To use the class, import it into the
+package that contains your <i>StyledTextContent</i> implementation. Then specify the fully
+qualified name of your implementation class as an argument to the<i>
+StyledTextContentSpec&#146;s</i> <b>main</b> method.&nbsp; As each test scenario is
+executed, <b>System.out</b> will be updated to indicate whether or not each test
+passed.&nbsp; Note that this class is designed to work with a <em>StyledTextContent</em>
+implementation that supports &quot;\r&quot;, &quot;\n&quot;, and '\r\n&quot; as line
+delimiters.</p>
+
+<p><a HREF="StyledTextContentSpec.java">StyledTextContentSpec.java</a> <br>
+
+</p>
+
+
+<h2>Implementing a LineStyleListener</h2>
+
+<h3>LineStyleListener Applicability</h3>
+
+<p>One of the main reasons to use a customized <i>LineStyleListener</i> is
+to support on-demand line styling. Instead of using the <b>replaceStyleRanges</b> (new in Eclipse 2.0),
+<b>setStyleRanges</b> and <b>setStyleRange</b>
+methods to statically set the style information for the widget&#146;s text,
+style information can be provided dynamically on a line-by-line basis. </p>
+
+<p>If styles are determined based on the actual text content, on-demand line styling can
+be used since the text of each line is passed to the <i>LineStyleListener</i>. Text styles
+that are used for syntax highlighting can typically be provided dynamically. For example,
+except for block comments, all of Java&#146;s syntactic elements occur on one line. It
+would be more efficient to use a dynamic, customized<i> LineStyleListener </i>vs. the <i>StyledText</i>
+API to implement Java syntax highlighting. If you used the <i>StyledText</i> API, style
+information would be maintained statically and any time text changes occurred this
+information would have to be updated (e.g., via the <b>setStyleRange</b> API). Using the <i>StyledText</i>
+API would also require you to parse the entire text up front. If on-demand line styling
+were used, the text would be parsed on an as needed basis, as it is displayed, thus
+improving initial load time. </p>
+
+<p>Another reason to use a customized <i>LineStyleListener</i> is to avoid duplicating
+data. When the <i>StyledText</i> methods <b>replaceStyleRanges</b>, <b>setStyleRanges</b> and <b>setStyleRange </b>are
+called, the <i>StyledText</i> widget will cache the <i>StyleRange</i> objects that are
+supplied as input parameters. However, if the information needed to construct style ranges
+is already stored by an object in your application, introducing a <i>LineStyleListener</i>
+that uses this object may be beneficial. </p>
+
+<p>You may also use a customized <i>LineStyleListener</i> in order to provide
+application-specific text coloring behavior. By default, when text changes occur in the <i>StyledText</i>
+widget, text colors are updated as follows:
+
+<ol>
+ <ol>
+ <li>If text is deleted, its associated style will also be deleted.</li>
+ <li>If new text is inserted, it&#146;s associated style will be null (i.e.,
+ the text background color will be the widget background color, the text foreground color
+ will be the widget foreground color, and the text font style will be the widget font
+ style).</li>
+ </ol>
+</ol>
+
+<dir>
+ <dir>
+ <dir>
+ <p>Note: A text replace operation is treated as a text delete operation
+ followed by a text insert operation.</p>
+ </dir>
+ </dir>
+</dir>
+
+<p>The <i>StyledText</i> widget does not make any assumptions about how to
+apply styles when text is inserted or deleted because how to update the styles will depend
+on how the <i>StyledText</i> widget is being used. For example, if the widget is being
+used to support syntax highlighting for a source code editor, coloring will occur only
+when inserted text completes a keyword. Whereas, if the widget is being used to support
+text attributes for a word processor, inserted text will most likely take on the style
+values of the characters adjacent to the text. To provide specific text style updating
+behavior you can introduce your own <i>LineStyleListener</i>.</p>
+
+
+<h3>LineStyleListener Method Overview</h3>
+
+<p>The <i>LineStyleListener </i>interface defines the protocol that is used
+by the <i>StyledText</i> widget to get the styles of a displayed line.</p>
+<i>
+
+<p>void lineGetStyle (LineStyleEvent event) </i>
+
+<dir>
+ <p>The <b>lineGetStyle</b> method is called when a line is about to be
+ drawn in order to get the line&#146;s style information. When the method is called, the <i>LineStyleEvent</i>
+ has two input fields set - <b>LineStyleEvent.lineOffset</b> contains the start offset of
+ the line and&nbsp; <b>LineStyleEvent<font COLOR="#000080">.</font>lineText</b> contains
+ the text of the line. It is your responsibility to set the output field, <b>LineStyleEvent.styles</b>.
+ This field defines the StyleRanges for the text line. The widget uses the StyleRanges for
+ measuring and rendering text when the <b>lineGetStyle</b> listener method returns. Each <i>StyleRange</i>
+ object describes the foreground color, background color and font style for a range of text
+ in the particular line your listener was called for. The range start offset is relative to
+ the beginning of the document, not the beginning of the line.</p>
+</dir>
+
+<h3>LineStyleListener Rules</h3>
+
+<p>If you implement your own <i>LineStyleListener </i>to supply line styles
+you may no longer use the <b>replaceStyleRanges</b>, <b>setStyleRange, setStyleRanges</b> or <b>getStyleRange</b>
+API. You can supply style information using a <i>LineStyleListener </i>or the API, but not
+both. </p><p>
+
+Ideally, you only have to use the line text and offset information supplied in the <i>LineStyleEvent</i>
+passed in to the <b>lineGetStyle</b> listener method to calculate line style information.
+However, it may be necessary for you to store style information and simply look up the
+styles when your listener method is called. In this case, you will have to update the
+style information when text changes occur. To do this, you can listen to the <b>extended
+modify event</b> (described in detail in our <a
+HREF="http://www.eclipsecorner.org/articles/StyledText%201/article1.html">first article</a>).
+The <b>extended modify event</b> is sent after the widget text has been updated, but
+before the screen updates take effect. In this manner, inserted text can immediately use
+any styles that have been specified. Note that it does not make sense to use the <b>modify
+event</b> to update styles in this manner since the <b>modify event</b> does not contain
+any specific information about the text change (e.g., character offset of the inserted
+text).&nbsp;<a NAME="StyleRedraw"></a> &nbsp; </p>
+
+<p>If, as a result of the text change, style information before or after the lines
+modified by the text change is changed, you will have to redraw the affected area of the
+widget. For example, if you are using the <i>StyledText</i> widget for java syntax
+highlighting in a source code editor, deleting the beginning of a block comment (i.e.,
+&quot;/*&quot;) will affect lines after the line on which the text change occurred. In
+this instance, it would be the application&#146;s responsibility to redraw the other
+comment lines. The <i>StyledText</i> widget will only update text lines based on the text
+change that occurred.</p>
+
+<p>The <i>StyledText</i> widget provides two redraw methods to support the above
+scenarios: </p>
+<tt>
+
+<pre> <font COLOR="#000080">public void</font> redrawRange(<font COLOR="#000080">int</font> start, <font
+COLOR="#000080">int</font> length, <font COLOR="#000080">boolean</font> clearBackground)
+ <font
+COLOR="#000080">public void</font> redraw(<font COLOR="#000080">int</font> x, <font
+COLOR="#000080">int</font> y, <font COLOR="#000080">int</font> width, <font
+COLOR="#000080">int</font> height, <font COLOR="#000080">boolean</font> all)</pre>
+</tt>
+
+<p>The first, <b>redrawRange</b>, lets you specify the exact text range to
+redraw using character offsets. The second method, <b>redraw</b>, is the standard SWT
+redraw method that redraws a pixel based rectangle in the widget. SWT provides another
+redraw method, which is not shown here. It does not have any arguments and redraws the
+whole widget. You can use this method, but it will cause the text to flash since it
+performs a full clear and redraw of the widget.</p>
+
+<h3>LineStyleListener Considerations</h3>
+
+<p>If you implement your own <i>LineStyleListener</i>, keep in mind that
+the listener is called every time a line is rendered or scrolled and when a key is
+pressed. It is therefore important that the <b>lineGetStyle</b> method is fast and that it
+scales well for use with large amounts of text. If you experience a lag when typing and
+scrolling, your <i>LineStyleListener </i>implementation is too slow. If typing and
+scrolling is slow at the end of the text, your algorithm does not scale well. Note that
+unresponsive typing may also be caused by slow processing in <i>VerifyListeners</i>, <i>ModifyListeners</i>
+or <i>ExtendedModifyListeners </i>(see our <a
+HREF="http://www.eclipsecorner.org/articles/StyledText%201/article1.html">first article</a>
+for more information about verify and modify listeners). </p>
+
+<p>If you implement a <i>LineStyleListener </i>and store the <i>StyleRange</i> objects
+(instead of calculating them on demand) it is advisable to merge adjacent styles that have
+the same style data. Merging StyleRanges improves the performance of text measuring and
+rendering in the <i>StyledText</i> widget because fewer <i>StyleRange</i> objects have to
+be processed. </p>
+
+<p><a NAME="LineStyleListenerRedraw"></a>If you redraw text during the <b>extended
+modified event</b>, make sure that you only redraw text ranges that actually have new
+styles. Unnecessary refresh operations can cause flash and degrade performance. See the
+discussion in the &quot;Text Refresh&quot; section of our <a
+HREF="http://www.eclipsecorner.org/articles/StyledText%201/article1.html">first article</a>
+for more information about what flash means and what causes it. </p>
+
+<p>For an example of a <i>LineStyleListener</i> implementation, refer to the class <i>org.eclipse.swt.custom.DefaultLineStyler</i>.
+This class&#146; implementation of the <i>LineStyleListener</i> interface is the
+implementation that the <i>StyledText</i> widget uses by default. The class illustrates
+the concepts discussed above, including how to merge neighboring styles </p>
+
+<h3>LineStyleListener Example</h3>
+
+<p>The following example is the <b>lineGetStyle</b> method from a <i>LineStyleListener
+ </i>that implements a simple Java syntax coloring strategy. The method constructs
+ the <em>StyleRange</em> objects dynamically (i.e., every time they are requested)
+ and merges similar styles for improved rendering performance.&nbsp; The example
+ method code is taken from the SWT Java Syntax Viewer example, which is part
+ of the example plugins that can be downloaded with the Eclipse SDK.&nbsp; The
+ example code can be found in the plugins subdirectory<em> </em>org.eclipse.swt.examples.&nbsp;
+ Three classes comprise the example - <em>JavaViewer</em>, <em>JavaLineStyler</em>
+ and <em>JavaScanner</em>. &nbsp; The <em>JavaScanner</em> class is an inner
+ class of <em>JavaLineStyler</em>.</p>
+
+<p>The <i>JavaScanner</i> class implements a Java syntax scanner. The <i>JavaScanner</i>
+public API includes the methods: </p>
+<tt>
+
+<pre> <font COLOR="#000080">void</font> setRange(String)
+ <font COLOR="#000080">int</font> nextToken()&nbsp;
+ <font
+COLOR="#000080">int</font> getStartOffset()
+ <font COLOR="#000080">int</font> getLength()</pre>
+</tt>
+
+<p>as well as constants for the different Java syntax elements that need
+highlighting. In addition, the method <b>Color getColor(int)</b> returns a <i>Color</i>
+object for a given Java syntax constant. </p>
+
+<p>In the example, we set the text of the line we want to syntax scan in the Java scanner.
+We apply different colors to each token and keyword tokens are given a font style of bold.
+If the color for a token differs from the widget foreground color or if the token is a
+keyword (in which case a <i>StyleRange</i> would be necessary in order to specify a bold
+font style), we create a new <i>StyleRange</i> object for that element. If the previous <i>StyleRange</i>
+object has the same foreground color, background color and font style, it is considered
+similar and the two ranges can be merged. Merging StyleRanges improves the performance of
+text measuring and rendering in the <i>StyledText</i> widget.</p>
+
+<p>The lineGetStyle method also includes special processing for handling the <i>StyleRanges</i>
+that are created for keywords. In Java code, multiple keywords are often grouped together
+(e.g., &quot;public static final int&quot;). To minimize the number of <i>StyleRanges</i>
+that are created in this instance, spaces between the keywords are assigned a bold font
+style. This strategy will lead to only one <i>StyleRange</i> for a group of keywords vs.
+multiple <i>StyleRanges</i> (i.e., one for each keyword and one for each space between the
+keywords).&nbsp; The strategy will also minimize the number of font style changes that
+occur during rendering (i.e., the number of changes from the normal font to the bold
+font).</p>
+
+<p>When the complete line has been scanned and processed, the styles are copied into the <i>LineStyleEvent</i>.
+
+
+<dir>
+ <dir>
+ <tt><pre><font COLOR="#000080">public</font> <font COLOR="#000080">void</font> lineGetStyle(LineStyleEvent event) {
+ Vector styles = <font
+COLOR="#000080">new</font> Vector();
+
+<font COLOR="#800000"> // If the line is part of a block comment, create one style for the entire line.
+</font> <font
+COLOR="#000080">if</font> (inBlockComment(event.lineOffset, event.lineOffset + event.lineText.length())) {
+ styles.addElement(new StyleRange(event.lineOffset, event.lineText.length(), getColor(COMMENT), <font
+COLOR="#000080">null</font>));
+ event.styles = <font COLOR="#000080">new</font> StyleRange[styles.size()];
+ styles.copyInto(event.styles);
+ <font
+COLOR="#000080">return</font>;
+ }
+
+<font COLOR="#000080"> int</font> token;
+ StyleRange lastStyle;
+ Color defaultFgColor = ((Control)event.widget).getForeground();
+ scanner.setRange(event.lineText);
+ token = scanner.nextToken();
+ <font
+COLOR="#000080">while</font> (token != EOF) {
+ <font COLOR="#000080">if</font> (token == OTHER) {
+<font
+COLOR="#800000"> // no syntax highlighting necessary
+</font> } <font
+COLOR="#000080">else</font> <font COLOR="#000080">if</font> ((token != WHITE) {
+<font
+COLOR="#800000"> // Only create a style if the token color is different than the widget's default foreground color and the
+ // token&#146;s fontStyle is not bold.
+</font> Color color = getColor(token);
+<font
+COLOR="#000080"> if</font> ((!color.equals(defaultFgColor)) || (token == KEY)) {
+ StyleRange style = new StyleRange(scanner.getStartOffset() + event.lineOffset, scanner.getLength(), color, <font
+COLOR="#000080">null</font>);
+ <font COLOR="#000080">if</font> (token == KEY) {
+ style.fontStyle = SWT.BOLD;
+ }
+ <font
+COLOR="#000080">if</font> (styles.isEmpty()) {
+ styles.addElement(style);
+ } <font
+COLOR="#000080">else</font> {
+<font COLOR="#800000"> // Merge similar styles.
+</font> lastStyle = (StyleRange)styles.lastElement();
+ <font
+COLOR="#000080">if</font> (lastStyle.similarTo(style) &amp;&amp; (lastStyle.start + lastStyle.length == style.start)) {
+ lastStyle.length += style.length;
+ } <font
+COLOR="#000080">else</font> {
+ styles.addElement(style);
+ }
+ }
+ }
+ } <font
+COLOR="#000080">else if</font> (!styles.isEmpty()) &amp;&amp; ((lastStyle=(StyleRange)styles.lastElement()).fontStyle == SWT.BOLD)) {
+<font
+COLOR="#800000"> // Have the white space take on the bold style before it to minimize the number of style ranges.
+</font> <font
+COLOR="#000080">int</font> start = scanner.getStartOffset() + event.lineOffset;
+<font
+COLOR="#800000"> </font><font COLOR="#000080">if</font> (lastStyle.start + lastStyle.length == start) {
+<font
+COLOR="#800000"> </font>lastStyle.length += scanner.getLength();
+ }
+ }
+ token= scanner.nextToken();
+ }
+ event.styles = new StyleRange[styles.size()];
+ styles.copyInto(event.styles);
+}
+</pre>
+ </tt></dir>
+</dir>
+
+
+<h2>Implementing a LineBackgroundListener</h2>
+
+<h3>LineBackgroundListener Applicability</h3>
+
+<p>As with the LineStyleListener, one reason to use a customized <i>LineBackgroundListener</i>
+is to avoid duplicating data. When the <i>StyledText</i> method <b>setLineBackground</b>
+is called, the <i>StyledText</i> widget will cache the colors for the specified lines. If
+this information is already stored by an object in your application, introducing a <i>LineBackgroundListener</i>
+that interacts with this object will eliminate data duplication. </p>
+
+<p>You may also use a customized <i>LineBackgroundListener</i> in order to provide
+application-specific line background coloring behavior. The <i>StyledText</i> widget
+maintains line background colors relative to text lines. By default, when text changes
+occur in the <i>StyledText</i> widget, line background colors are updated as follows:
+
+<ol>
+ <ol>
+ <li>If a line is deleted, its associated line background color will also be deleted.</li>
+ <li>If a new line is inserted, its associated line background color will be null (i.e., the
+ widget background color) and line background colors for existing lines of text are
+ unchanged.</li>
+ </ol>
+</ol>
+
+<p>For example, in the window below, a line background color of gray is used to emphasize
+the import statements. If text lines are inserted or deleted, you would want the line
+background color that is associated with the block of import statements to be maintained. </p>
+
+<p ALIGN="CENTER"><img SRC="Image8.gif" WIDTH="427" HEIGHT="169"></p>
+<p>
+
+<font SIZE="2"><br>
+</font>Your application may want line background colors to be updated
+differently when text changes occur. For example, if you want the background of every
+other line to be gray (e.g., in order to facilitate reading tabulated text), you would
+need to &quot;shift&quot; line background colors as lines are deleted or inserted. You
+could easily support this behavior by implementing your own <i>LineBackgroundListener</i>.</p>
+
+
+<h3>LineBackgroundListener Method Overview</h3>
+
+<p>The <i>LineBackgroundListener</i> interface defines the protocol that is
+used by the <i>StyledText</i> widget to get the line background colors to use when
+displaying the text. The interface, <i>LineBackgroundListener</i>, contains the methods
+that must be implemented in order to supply your own line background color implementation.
+</p>
+<i>
+
+<p>void lineGetBackground(LineBackgroundEvent event)</i>
+
+<dir>
+ <p>This method is called when a line is to be drawn in order to get the line&#146;s
+ background color. <i>LineBackgroundEvent</i> will contain the start offset, <b>lineOffset</b>,
+ and the text, <b>lineText</b>, of the line to be drawn. Fill in the background color in
+ the <b>lineBackground</b> field. A value of null indicates that the default widget
+ background should be used for the line. <br>
+ &nbsp;</p>
+</dir>
+
+<p>In the following example, a LineBackgroundListener is used to color the background of
+every other line to light gray. The method assumes that we have a cache of colors indexed
+by RGB value.
+
+<dir>
+ <dir>
+ <tt><pre><font COLOR="#000080">public void</font> lineGetBackground(LineBackgroundEvent event) {
+ <font
+COLOR="#000080">int</font> line = ((StyledText) event.widget).getLineAtOffset(event.lineOffset);
+ <font
+COLOR="#000080">if</font> ((line % 2) == 1) {
+ event.lineBackground = (Color)colors.get(<font
+COLOR="#000080">new</font> RGB(222, 222, 222));
+ }
+}</pre>
+ </tt></dir>
+</dir>
+
+
+<h3>LineBackgroundListener Rules</h3>
+
+<p>Line background colors are drawn for the width of the widget, not the
+width of the text. If a text background color is defined (i.e., via a <i>StyleRange</i>),
+this color will overlay the line background color. </p>
+
+<p>If you implement your own <i>LineBackgroundListener, </i>the following <i>StyledText</i>
+methods are not applicable and should not be used since your <i>LineBackgroundListener</i>
+will be maintaining and storing line background colors:
+
+<dir>
+ <dir>
+ <p><tt><font COLOR="#000080">public</font> Color getLineBackground(<font COLOR="#000080">int</font>
+ index)</tt><font SIZE="2"> <br>
+ </font><tt><font COLOR="#000080">public</font> <font COLOR="#000080">void</font>
+ setLineBackground(<font COLOR="#000080">int</font> startLine, <font COLOR="#000080">int</font>
+ lineCount, Color background)</tt> </p>
+ </dir>
+</dir>
+
+
+<h3>LineBackgroundListener Considerations</h3>
+
+<p>When you implement a <i>LineBackgroundListener</i>, since the <b>setLineBackground</b>
+API is no longer available, you will be responsible for refreshing line background colors
+within the widget. For example, if a text content change alters line background colors for
+lines other than the lines on which the text change occurred, it would be the
+LineBackgroundListener&#146;s responsibility to redraw these lines. You can refresh line
+background colors by using the <b>redraw(int x, int y, int width, int</b><b>height, boolean all)</b> method. The input parameters
+to this method specify a pixel-based rectangle. You can use other <i>StyledText</i> API
+(e.g., <b>getLocationAtOffset</b>) to calculate the rectangle for a line. </p><p>
+
+<a NAME="LineBackgroundListenerRedraw"></a>When you implement a <i>LineBackgroundListener</i>
+you should make sure that you only initiate line background updates when necessary.
+Unnecessary refreshing of lines will cause flash and degrade performance of the <i>StyledText</i>
+widget, as discussed in the Text Refresh section of our <a
+HREF="http://www.eclipsecorner.org/articles/StyledText%201/article1.html">first article</a>.</p><p>
+
+For an example of how to implement a <i>LineBackgroundListener</i>, refer to the class <i>org.eclipse.swt.custom.DefaultLineStyler</i>.
+The <i>DefaultLineStyler </i>implements the<i> LineBackgroundListener</i> behavior that
+the <i>StyledText</i> widget uses by default.
+
+<dl>
+ <dt>&nbsp;</dt>
+</dl>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+
+</body>
+</html>
diff --git a/ToolIntegration/ToolIntegration.html b/ToolIntegration/ToolIntegration.html
new file mode 100644
index 0000000..13624e3
--- /dev/null
+++ b/ToolIntegration/ToolIntegration.html
@@ -0,0 +1,417 @@
+<html>
+<head>
+<title>The Eclipse Strategy</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="../../default_style.css">
+</head>
+
+<body bgcolor="#FFFFFF" text="#000000">
+&nbsp;
+<div align="right">&nbsp; <font face="Times New Roman, Times, serif" size="2">Copyright
+ &copy; 2001 Object Technology International, Inc.</font> </div>
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table>
+<h1> <img src="../../images/Idea.jpg" height=86 width=120 align=CENTER></h1>
+<center>
+ <h1> What's the Big Deal about<br>
+ Tool Integration?</h1>
+ </center>
+<center>
+ <h3> What does tool integration mean to ISVs, customers, and the <br>
+ Eclipse Community?</h3>
+ </center>
+<blockquote><b>Summary</b> <br>
+ The Eclipse Platform provides the &quot;integration-ware&quot; to enable the
+ next generation of integrated application development tools. This article is
+ an overview that takes you through the why, how and what of the design, development,
+ and deployment of extensible tool components developed using this technology.
+ <br>
+</blockquote>
+<b>By: Tony Cianchetta</b>
+<p>
+<hr width="100%">
+<h3>Why do we need tool integration?<br>
+</h3>
+<p>The last five years have shown us extraordinary change in the field of application
+ development. There are many implications of this change but the net result has
+ been intense pressure on everything associated with creating runtime solutions
+ in Web time. Figure 1 provides a view of some of those pressures and, as most
+ things in the business world, it begins and ends with the Customer.</p>
+<p>Customers have high expectations set by the functionality provided by modern
+ development tools. They know what integrated tools look like from their use
+ of such integrated suites as Lotus Smart Suites and Microsoft Office. Customers
+ expect to see the same level of integration in their software development tools.</p>
+<p align="center"> <img src="images/pressures.gif" width="555" height="385"><br>
+ Figure 1. Pressures on contemporary software development tools.</p>
+<p>The evolution of e-business from concept to reality has dramatically changed
+ the face of business integration. Surviving on the World Wide Web means application
+ interoperability, and application interoperability means an integrated set of
+ development tools that understand and can maintain the complex relationships
+ between the integrated components that make up a complete application.</p>
+<p>Business Models are changing rapidly due to intense and comprehensive business
+ process reengineering resulting from a desire to leverage the Web. These new
+ business models are often complex and extremely difficult to maintain. In addition,
+ application development must be able to keep pace with changing business needs
+ by supporting integrated tools that allow rapid and iterative development.</p>
+<p>Prescriptive methodologies are often necessary to manage the complexity of
+ application development, and to make development a pragmatic, controllable,
+ and repeatable process. To be effective, the methodology must be appropriate
+ to the customer's domain and development style. Users should be able to select
+ a methodology that can be tightly integrated with the development tools use
+ to create the artifacts of their applications as specified by the methodology.</p>
+<p>Current application development tool suites and IDEs have received mixed reviews
+ from Customers. Tools like IBM VisualAge, Microsoft VisualStudio, SUN Forte
+ for Java, etc., provide rich functionality to support customer application development.
+ But these tool suites have gaps and overlaps in functionality, and can be complex
+ to adopt. Customers' need application development tools that are truly integrated
+ with one another in order to hide this complexity. </p>
+<p align="center"><img src="images/problemSpace.gif" width="580" height="329">
+ <br>
+ Figure 2. What is important to software development customers?</p>
+<p>The software development landscape is simple: software companies are in business
+ to generate revenue by solving some business problem with one or more runtime
+ application. They need to focus their limited resources on their core competencies.
+ They have some level of domain expertise and have chosen some runtime topology,
+ usually dictated by their customers. If they have been around for any significant
+ duration, they probably also have some set of legacy artifacts that they need
+ to reuse. </p>
+<p>As a result, customers are primarily interested in two ends of the software
+ development process: their core business domain and the applications that automate
+ their business processes, and the runtime environment that executes these applications
+ to help run their business. In between are a number of items that are necessary
+ to transform the customer's concept of their business into applications running
+ on some runtime platform. Typically application developers use some development
+ process to manage this transformation. Regardless of what the development process
+ might be, it will typically consist of roles and responsibilities people play
+ to achieve the desired result. Developers playing these roles will use tools
+ to help them fulfill their responsibilities, and create the artifacts of the
+ application that will be hosted on the runtime platform.</p>
+<p>These &quot;customer problem spaces&quot; tend to appear in recurring patterns
+ representing a state of the practice for software development, and effective
+ runtime architectures. Focusing on these recurring patterns introduces an opportunity
+ to better understand the full life-cycle needs of application developers, and
+ to determine what tools they need to create and maintain their applications.
+ The relationships between the artifacts of these applications and runtime architectures
+ also provide an indication of how the tools should be integrated.</p>
+<p>By leveraging these patterns, it is possible to create full life-cycle, end-to-end,
+ integrated tools that allow application developers to focus on their business
+ domain instead of investing in the collection and manual integration of tools
+ supporting their development process.</p>
+<p>For example, consider Figure 3, which provides an overview of the typical technologies
+ involved in a Web based transaction.</p>
+<p align="center"> <img src="images/webTransaction.gif" width="496" height="325"><br>
+ Figure 3. Web development technology choices.</p>
+<p>A typical web-based transaction generally originates from a client, travels
+ through some communication channel to a server, where it is processed and perhaps
+ queued to some backend system for data access or integration with existing applications.
+ The result then travels back through the same path to the originating client.
+</p>
+<p>For most early adopters of web technology the entry point was based on a Business-to-Customer
+ (B2C) focus. Initially, getting a home page developed to tell customers who
+ you were and what you offered was perceived as the goal. Accomplishing this
+ required a certain set of tools and skills and centered on HTML-based information
+ presentation. </p>
+<p>A B2C transaction can be defined as a horizontal slice through the various
+ technology choices shown in Figure 3 to satisfy such a request. These horizontal
+ slices represent a typical pattern for Web applications using static HTML pages.
+ As customer focus shifts from simple, static web page development and they begin
+ to think in terms of surfacing business processes on the web, they migrate to
+ a different, more complex usage scenario. They begin to appear in the Business-to-Business
+ (B2B) space. As their application requirements evolve, the tooling required
+ to support these new requirements must also evolve.</p>
+<p>This might mean a move from HTML-based information presentation to web applications
+ using XML-based information interchange and Web services. B2B applications range
+ in complexity from simple services to complex inter-enterprise business process
+ integration. As natural as the progression from B2C to B2B may seem, the jump
+ in technology and complexity is significant. Sometimes just that one new function
+ point may push the application over the line to a new run time architecture
+ requiring a whole new set of development tools. New tools need to be purchased
+ or developed, and people retrained to use them. These new tools must be seamlessly
+ integrated with existing tools so that customers leverage existing knowledge
+ and development processes while exploiting the capabilities of more complex
+ runtime topologies. </p>
+<p>To make things easier for customers to evolve as an e-Business, tool vendors
+ must change the way they deploy their tools in the marketplace. Tool vendors
+ have traditionally taken a product focus to providing individual tools. The
+ result was that choices in tools revolved around programming language and operating
+ system stacks. </p>
+<p align="center"> <img src="images/currentToolIntegration.gif" width="557" height="398"><br>
+ Figure 4. Individual shrink-wrapped tools require on-site integration by the
+ customer.</p>
+<p>This pretty much left integrating the various tools up to the customer using
+ their own development resources or paying for external consultants to do the
+ work for them. What is required is a tool strategy that is more solution-based,
+ driven by customer usage scenarios. The patterns of customer problem spaces
+ described above can be used to help define these usage scenarios, the runtime
+ architectures that support them, and the tools required to build the applications
+ on the runtimes. Taking a solution-based approach can address gaps and overlaps
+ in tools supporting particular patterns, provide a common view of the application
+ as a whole, and reduce cost in development. </p>
+<h3>So How can Eclipse help?</h3>
+<p>The Eclipse projects provide the necessary &quot;integration-ware&quot; enabling
+ effective tool development and integration. This integration-ware consists of
+ common services that are useful across all tools, and a common set of frameworks
+ for building plug-in extensions. Using Eclipse it is no longer necessary to
+ build the whole tool environment as a single, inflexible, highly coupled IDE
+ where the tool components are often compromises compared to best-of-breed individual
+ tools. Tool integration is based on open APIs and components that provide:</p>
+<p>A common destination to install and integrate tools <br>
+ A central view across all resources and roles providing a base for consistent,
+ effective, efficient, scalable, and end-to-end application development <br>
+ An open, flexible, extensible, standards-based and portable framework for tool
+ integration and interoperability <br>
+ A view of the complete application across all components and the entire team
+ <br>
+ Standard look-and-feel across all plug-in tools <br>
+ Portable, high-performance, platform native look-and-feel <br>
+</p>
+<p align="center"> <img src="images/workbenchIntegration.gif" width="546" height="463"><br>
+ Figure 5. A common workbench with plug-in components.</p>
+<p>By providing a common set of services and frameworks, we hope to eliminate
+ the need for on-site integration of widely diverse tools. This, in turn, will
+ aid our software development customers in focusing their resources on what they
+ do best: providing solutions to their customers. By leveraging existing standards
+ and providing well-defined extension points (APIs), we intend to provide as
+ much flexibility and extensibility as possible.</p>
+<h3>Exactly what is Eclipse and why would I want to use it?<br>
+</h3>
+<p>The Eclipse platform has been developed to provide the base for accessing common
+ services and frameworks. Specialized tool functionality can be provided by separate
+ plug-in components. Tool developers are currently creating plug-in components
+ for new tools, and wrapping their existing tools so they can integrate with
+ Eclipse.</p>
+<p></p>
+<p align="center"> <img src="../../images/workbenchOverview.gif"><br>
+ Figure 6. Workbench + plug-ins = functionality and extensibility.</p>
+<p>The Eclipse platform and some set of plug-ins can be combined to provide a
+ solution for customer scenarios described above. For a full description of the
+ Eclipse projects, visit the <a href="../../index.html" target="_parent">Eclipse
+ Corner</a>, the portal into the Eclipse community and the <a href="../../about_eclipse.html">Eclipse
+ overview</a>.</p>
+<h3>Hasn't the Software Industry tried this before? What's different this time?</h3>
+<p>Yes, sadly, tool integration has been tried many times before. There are lots
+ of tool integration frameworks and standards scattered in the dust. Things like
+ IRDS, PCTE+, Atherton Backplane, ATIS, IBM Repository manager and ADCycle to
+ name a few. Let's take a quick look at some of the things that made these integration
+ platforms unsuccessful.</p>
+<p>First, many of them focused primarily on data integration by specifying a single
+ common repository manager, and a single, common, extensible &quot;Enterprise
+ Schema&quot;. This was a great idea in that it provided a single method for
+ accessing and interchanging data, but it didn't work. It is nearly impossible
+ to do the commonality/variability analysis required to develop a common schema
+ across a wide set of development tools, ISVs that produce them, problem domains,
+ and time. This just creates too much coupling in tools that have to optimize
+ their schema and stored data formats to support their own specific needs. Encapsulation
+ is our friend, and some forms of data integration breaks encapsulation. There
+ is also still no single repository manager that meets all the diverse needs
+ of emerging application development tools.</p>
+<p>Second, data access and interchange protocols, and common schemas used to support
+ data integration were often tied to a single product built, managed, controlled,
+ and sold by a single vendor. This made it difficult for other vendors to manage
+ their own repository access and schema needs. It put the control of one of the
+ most critical components of a tool vendor's product in the hands of a potential
+ competitor!</p>
+<p>Third, data integration by itself did not address other aspects of tool integration
+ like tool behavior and user interfaces. Most of the difficult work involved
+ in integrating tools is in the architectures, services, and frameworks that
+ support extensibility and user interface development and integration. Using
+ simple operating system processes does not lead to tool integration. It drops
+ it in the customer's lap where the integration has to be done over and over
+ again by hand.</p>
+<p>Finally we didn't have the computer languages, or programming, and component
+ models required to support real framework development and reuse. </p>
+<p>Now there's a whole new crop of tool integration platforms like Microsoft Visual
+ Studio.NET, SUN's Forte for Java, and Borland's Jbuilder. Having more than one
+ tool integration platform might seem like a good thing, but it creates a portability
+ problem just like operating systems do for applications. A tool builder needs
+ to maximize his market while minimizing his development costs. Leveraging tool
+ integration frameworks can decrease development costs through reuse of common
+ services and frameworks, but those costs go right back up if the tool builder
+ needs to integrate with more than one integration framework. We're right back
+ into the OS porting problem, but with few standards to minimize the variability
+ between integration platforms. Tool builders are likely to have to spend a lot
+ of time coming up with wrapping technologies of their own to allow their tool
+ to integrate with more than one integration platform. This is just what we used
+ to do with GUI and database frameworks. All this wrapping increases the complexity
+ of the tool, subjects it to the pressures of tracking releases of multiple integration
+ platforms, and takes away from development time they could be spending on their
+ problem domain.</p>
+<p>So how is Eclipse different? How will it help minimize some of these problems
+ and allow us to achieve some of the promises given above? </p>
+<p>First, Eclipse is not just about data integration. Tools can easily share each
+ other's data. All resources being edited are just files in the user's local
+ file system. Eclipse can be integrated with a number of repository management
+ systems to provide additional versioning and resource access and distribution
+ services. The Workbench currently supports Rational ClearCase/LT, CVS, and WebDAV
+ (RFC2416, versioning will come later). </p>
+<p>Eclipse also supports API and UI integration. That is, a tool may encapsulate
+ its model data in a Java API, and provide that API as a plug-in for other tools
+ to use. This way clients of the API don't have to reconstruct the meaning or
+ behavior of some other tool's data, and that tool's data integrity is not compromised
+ by exposing implementation detail. UI integration allows tools to contribute
+ to the Workbench menus, toolbars, status bar, preference pages, properties view,
+ task view, outline view, etc. This way an integrated tool looks like it was
+ built right in. Users get a seamless experience as they move from one tool to
+ another.</p>
+<p>Eclipse exploits Java as the development and integration language. This provides
+ a nice high-level object-oriented language and programming model capable of
+ supporting a tool integration platform. Not that Java is issue free. The Eclipse
+ platform addresses many of Java's issues with things like Adapters, SWT, the
+ UI frameworks, various contribution frameworks, and the plug-in class loader.
+ Using the plug-in class loader allows each plug-in to have its own classpath,
+ and allows the Workbench to have more than one version of the same plug-in running
+ at the same time allowing flexibility in managing plug-in versions.</p>
+<p>Eclipse provides its services and frameworks within a set of basic design objectives:</p>
+<ul>
+ <li><b>Extensibility</b> &#150; There is no way to predict all the possible
+ extension points in set of components. On the other hand, interoperability
+ cannot be achieved if each individual development group defines their own
+ private ways of extending and configuring their components.</li>
+ <li><b>Controlled openness</b> &#150; Its good to be open, but not so open that
+ implementation detail in unnecessarily exposed, or the platform can be &quot;configured
+ into destruction&quot;. Wherever possible, extensibility is handled through
+ declarative registration and configuration rather than through direct programmatic
+ means with exposed APIs</li>
+ <li><b>Integration</b> (a corollary of controlled openness) &#150; Eclipse maintains
+ a consistent level of product integration even across multiple extensions
+ from many sources. This covers areas such as look-and-feel, overall tool task
+ flow, user assistance (help), etc. </li>
+ <li><b>Performance</b> &#150; A typical user configuration might result in many
+ different extensions to the platform.. The user should not pay a performance
+ penalty for any one given installed extension until the use of the extension
+ is explicitly triggered by a user action (e.g., Eclipse avoids long platform
+ startup times due to in-line extension initialization). </li>
+ <li><b>Simplicity</b> &#150; Adding an extension should not require understanding
+ of unnecessary elements of the overall platform, its APIs, and especially
+ their implementations. </li>
+ <li><b>Isolation</b> &#150; Extensions will come from many different sources.
+ These extensions should not introduce points requiring coordination among
+ extension providers </li>
+</ul>
+<p>These design goals allow Eclipse to be a truly open, scalable, high performance,
+ tool integration platform.</p>
+<p>Building complex, distributed Web applications consisting of many diverse and
+ highly coupled resource types surly requires integrated tools that understand
+ and manage the relationships between these resources. No one company, no matter
+ how good they are, can keep up with the tooling demands of the Web. New technologies
+ are constantly emerging requiring new tools that somehow have to interoperate
+ with the old ones that are still supporting the customer's business. The solution
+ requires a broad community of software developers contributing application development
+ tools, and an open, ubiquitous tool integration platform that enables interoperability
+ between them. To attract tool builders and promote adoption, the tool integration
+ platform must be accessible and available under acceptable terms including licensing
+ and access to source code. This will minimize interoperability and integration
+ problems while allowing the community dependent on the integration platform
+ to manage their own critical issues. Open Source provides an ideal mechanism
+ for managing the integration platform as a shared asset. Through Open Source,
+ problems resulting from loss of control and being at the mercy of a competitor
+ are gone. If there's a problem with the integration platform, or some feature
+ is missing, a tool builder can join the community and contribute the necessary
+ fixes.</p>
+<h3>Conclusion</h3>
+<p>In summary, lets take a look at the Eclipse value proposition for the Eclipse
+ community, tool builders, and end users of tools integrated with Eclipse.</p>
+<p>Benefits to the Eclipse Community:</p>
+<ol>
+ <li>Growing community of tool vendors </li>
+ <ul>
+ <li>supporting and participating in solutions</li>
+ <li>hardening the Eclipse platform with a broad, diverse community view</li>
+ <li>promoting common application development models</li>
+ <li>driving derivative sales</li>
+ </ul>
+ <li>The community contributes directly to the future of the platform
+ <ul>
+ <li>reducing the cost of this effort over time</li>
+ <li>allows contribution by individuals with unique competencies</li>
+ </ul>
+ </li>
+ <li>Provides a potentially pervasive tool integration platform
+ <ul>
+ <li>Open standards defining externals are a start</li>
+ <li>Where integration standards don't exist Open Source is a good alternative</li>
+ <li>Easy to quickly build well integrated components generating excitement
+ and customer appeal, and its fun too!</li>
+ </ul>
+ </li>
+ <li>Enables a new level of collaboration
+ <ul>
+ <li>Realizing interoperability and integration by their very nature require
+ community participation</li>
+ <li>Eclipse is the seed technology to get the community started</li>
+ </ul>
+ </li>
+</ol>
+<p>Benefits to Tool Developers:</p>
+<ol>
+ <li>Access to New and Growing Markets
+ <ul>
+ <li>Build for emerging e-business run-time markets (including e-commerce,
+ B2B and collaboration, pervasive, Web Services, etc.)</li>
+ </ul>
+ </li>
+ <li>Reduced Time to Market </li>
+ <ul>
+ <li>Through exploitation of open standard API&#146;s Through use of Eclipse
+ platform technology</li>
+ </ul>
+ <li>Reduced Development and Marketing Costs
+ <ul>
+ <li>Through reuse of open, portable technology and an extended community
+ of developers</li>
+ <li>By allowing a focus on core competencies</li>
+ <li>By reducing tool integration expense</li>
+ <li>Through involvement in the Eclipse Corner</li>
+ </ul>
+ </li>
+ <li>Address Buying Trend or Integrated Suites
+ <ul>
+ <li>Integrate suites of tools from other providers using the Eclipse platform</li>
+ <li>Form partnerships around the Eclipse platform for full end-to-end solutions<br>
+ </li>
+ </ul>
+ </li>
+</ol>
+<p>Benefits to End Users:</p>
+<ol>
+ <li>Faster Deployment of Quality Applications
+ <ul>
+ <li>Support full development cycle with integrated offerings</li>
+ <li>Smooth transition from tool to tool and role to role</li>
+ <li>Provide better integration for many different kinds of application resources</li>
+ </ul>
+ </li>
+ <li>Decreased Cost of Programmer Training/Skills</li>
+ <ul>
+ <li>Provide consistent views across all programming resources and roles</li>
+ <li>Enable integration of existing skills and programs</li>
+ </ul>
+ <li>Best-of-Breed Tools</li>
+ <ul>
+ <li>Leverage partnerships with industry-leading developers</li>
+ <li>Select and integrate tools when needed, not on fixed (long) development
+ release cycles</li>
+ </ul>
+ <li>Easy Adaptation to Change</li>
+ <ul>
+ <li>Drive open standards-based technology</li>
+ <li>Architect solutions for extensibility</li>
+ </ul>
+ <li>Eclipse is tied to the community, not a single vendor
+ <ul>
+ <li>allows choice without giving up interoperability and integration<br>
+ </li>
+ </ul>
+ </li>
+</ol>
+<p>The overall goal of Eclipse is to make good on promises made a decade ago:
+ integrated development, reduced time to market, and reuse of developed artifacts.</p>
+<h3></h3>
+<p><br>
+</p>
+</body>
+</html>
diff --git a/ToolIntegration/images/currentToolIntegration.gif b/ToolIntegration/images/currentToolIntegration.gif
new file mode 100644
index 0000000..37c5e5a
--- /dev/null
+++ b/ToolIntegration/images/currentToolIntegration.gif
Binary files differ
diff --git a/ToolIntegration/images/eclipseOverview.gif b/ToolIntegration/images/eclipseOverview.gif
new file mode 100644
index 0000000..3d3cc18
--- /dev/null
+++ b/ToolIntegration/images/eclipseOverview.gif
Binary files differ
diff --git a/ToolIntegration/images/image004.gif b/ToolIntegration/images/image004.gif
new file mode 100644
index 0000000..4ada5cf
--- /dev/null
+++ b/ToolIntegration/images/image004.gif
Binary files differ
diff --git a/ToolIntegration/images/image007.gif b/ToolIntegration/images/image007.gif
new file mode 100644
index 0000000..bc8e889
--- /dev/null
+++ b/ToolIntegration/images/image007.gif
Binary files differ
diff --git a/ToolIntegration/images/image008.gif b/ToolIntegration/images/image008.gif
new file mode 100644
index 0000000..4a03abd
--- /dev/null
+++ b/ToolIntegration/images/image008.gif
Binary files differ
diff --git a/ToolIntegration/images/image009.gif b/ToolIntegration/images/image009.gif
new file mode 100644
index 0000000..d073a0e
--- /dev/null
+++ b/ToolIntegration/images/image009.gif
Binary files differ
diff --git a/ToolIntegration/images/image010.gif b/ToolIntegration/images/image010.gif
new file mode 100644
index 0000000..d073a0e
--- /dev/null
+++ b/ToolIntegration/images/image010.gif
Binary files differ
diff --git a/ToolIntegration/images/pressures.gif b/ToolIntegration/images/pressures.gif
new file mode 100644
index 0000000..5972b19
--- /dev/null
+++ b/ToolIntegration/images/pressures.gif
Binary files differ
diff --git a/ToolIntegration/images/problemSpace.gif b/ToolIntegration/images/problemSpace.gif
new file mode 100644
index 0000000..353d9f3
--- /dev/null
+++ b/ToolIntegration/images/problemSpace.gif
Binary files differ
diff --git a/ToolIntegration/images/webTransaction.gif b/ToolIntegration/images/webTransaction.gif
new file mode 100644
index 0000000..746ab00
--- /dev/null
+++ b/ToolIntegration/images/webTransaction.gif
Binary files differ
diff --git a/ToolIntegration/images/workbenchIntegration.gif b/ToolIntegration/images/workbenchIntegration.gif
new file mode 100644
index 0000000..b6ed982
--- /dev/null
+++ b/ToolIntegration/images/workbenchIntegration.gif
Binary files differ
diff --git a/article-template.zip b/article-template.zip
new file mode 100644
index 0000000..7eee49c
--- /dev/null
+++ b/article-template.zip
Binary files differ
diff --git a/contributing.html b/contributing.html
new file mode 100644
index 0000000..7b088d0
--- /dev/null
+++ b/contributing.html
@@ -0,0 +1,127 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="../default_style.css" type="text/css">
+<title>Contributing Eclipse Articles</title>
+</head>
+<body>
+&nbsp;
+<table BORDER=0 CELLSPACING=5 CELLPADDING=2 WIDTH="100%" >
+ <tr>
+ <td ALIGN=LEFT width="54%">
+ <p><font class=indextop> contributing articles<br>
+ </font></p>
+ </td>
+ <td width="46%"><img SRC="../images/howto_banner.jpg" height=111 width=272 align=CENTER></td>
+ </tr>
+</table>
+
+<table border=0 cellspacing=5 cellpadding=2 width="100%" >
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font color="#FFFFFF" face="Arial,Helvetica">Eclipse
+ Corner Articles</font></b></td>
+ </tr>
+ <tr>
+ <td>
+ <p>Articles appearing on Eclipse Corner have been written by members of
+ the development team and other members of the eclipse community. You too
+ can contribute! Eclipse Corner depends on contributions from people like
+ you.
+ </p>
+ </td>
+ </tr>
+</table>
+<table BORDER=0 CELLSPACING=5 CELLPADDING=2 WIDTH="100%" >
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">How
+ to write an article<a name="WritingArticle"></a></font></b></td>
+ </tr>
+ <!-- Add the Articles -->
+ <tr>
+ <td ALIGN=RIGHT VALIGN=TOP><img SRC="images/Adarrow.gif" BORDER=0 height=16 width=16></td>
+ <td align="left" valign="top">
+ <p>So you have an idea for an article. Excellent! To make your article writing
+ experience a smooth one here is a little advice:</p>
+ <p><b>Before writing the article</b> </p>
+ <ul>
+ <li>Before you start churning out the content, take a few minutes to
+ search Bugzilla to make sure the subject is not already being covered.
+ All requested, proposed, and in-progress articles are listed in the
+ Community project, Articles component.
+ This is also a good way to find out what articles people want if you're
+ trying to decide what to write.
+ If someone else is working on a similar article, consider joining them
+ as a co-author, or adjusting the focus of your article so they don't overlap.</li>
+ <li>Next, write down a short outline of your article and the main topics
+ you intend to cover.
+ Open a new bugzilla entry for the article if there's not one already and
+ put your outline in the comments there.
+ Indicate a rough idea of when you expect the article to be completed.</li>
+ <li>Once your outline is entered in the system, interested parties will
+ provide you with additional ideas and feedback.</li>
+ </ul>
+ <b>Writing the article</b>
+ <p>Assuming the feedback on your outline is positive, then it's time to write the
+ content.</p>
+ <ul>
+ <li>To get you started you can extract the following <a href="article-template.zip"><b>document
+ template</b></a> . Be sure to read the <b>readme.txt</b> in its root
+ directory.</li>
+ <li>Try and keep it fun and lively, after all, you probably wouldn't want
+ to read a boring article. </li>
+ <li>Keep your article practical and if you have code snippets <b>always</b>
+ have your article link to a zip file containing a plug-in with the code.</li>
+ <li>The last tip is to aim for maximal content with minimum words. Forty
+ page articles could better be published as paper back novels.</li>
+ </ul>
+ <p><b>After finishing the article</b></p>
+ <ul>
+ <li>When you have finished your draft article, zip it up and
+ attach the zip to the bugzilla entry.
+ </li>
+ <li>The Articles Editor and one or more reviewers
+ will work with you (via bugzilla comments and/or email) to finalize the article.
+ As you come up with new revisions, attach them to the bugzilla entry.</li>
+ <li>Don't be discouraged if you get lots of feedback.
+ Most articles require at least two drafts before they are finalized.
+ Remember, the reviewers are trying to help you make the article the best
+ thing since the invention of those tiny umbrellas they put in drinks.</li>
+ </ul>
+ <p><b>Posting the article</b></p>
+ <ul>
+ <li>After all the kinks are worked out and the final draft is in bugzilla,
+ the article will be posted on the site and the bugzilla entry marked as closed.
+ Stand back and watch as the masses come running to read it.<br>
+ </li>
+ </ul>
+ <p>Please direct any question on submitting an article to <a href="mailto:articles_editor@eclipse.org">(Editor)</a>.</p>
+ </td>
+ </tr>
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Legal</font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td align="left" valign="top">
+ <p>Articles submitted to Eclipse Corner are accepted for posting under the
+ &quot;<a href="http://www.eclipse.org/legal/termsofuse.html">Terms of
+ Use</a>&quot; .</p>
+ </td>
+ </tr>
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+</table>
+
+</body>
+</html>
+
diff --git a/images/Adarrow.gif b/images/Adarrow.gif
new file mode 100644
index 0000000..1848247
--- /dev/null
+++ b/images/Adarrow.gif
Binary files differ
diff --git a/images/Idea.jpg b/images/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/images/Idea.jpg
Binary files differ
diff --git a/images/howto_banner.jpg b/images/howto_banner.jpg
new file mode 100644
index 0000000..f2e2d42
--- /dev/null
+++ b/images/howto_banner.jpg
Binary files differ
diff --git a/images/htmltoolbar.jpg b/images/htmltoolbar.jpg
new file mode 100644
index 0000000..86b105c
--- /dev/null
+++ b/images/htmltoolbar.jpg
Binary files differ
diff --git a/images/linux_only.gif b/images/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/images/linux_only.gif
Binary files differ
diff --git a/images/markers.jpg b/images/markers.jpg
new file mode 100644
index 0000000..85195e6
--- /dev/null
+++ b/images/markers.jpg
Binary files differ
diff --git a/images/normaltoolbar.jpg b/images/normaltoolbar.jpg
new file mode 100644
index 0000000..b05173c
--- /dev/null
+++ b/images/normaltoolbar.jpg
Binary files differ
diff --git a/images/note.gif b/images/note.gif
new file mode 100644
index 0000000..f6260db
--- /dev/null
+++ b/images/note.gif
Binary files differ
diff --git a/images/notifiers.gif b/images/notifiers.gif
new file mode 100644
index 0000000..aefc75d
--- /dev/null
+++ b/images/notifiers.gif
Binary files differ
diff --git a/images/srctoolbar.jpg b/images/srctoolbar.jpg
new file mode 100644
index 0000000..2042b12
--- /dev/null
+++ b/images/srctoolbar.jpg
Binary files differ
diff --git a/images/tag_1.gif b/images/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/images/tag_1.gif
Binary files differ
diff --git a/images/tag_2.gif b/images/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/images/tag_2.gif
Binary files differ
diff --git a/images/tag_3.gif b/images/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/images/tag_3.gif
Binary files differ
diff --git a/images/tag_4.gif b/images/tag_4.gif
new file mode 100644
index 0000000..a1ad63f
--- /dev/null
+++ b/images/tag_4.gif
Binary files differ
diff --git a/images/tag_5.gif b/images/tag_5.gif
new file mode 100644
index 0000000..d86a748
--- /dev/null
+++ b/images/tag_5.gif
Binary files differ
diff --git a/images/tag_6.gif b/images/tag_6.gif
new file mode 100644
index 0000000..b9eb4ec
--- /dev/null
+++ b/images/tag_6.gif
Binary files differ
diff --git a/images/tag_7.gif b/images/tag_7.gif
new file mode 100644
index 0000000..5f0e8fa
--- /dev/null
+++ b/images/tag_7.gif
Binary files differ
diff --git a/images/tip.gif b/images/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/images/tip.gif
Binary files differ
diff --git a/images/tryit.gif b/images/tryit.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/images/tryit.gif
Binary files differ
diff --git a/images/win_only.gif b/images/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/images/win_only.gif
Binary files differ
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..fe3e004
--- /dev/null
+++ b/index.html
@@ -0,0 +1,21 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>Eclipse Corner</title>
+</head>
+<frameset rows="48,*" frameborder=0 framespacing=0 border="0">
+ <frame name="banner" scrolling="no" noresize target="home"
+ src="../ecorner-banner.html" marginwidth="0" marginheight="0" frameborder="NO">
+ <frameset cols="126,*" frameborder=0 framespacing=0 border="0">
+ <frame name="nav" scrolling="no" noresize target="main"
+ src="../home_nav.html" marginwidth="0" marginheight="0" frameborder="NO">
+ <frame name="main" marginwidth=10 marginheight=10 noresize frameborder="NO" src="main.html">
+ </frameset>
+ <noframes>
+ <body>
+ <p>This page uses frames, but your browser doesn't support them.</p>
+ </body>
+ </noframes>
+ </frameset>
+</html> \ No newline at end of file
diff --git a/index.php b/index.php
index 2b749c3..86080f7 100644
--- a/index.php
+++ b/index.php
@@ -54,7 +54,7 @@
<p>Besides these, a number of other web sites carry technical articles about
Eclipse. You can find pointers to these on the
- <a href="../community/main.html#EclipseInformation">Eclipse Community page</a>.
+ <a href="/community/">Eclipse Community page</a>.
<div class="homeitem3col">
$articles
diff --git a/main.html b/main.html
new file mode 100644
index 0000000..81a9c45
--- /dev/null
+++ b/main.html
@@ -0,0 +1,1015 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="../default_style.css" type="text/css">
+<title>Eclipse Technical Articles</title>
+</head>
+<body>
+&nbsp;
+<table BORDER=0 CELLSPACING=5 CELLPADDING=2 WIDTH="100%" >
+ <tr>
+ <td ALIGN=LEFT width="54%">
+ <p><font class=indextop> technical <br> articles</font><br>
+ <font class=indexsub> technical information for developers</font> </p>
+ </td>
+ <td width="46%"><img SRC="../images/howto_banner.jpg" height=111 width=272 align=CENTER></td>
+ </tr>
+</table>
+
+<table border=0 cellspacing=5 cellpadding=2 width="100%" >
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font color="#FFFFFF" face="Arial,Helvetica">Eclipse
+ Corner Articles</font></b></td>
+ </tr>
+ <tr>
+ <td>
+ <p><font size="-1" face="arial,helvetica,geneva">The following articles
+ have been written by members of the development team and other members
+ of the eclipse community. You too can contribute! Eclipse Corner depends
+ on contributions from people like you. </font></p>
+ <ul>
+ <li><font size="-1" face="arial,helvetica,geneva"><b>Interested in writing
+ an article?</b> &nbsp;&nbsp;&nbsp;See <a href="contributing.html">how
+ to contribute an article</a>.</font></li>
+ </ul>
+ (Besides these, a number of other web sites carry technical articles about
+ Eclipse. You'll find pointers to these on the <a href="../community/main.html#EclipseInformation">Eclipse
+ Community page</a>.)</td>
+ </tr>
+</table>
+<table border=0 cellspacing=5 cellpadding=2 width="100%" >
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font color="#FFFFFF" face="Arial,Helvetica">Eclipse
+ White Paper</font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="../whitepapers/eclipse-overview.pdf">Eclipse
+ Platform Technical Overview</a> </strong> July 2001 (updated for Eclipse
+ 2.1 in Feb. 2003) <br>
+ The Eclipse Platform is designed for building integrated development environments
+ (IDEs) that can be used to create applications as diverse as web sites,
+ embedded JavaTM programs, C++ programs, and Enterprise JavaBeansTM. This
+ paper is a general technical introduction to the Eclipse Platform. Part
+ I presents a technical overview of its architecture. Part II is a case study
+ of how the Eclipse Platform was used to build a full-featured Java development
+ environment.</font></td>
+ </tr>
+</table>
+<table BORDER=0 CELLSPACING=5 CELLPADDING=2 WIDTH="100%" >
+ <tr>
+ <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">New
+ Articles <a name="new"></a></font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-RCP-2/tutorial2.html">Rich
+ Client Tutorial Part 2</a></strong> Ed Burnette (SAS) August 9, 2004
+ (Updated November 21, 2005 for Eclipse 3.1)
+ <br>
+ The Rich Client Platform (RCP) allows you to build
+Java applications that can compete with native applications on any
+platform. Part 1 of the tutorial introduced you to the platform and the
+steps used to build the smallest possible RCP program. In part 2 we'll
+look at what we did in more detail and introduce some of the
+configuration classes that let you take control of much of the layout
+and functionality of an RCP application. This part has been updated for
+Eclipse 3.1.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Plugging-into-SourceForge/sourceforge.html">Plugging
+ into SourceForge.net</a></strong> David Biesack (SAS) October 15, 2005<br>
+ Congratulations on taking the plunge and writing an open source
+ plug-in for the Eclipse platform.
+ SourceForge.net can provide a good home your plug-in, but
+ information on how best to set up an Eclipse project there is sparse.
+ This article is an introduction to SourceForge for the Eclipse
+ developer. You will learn the features available to the
+ SourceForge.net open source developer community and be guided
+ through the process, from creating a SourceForge project to
+ hosting your Eclipse Update site.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-WTP-Persisting-EMF/persisting.html">Persisting
+ EMF models with WTP</a></strong> Daniel Rohe October 10, 2005<br>
+ This article will guide you through an example where an EMF model is created
+ without serialization and the serialization is done with the framework from
+ the WTP plugin org.eclipse.wst.common.emf.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-RCP-1/tutorial1.html">Rich
+ Client Tutorial Part 1</a></strong> Ed Burnette (SAS) July 28,
+ 2004 (updated July 2005 for Eclipse 3.1)<br>
+ The Rich Client Platform (RCP) is an exciting new way to build Java applications that can compete with native applications on any platform. This tutorial is designed to get you started building RCP applications quickly.
+ It has been updated for Eclipse 3.1.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-VE-Custom-Widget/customwidget.html">
+ Extending The Visual Editor</a></b>
+ Dave Orme (db4objects), Gili Mendel (IBM), Joe Winchester (IBM)
+ June 20, 2005
+ <br>
+ This tutorial
+ shows how to extend the Visual Editor to support a custom widget.
+ It covers topics such as adding to the Visual Editor's palette,
+ building a BeanInfo class, and working with
+ EMF .override files to
+ introduce custom editor behavior.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-GEF-EMF/gef-emf.html">
+ Using GEF with EMF</a></b>
+ Chris Aniszczyk (IBM)
+ June 8, 2005
+ <br>
+ The Graphical Editing Framework (GEF) provides a framework for
+ creating visual editors while being model agnostic. In most cases, people
+ bring their own model which tend to be based on Plain Old Java Objects
+ (POJOs). An alternative using POJOs is the Eclipse Modeling Framework
+ (EMF), which provides many features for manipulating models that aren't
+ found in POJOs. The purpose of this article is to build upon the shapes
+ example provided by GEF using the Eclipse Modeling Framework (EMF) and to
+ provide an introduction using EMF based models in GEF based editors.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-PDE-Automation/automation.html">
+ Build and Test Automation for Plug-ins and Features</a></b>
+ Markus Barchfeld (Zuehlke Engineering)
+ May 29, 2005
+ <br>
+ Eclipse offers the possibility to build plug-ins automatically outside
+ the Eclipse IDE, which is called "headless build". Eclipse itself is
+ built headless and since Eclipse is an assembly of plug-ins, this feature
+ is also available for any other plug-in. Although the set up of automatic
+ building and testing requires only a couple of files, it can be tedious
+ work to do nonetheless. This article shares the experiences and lessons
+ learned while setting up automatic building and testing for an
+ Open-Source Eclipse plug-in called RDT, Ruby Development Tools.
+ </font></td>
+ </tr>
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">General</font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Plugging-into-SourceForge/sourceforge.html">Plugging
+ into SourceForge.net</a></strong> David Biesack (SAS) October 15, 2005<br>
+ Congratulations on taking the plunge and writing an open source
+ plug-in for the Eclipse platform.
+ SourceForge.net can provide a good home your plug-in, but
+ information on how best to set up an Eclipse project there is sparse.
+ This article is an introduction to SourceForge for the Eclipse
+ developer. You will learn the features available to the
+ SourceForge.net open source developer community and be guided
+ through the process, from creating a SourceForge project to
+ hosting your Eclipse Update site.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-PDE-Automation/automation.html">
+ Build and Test Automation for Plug-ins and Features</a></b>
+ Markus Barchfeld (Zuehlke Engineering)
+ May 29, 2005
+ <br>
+ Eclipse offers the possibility to build plug-ins automatically outside
+ the Eclipse IDE, which is called "headless build". Eclipse itself is
+ built headless and since Eclipse is an assembly of plug-ins, this feature
+ is also available for any other plug-in. Although the set up of automatic
+ building and testing requires only a couple of files, it can be tedious
+ work to do nonetheless. This article shares the experiences and lessons
+ learned while setting up automatic building and testing for an
+ Open-Source Eclipse plug-in called RDT, Ruby Development Tools.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-RCP-1/tutorial1.html">Rich
+ Client Tutorial Part 1</a></strong> Ed Burnette (SAS) July 28,
+ 2004 (updated July 2005 for Eclipse 3.1)<br>
+ The Rich Client Platform (RCP) is an exciting new way to build Java applications that can compete with native applications on any platform. This tutorial is designed to get you started building RCP applications quickly.
+ It has been updated for Eclipse 3.1.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-RCP-2/tutorial2.html">Rich
+ Client Tutorial Part 2</a></strong> Ed Burnette (SAS) August 9, 2004
+ (Updated November 21, 2005 for Eclipse 3.1)
+ <br>
+ The Rich Client Platform (RCP) allows you to build
+Java applications that can compete with native applications on any
+platform. Part 1 of the tutorial introduced you to the platform and the
+steps used to build the smallest possible RCP program. In part 2 we'll
+look at what we did in more detail and introduce some of the
+configuration classes that let you take control of much of the layout
+and functionality of an RCP application. This part has been updated for
+Eclipse 3.1.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-RCP-3/tutorial3.html">Rich
+ Client Tutorial Part 3</a></strong> Ed Burnette (SAS) July 28,
+ 2004<br>
+ The Rich Client Platform (RCP) lets you pick and choose functionality from Eclipse for use in your own applications. Parts 1 and 2 of this tutorial introduced you to the platform and some of the configuration classes it provides. Part 3 discusses how to add functionality such as menus, views, and help files.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><a href="Article-PDE-does-plugins/PDE-intro.html"><strong>PDE
+ Does Plug-ins</strong></a> Wassim Melhem (IBM) and Dejan Glozic (IBM) September
+ 8, 2003<br>
+ The Plug-in Development Environment (PDE) provides a set of tools that assist
+ the developer in every stage of plug-in development from genesis to deployment.
+ This article chronicles the creation, development, testing, building, and
+ deployment of a simple &quot;Hello World&quot; plug-in using a subset of
+ these tools.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Internationalization/how2I18n.html">How
+ to Internationalize your Eclipse Plug-In</a></b>&nbsp;Dan Kehn (IBM), Scott
+ Fairbrother (IBM), and Cam-Thu Le (IBM) August 23, 2002<br>
+ This article is a roadmap for writing Eclipse plug-ins destined for the
+ international market. We'll begin with a brief review of the motivations
+ and technical challenges of internationalization, followed by step-by-step
+ instructions of how to internationalize your Eclipse plug-in. </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-TVT/how2TestI18n.html">How
+ to Test Your Internationalized Eclipse Plug-In</a></strong> Dan Kehn (IBM)
+ August 23, 2002<br>
+ This article shows you how to validate your internationalized product and
+ prepares you for the types of common problems you can expect during translation
+ testing. It includes an Eclipse plug-in that defines a <i>Properties File
+ Compare</i> view that can help your translation testers find errors more
+ quickly.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Branding/branding-your-application.html">
+ Branding Your Application</a></b>&nbsp;Andrew Eidsness and Pascal Rapicault
+ (IBM) September 16, 2004 <br>
+ In this article we look at how to create branding for your Eclipse-based
+ application. Branding is how you change the high level visual elements of your
+ product. This includes items such as the splash screen, the about dialog, and
+ the program executable.</font></td>
+ </tr>
+ <!-- Add the Articles -->
+ <tr>
+ <td ALIGN=RIGHT VALIGN=TOP><img SRC="images/Adarrow.gif" BORDER=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-API%20use/eclipse-api-usage-rules.html">
+ How to Use the Eclipse API</a></b>&nbsp;Jim des Rivieres&nbsp;(OTI) April
+ 24, 2001 <br>
+ The Eclipse Platform offers a comprehensive API (Application Programmer
+ Interface) to developers writing plug-ins. This article discusses the general
+ ground rules for using the Eclipse Platform API, including how to tell API
+ from non-API, and how to stay in the API "sweet spot" to avoid the risk
+ of being broken as the platform and its APIs evolve. These general ground
+ rules are also recommended practice for plug-ins that must declare API elements
+ of their own. </font></td>
+ </tr>
+ <!-- Add the Articles -->
+ <tr>
+ <td ALIGN=RIGHT VALIGN=TOP><img SRC="images/Adarrow.gif" BORDER=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Levels-Of-Integration/Levels%20Of%20Integration.html">
+ Levels of Integration</a></b>&nbsp;Jim Amsden&nbsp;(OTI) March 25, 2001
+ <br>
+ The types of problems web application developers face today require the
+ use of a diverse set of tools that operate in many domains. In order to
+ provide flexible tool integration, a tool integration platform must allow
+ tool developers to target different levels or integration based on the desired
+ level of investment, time to market, and specific tool needs. Each integration
+ level determines how a tool must behave, and what end users can expect as
+ a result. This article defines the different levels of tool integration
+ supported by Eclipse, and gives an overview of how they work. </font>
+ </td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Accessibility/accessibility.html">Designing
+ Accessible Plug-ins in Eclipse</a></strong> Tod Creasey (IBM) May 20, 2003<br>
+ Accessibility for the disabled is now a priority in application development
+ as advances in techniques and support within operating systems have now
+ made this possible. This article covers the Eclipse accessibility support,
+ general tips for creating accessible plug-ins, and the types of disabilities
+ that the Eclipse accessibility support assists. This is all illustrated
+ using an example of making a view accessible.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Monitor/monitorArticle.html">Building
+ administrative applications in Eclipse</a></b>&nbsp;Doina Klinger and Chris
+ Markes (IBM) November 12, 2004</font><br>
+ Eclipse is most commonly used as a platform for tools that allow the
+ user to construct or assemble an end product out of development resources.
+ It is less usual to use Eclipse as an administrative tool for monitoring
+ existing runtime systems or applications. This article will describe some
+ of the issues that arise in this case and illustrate possible solutions.
+ It will show you can build an Eclipse perspective dedicated to the monitoring
+ task. Running processes are shown in a dedicated view which always reflects
+ their current state. You can start/stop the process, manage connections,
+ invoke operations that the server exposes, examine server output and view
+ events generated by the running applications.</td>
+ </tr>
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF"><a name="core">Core</a></font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Resource-deltas/resource-deltas.html">How
+ You've Changed! Responding to resource changes in the Eclipse workspace
+ (Revised for 3.0)
+ </a></strong> John Arthorne (OTI) November 23, 2004<br>
+ Many tools and user interface elements are interested in processing resource
+ changes as they happen. For example, the task list wants to update new or
+ changed markers, the navigator wants to reflect added and deleted resources,
+ and the Java compiler wants to recompile modified Java files. Such notifications
+ are potentially costly to compute, manage and broadcast. The Eclipse Platform
+ resource model includes a series of mechanisms for efficiently notifying
+ clients of resource changes. This article outlines these facilities and
+ gives some examples of their use.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Builders/builders.html">Project
+ Natures and Builders (Revised for 3.0)</a> </strong> John Arthorne (IBM)
+ November 23, 2004<br>
+ This article discusses two central mechanisms that are associated with projects
+ in an Eclipse workspace. The first of these is incremental project builders,
+ which create some built state based on the project contents, and then keep
+ that built state synchronized as the project contents change. The second
+ is project natures, which define and manage the association between a given
+ project and a particular plug-in or feature. The purpose and uses of builders
+ and natures will be described in detail, and working examples will be provided
+ to highlight the finer details of implementing them for your own plug-in.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Plug-in-architecture/plugin_architecture.html">Notes
+ on the Eclipse Plug-in Architecture</a> </strong> Azad Bolour (Bolour Computing)
+ July 3, 2003<br>
+ Eclipse plug-ins embody an architectural pattern for building an application
+ from constituent parts. This article presents an in-depth view of the participant
+ roles and collaborations of this architectural pattern, as they exist in
+ an instance of the Eclipse workbench. The goal is to provide an understanding
+ of plug-ins, and of how plug-in extensions are defined and processed, independently
+ of the mechanics of using the Eclipse workbench to produce plug-ins.</font></td>
+ </tr>
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Debug<a name="debug"></a></font></b></td>
+ </tr>
+ <!-- Add the Articles -->
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Launch-Framework/launch.html">
+ We Have Lift-off: The Launching Framework in Eclipse</a></b> Joe Szurszewski
+ (IBM) January 8, 2003<br>
+ The ability to launch (run or debug) code under development is fundamental
+ to an IDE. But because Eclipse is more of a tools platform than a tool itself,
+ Eclipse's launching capabilities depend entirely on the current set of installed
+ plug-ins. This article describes the API available to build launching plug-ins
+ and works through developing an example launcher using this API.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Java-launch/launching-java.html">
+ Launching Java Applications Programmatically</a></b> Darin Wright (IBM)
+ August 26, 2003<br>
+ Application developers require the ability to run and debug code in order to
+ test it. Tool developers require the ability to launch Java applications that
+ assist in application development - for example, starting and stopping a web
+ server on which servlets, JSPs, and HTML pages can be tested; or launching a
+ VM on which scrapbook evaluations can be performed. This article focuses on
+ the high level API provided by the Java launching plug-in that tool developers
+ can leverage for the programmatic launching of local Java applications.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Debugger/how-to.html">
+ How to write an Eclipse debugger</a></strong> Darin Wright (IBM) and Bjorn
+ Freeman-Benson (Predictable Software) August 27, 2004<br>
+One of the major tasks of adding a new language to an Eclipse-based IDE is debugging support. A debugger needs to start and stop the
+program being debugged, suspend and resume, single-step, manage breakpoints and watch points,
+and so on. This article explains the Eclipse Platform debug framework and steps through a
+simple, yet illustrative, example of adding debug support for a new language.</font></td>
+ </tr>
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Help<a name="help"></a></font></b></td>
+ </tr>
+ <tr>
+ <td ALIGN=RIGHT VALIGN=TOP><img SRC="images/Adarrow.gif" BORDER=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Online%20Help%20for%202_0/help1.htm">
+ Help - Part 1: Contributing a Little Help (Revised for 2.0)</a></b>&nbsp;Greg
+ Adams (OTI) and Dorian Birsan&nbsp;(IBM) August 9, 2002<br>
+ The Eclipse Platform&#8217;s help system defines two extension points (<code>"toc"
+ </code>and<code> "contexts"</code>) that allow individual plug-ins to contribute
+ online help and context-sensitive help for their components. In this article
+ we will investigate the <code>"toc"</code> extension point and how you can
+ use it to contribute documentation for your plug-in.</font></td>
+ </tr>
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">SWT<a name="SWT"></a></font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-SWT-OpenGL/opengl.html">
+ Using OpenGL with SWT</a></b>
+ Bo Majewski (Cisco)
+ April 15, 2005
+ <br>
+ OpenGL is a vendor-neutral, multi-platform standard for creating
+ high-performance 2D and 3D graphics. Hardware and software implementations
+ exist on various operating systems, including Windows, Linux and
+ MacOS. OpenGL may be used to render simple 2D charts or complex 3D games. This
+ article describes an experimental Eclipse plug-in that facilitates the use
+ of OpenGL for drawing onto SWT widgets. A short history and overview of
+ OpenGL is presented, followed by an example application.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Understanding%20Layouts/Understanding%20Layouts.htm">Understanding
+ Layouts in SWT (Revised for 2.0)</a></b><a href="preferences/preferences.htm">&nbsp;</a>
+ <span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'><span lang=EN-US style='mso-ansi-language:
+EN-US'>Carolyn MacLeod (OTI)</span></span></span>, <span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'><span lang=EN-US style='mso-ansi-language:
+EN-US'>Shantha Ramachandran</span></span></span> (OTI) April 24, 2002</font> <br>
+ <font face="arial,helvetica,geneva"><font size=-1> <span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'><span lang=EN-US style='mso-ansi-language:
+EN-US'>When writing applications in SWT, you may need to use <i style='mso-bidi-font-style:
+normal'>layouts</i> to give your windows a specific look. A layout controls the
+ position and size of children in a <i style='mso-bidi-font-style:normal'>Composite</i>.
+ Layout classes are subclasses of the abstract class <i style='mso-bidi-font-style:
+normal'>Layout</i>. This article shows you how to work with standard layouts,
+ and write your own custom layout class.</span></span></span></font></font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="swt-design-2/swt-design-2.html">SWT:
+ The Standard Widget Toolkit - Part 2</a></b>&nbsp;Carolyn MacLeod (OTI)
+ and Steve Northover (OTI) November 27, 2001</font> <br> <font face="arial,helvetica,geneva"><font size=-1>
+ SWT uses operating system resources to deliver its native graphics and widget
+ functionality. Allocating and freeing operating system resources is traditionally
+ an area of programming that is error prone. Languages that include garbage
+ collection, such as the Java™ language, relieve the programmer from the
+ burden of managing memory, but not from the allocation and freeing of operating
+ system resources. This article discusses the simple strategy used by SWT
+ to help application designers manage operating system resources. </font></font></td>
+ </tr>
+ <!-- Add the Articles -->
+ <tr>
+ <td ALIGN=RIGHT VALIGN=TOP><img SRC="images/Adarrow.gif" BORDER=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="StyledText%201/article1.html">
+ Getting Your Feet Wet with the SWT StyledText Widget (Revised for 3.0)</a></b>&nbsp;Lynne
+ Kues (OTI) and Knut Radloff&nbsp;(OTI) </font>July 19, 2004<br> <font face="arial,helvetica,geneva"><font size=-1>
+ The StyledText widget is a customizable widget that can be used to display
+ and edit text with different colors and font styles. This article presents
+ an overview of the concepts, issues, and rules that you should be aware
+ of when using the StyledText widget.</font></font></td>
+ </tr>
+ <!-- Add the Articles -->
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td> <p><font face="arial,helvetica,geneva" size=-1><b><a href="StyledText%202/article2.html">Into
+ the Deep End of SWT StyledText Widget (Revised for 2.0)</a></b>&nbsp;Lynne
+ Kues (OTI) and Knut Radloff&nbsp;(OTI) September 18, 2002</font><br>
+ <font face="arial,helvetica,geneva"><font size=-1> This is the second
+ of two articles on the SWT StyledText widget. This article dives into
+ some of the more advanced concepts of StyledText and builds on the previous
+ article </font></font><font face="arial,helvetica,geneva" size="-1">&quot;Getting
+ Your Feet Wet With the SWT StyledText Widget&quot;. </font><br>
+ </p></td>
+ </tr>
+ <tr>
+ <td ALIGN=RIGHT VALIGN=TOP><img SRC="images/Adarrow.gif" BORDER=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="SWT%20Color%20Model/swt-color-model.htm">
+ SWT Color Model</a></b>&nbsp;James Moody (OTI) and Carolyn MacLeod (OTI)
+ April 24, 2001</font> <br> <font face="arial,helvetica,geneva"><font size=-1>
+ The combination of platforms, display devices and color depth makes providing
+ an easy to use yet powerful and portable color model an interesting challenge.
+ In this article we will examine the color management models of Windows and
+ X/Motif and then dig into the makings of the SWT color model and its implications
+ for client code. </font></font> </td>
+ </tr>
+ <!-- Add the Articles -->
+ <tr>
+ <td ALIGN=RIGHT VALIGN=TOP><img SRC="images/Adarrow.gif" BORDER=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-SWT-Design-1/SWT-Design-1.html">
+ SWT: The Standard Widget Toolkit - Part 1</a></b>&nbsp;Steve Northover&nbsp;
+ (OTI) March 22, 2001</font> <br> <font face="arial,helvetica,geneva"><font size=-1>
+ SWT is the software component that delivers native widget functionality
+ for the Eclipse platform in an operating system independent manner. It is
+ analogous to AWT/Swing in Java with a difference - SWT uses native widgets.
+ This article is the first in series of articles that discuss the SWT widget
+ toolkit. This article discusses the low level implementation techniques
+ used to implement SWT on different platforms. Examples are drawn from the
+ windows and Motif implementations. </font></font> </td>
+ </tr>
+ <!-- Add the Articles -->
+ <tr>
+ <td ALIGN=RIGHT VALIGN=TOP><img SRC="images/Adarrow.gif" BORDER=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-ActiveX%20Support%20in%20SWT/ActiveX%20Support%20in%20SWT.html">
+ ActiveX Support in SWT</a></b>&nbsp;Veronika Irvine&nbsp; (OTI) March 22,
+ 2001</font> <br> <font face="arial,helvetica,geneva"><font size=-1> OLE
+ Documents, such as Word, Excel or PowerPoint, and ActiveX Controls such
+ as Internet Explorer are COM objects that can be embedded into other applications
+ running on a Microsoft Windows platform. This article provides an overview
+ of OLE and how to integrate OLE Documents and ActiveX Controls into an application
+ using SWT. </font></font><br> </td>
+ </tr>
+ <!-- Add the Articles -->
+ <!-- Add the Articles -->
+ <tr>
+ <td ALIGN=RIGHT VALIGN=TOP><img SRC="images/Adarrow.gif" BORDER=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm">
+ Creating Your Own Widgets using SWT</a></b>&nbsp;Steve Northover (OTI) &
+ Carolyn MacLeod&nbsp; (OTI) March 22, 2001</font> <br> <font face="arial,helvetica,geneva"><font size=-1>
+ When writing applications, you typically use the standard widgets provided
+ by SWT. On occasion, you will need to extend the set of base widgets by
+ creating your own custom widgets. For example, you might want to add a new
+ type of widget not provided by the standard widgets, or extend the functionality
+ of an existing widget. This article explains the different SWT extension
+ strategies and shows you how to use them. </font></font><br> </td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-SWT-graphics/SWT_graphics.html">Graphics
+ Context - Quick on the draw</a></strong> Joe Winchester (IBM) July 3, 2003<br>
+ The package <code>org.eclipse.swt.graphics</code> contains classes that
+ allows management of graphics resources. Graphics can be drawn on anything
+ that implements <code>org.eclipse.swt.graphics.Drawable, </code>which includes
+ <code>org.eclipse.swt.widgets.Control</code> and <code>org.eclipse.swt.graphics.Image</code>.
+ The class <code>org.eclipse.swt.graphics.GC </code>encapsulates all of the
+ drawing API, including how to draw lines and shapes, draw text and images
+ and fill shapes. This article shows how to use a GC to draw onto an Image,
+ or onto a control through its paintEvent callback. The Canvas control, specifically
+ designed for drawing operations, has a number of constructor style bits
+ that allow you to determine when and how painting occurs, and the article
+ shows how to use these.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b>
+ <a href="Article-SWT-DND/DND-in-SWT.html">Drag and Drop - Adding Drag and Drop to an SWT Application</a></b>&nbsp;Veronika Irvine&nbsp;(IBM) August 25, 2003<br>
+ Drag and drop provides a quick and easy mechanism for users to re-order and transfer
+ data within an application and between applications. This article is an overview of how
+ to implement Drag and Drop and Clipboard data transfers within an SWT
+ application.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-SWT-images/graphics-resources.html">Taking
+ a look at SWT Images</a></strong> Joe Winchester (IBM) September 10, 2003<br>
+ SWT's Image class can be used to display images in a GUI. The most common
+ source of images is to load from a standard file format such as GIF, JPEG,
+ PNG, or BMP. Some controls, including Buttons and TreeItems, are able to
+ display an Image directly through the setImage(Image) method, but any control's
+ paint event allows images to be drawn through the callback's graphic context.
+ SWT's ImageData class represents the raw data making up an SWT Image and
+ determines the color for each pixel coordinate. This article shows the correct
+ uses of ImageData and Image, shows how to load images from files, and how
+ to achieve graphic effects such as transparency, alpha blending, animation,
+ scaling, and custom cursors.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-small-cup-of-swt/pocket-PC.html">A
+ small cup of SWT</a></strong> Christophe Cornu (IBM) September 19, 2003<br>
+ Are you interested in developing applications for the Microsoft Pocket PC?
+ Are you a desktop developer curious about embedded user interfaces? A well-built
+ embedded application is both user and resource friendly. User expectations
+ are high, but resources are very limited. This article contains a bag of
+ hints, tricks, and recipes for developing SWT apps on the Pocket PC.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Image-Viewer/Image_viewer.html">A
+ Basic Image Viewer</a></strong> Chengdong Li (University of Kentucky) March
+ 15, 2004<br>
+ This article shows how to extend SWT <code>Canvas</code> to implement a mini image viewer plug-in using Java2D
+transforms. The
+extended image canvas can be used to scroll and zoom large images, and can also
+be extended to apply other transforms. The implementation is based on SWT and
+the non-UI portions of AWT. The plug-in has been tested on Windows, Linux GTK, and Mac
+OS X Carbon with Eclipse 2.1 or better.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-SWT-browser-widget/browser.html">Viewing
+ HTML pages with SWT Browser widget</a></strong> Christophe Cornu (IBM) August
+ 26, 2004<br>
+ This article explains how to add HTML viewing capability to an SWT application. The Browser widget provides an easy way to integrate rich HTML content into your application.</font></td>
+ </tr>
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Workbench
+ &amp; JFace<a name="ui"></a></font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Folding-in-Eclipse-Text-Editors/folding.html">Folding
+ in Eclipse Text Editors</a></b>&nbsp;Prashant Deva March 11, 2005<br>
+ Starting with release 3.0, Eclipse allows folding in its text
+ editor. In this article, I explain the new projection infrastructure
+ introduced in the JFace Text framework and show how to extend the XML
+ Editor example provided with Eclipse to allow folding of text.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-UI-Guidelines/Contents.html" target="_top">Eclipse
+ User Interface Guidelines, Version 2.1</a></b> Nick Edgar, Kevin Haaland,
+ Jin Li, and Kimberley Peter (IBM) February 2004</font><br>
+ <font face="arial,helvetica,geneva"><font size=-1> User Interface Guidelines &quot;best practices&quot;
+ document intended for use by designers and implementors of an Eclipse user
+ interface extension. (<a href="Article-UI-Guidelines/v200202/Index.html" target="_top">Earlier
+ version of the guidelines.</a>)</font></font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><a href="Article-Field-Editors/field_editors.html"><strong>Simplifying
+ Preference Pages with Field Editors</strong></a> Ryan Cooper (OTI) August
+ 21, 2002</font><br> <font face="arial,helvetica,geneva"><font size=-1>Even
+ though preference pages can be simple to program, you can spend a lot of
+ time getting them &quot;just right.&quot; Field editors make this task faster
+ and easier by providing the behavior for storing, loading, and validating
+ preferences. Field editors also define some of the behavior for grouping
+ and laying out widgets on a preference page.</font></font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="treeviewer-cg/TreeViewerArticle.htm">How
+ to use the JFace Tree Viewer</a></b><a href="preferences/preferences.htm">&nbsp;</a>
+ Chris Grindstaff (Applied Reasoning) May 2, 2002</font> <br> <font face="arial,helvetica,geneva"><font size=-1>
+ <span style='mso-bookmark:_Toc509864523'><span
+style='mso-bookmark:_Toc496069418'>The goal of this article is to teach you how
+ to use TreeViewers in your Eclipse plug-ins or stand-alone JFace/SWT applications.
+ We&#8217;ll start with a simple example and progressively add functionality.
+ </span></span></font></font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Preferences/preferences.htm">Preferences
+ in the Eclipse Workbench UI (Revised for 2.0)</a></b>&nbsp;Tod Creasey (OTI)
+ August 15, 2002</font><br>
+ <font face="arial,helvetica,geneva"><font size=-1> In the Eclipse Platform
+ plug-in developers define preference pages for their plug-ins for use in
+ the Workbench Preferences Dialog. This article explains when to use a preference
+ and some of the features the Eclipse Platform provides to support preferences.
+ </font></font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="viewArticle/ViewArticle2.html">
+ Creating an Eclipse View</a></b>&nbsp;Dave Springgay (OTI) November 2, 2001</font>
+ <br>
+ <font face="arial,helvetica,geneva"><font size=-1> In the Eclipse Platform
+ a view is typically used to navigate a hierarchy of information, open an
+ editor, or display properties for the active editor.&nbsp; In this article
+ the design and implementation of a view will be examined in detail.&nbsp;
+ You'll learn how to create a simple view based on SWT, and a more advanced
+ view using the JFace viewer hierarchy.&nbsp; We'll also look at ways to
+ achieve good integration with many of the existing features in the workbench,
+ such as the window menu and toolbar, view linking, workbench persistence
+ and action extension.</font></font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-JFace%20Wizards/wizardArticle.html">
+ Creating JFace Wizards</a></b> Doina Klinger (IBM) December 16, 2002<br>
+ This article shows you how to implement a wizard using the JFace toolkit
+ and how to contribute your wizard to the Eclipse workbench. A wizard whose
+ page structure changes according to user input is implemented to demonstrate
+ the flexibility of wizard support.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b> <a href="Article-action-contribution/Contributing%20Actions%20to%20the%20Eclipse%20Workbench.html">Contributing
+ Actions to the Eclipse Workbench</a></b>&nbsp;</font>Simon Arsenault <font face="arial,helvetica,geneva" size=-1>
+ (OTI)</font> October 18, 2001<br>
+ <font face="arial,helvetica,geneva"><font size=-1> The Eclipse Platform
+ is an open and extensible platform. This article explains in detail how
+ the Workbench can be extended to add new actions and provides guidance to
+ the plug-in developers on how they can design for extensibility.</font></font><br> </td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="using-perspectives/PerspectiveArticle.html">
+ Using Perspectives in the Eclipse UI</a></b>&nbsp;Dave Springgay (OTI) &nbsp;August
+ 27, 2001</font> <br>
+ <font face="arial,helvetica,geneva"><font size=-1> In the Eclipse Platform
+ a Perspective determines the visible actions and views within a window.&nbsp;
+ Perspectives also go well beyond this by providing mechanisms for task oriented
+ interaction with resources in the Eclipse Platform, multi-tasking and information
+ filtering.&nbsp; In this article the concepts behind perspectives are examined.&nbsp;
+ The process for perspective definition, extension and instantiation will
+ also be covered in detail with coding examples and sample scenarios.</font></font>
+ </td>
+ </tr>
+ <!-- Add the Articles -->
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Using%20Images%20In%20Eclipse/Using%20Images%20In%20Eclipse.html">
+ Using Images in the Eclipse UI (Revised for 2.0)</a></b>&nbsp;John Arthorne&nbsp;(OTI)
+ September 12, 2002<br>
+ Managing images in a large graphical application can be a daunting task.
+ Since modern operating systems such as Windows only support a small number
+ of images in memory at once, an application’s icons and background images
+ must be carefully managed and sometimes shared between widgets. This article
+ describes the image management facilities provided by the Eclipse Platform,
+ along with some best practice guidelines to keep in mind when writing your
+ own Eclipse UI plug-ins. We assume the reader already has a basic understanding
+ of Eclipse, the UI extension points defined by the Eclipse Platform, and
+ the Standard Widget Toolkit (SWT).</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Mark%20My%20Words/Mark%20My%20Words.html">
+ Mark My Words</a></b>&nbsp;Dejan Glozic (IBM) and Jeff McAffer (OTI)&nbsp;April
+ 1, 2001</font> <br>
+ <font face="arial,helvetica,geneva"><font size=-1> Eclipse workbench has
+ a central mechanism for managing resource annotations. They are called markers.
+ In this article, you will learn how to use markers to mark-up resources
+ as well as how to define your own marker types and enhance the Tasks view
+ to handle them in a special way. </font></font> </td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Decorators/decorators.html">
+ Understanding Decorators in Eclipse</a> </b>Balaji Krish-Sampath (IBM) January
+ 16, 2003</font> <br>
+ Decorators, as the name suggests, are used for adorning/annotating resources
+ with useful information. Decorators can be used by plug-ins to convey more
+ information about a resource and other objects displayed in different workbench
+ views.&nbsp; This article, with the help of a simple plug-in example, will
+ illustrate the steps involved in decorating resources, along with some best
+ practice approaches for decorating resources. Finally, we will discuss performance
+ issues that may arise when enabling decorators, and briefly go over the
+ new Lightweight decorators found in Eclipse 2.1.</td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Properties-View/properties-view.html">Take
+ control of your properties</a> </strong> Dicky Johan (Broadvision) May 20,
+ 2003<br>
+ The Eclipse workbench provides a properties view which is used to view (and/or
+ edit) properties of a selected item. In this article, you will learn how
+ to use the properties view to dynamically modify the properties of a GUI
+ button. </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Table-viewer/table_viewer.html">Building
+ and delivering a table editor with SWT/JFace</a></strong> Laurent Gauthier
+ (Mirasol Op'nWorks) July 3, 2003<br>
+ The JFace API provides several classes that can be used to build editable
+ table views. In this article, we present a fairly extensive example that
+ exercises the JFace and SWT classes needed to implement a table with cell
+ editors for check-boxes, free text and combo-boxes. We also show how to
+ package and deliver the classes into a stand-alone (non-Eclipse) Java application.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b> <a href="Article-Workbench-DND/drag_drop.html">Drag
+ and Drop in the Eclipse UI</a></b>&nbsp;John Arthorne&nbsp;(IBM) August
+ 25, 2003<br>
+ In this article, we discuss the drag and drop facilities provided by JFace and
+ the Eclipse platform UI. After reading this, you will know how to add drag and
+ drop support to your own Eclipse views, and how that support will interact with
+ the standard views in the Eclipse platform. Along the way, we'll also discuss
+ that keyboard relative of drag and drop: cut and paste. You'll learn that putting
+ your own custom objects on the clipboard is easy once you've figured out the
+ basics of drag and drop. This article is intended to be read as a companion
+ to the <a href="Article-SWT-DND/DND-in-SWT.html">SWT
+ drag and drop article</a>.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-Mutatis-mutandis/overlay-pages.html">Mutatis
+ mutandis - Using Preference Pages as Property Pages</a></strong> Berthold
+ Daum (bdaum industrial communications) October 24, 2003<br>
+ A common problem in the implementation of applications is the implementation of
+ project-specific properties that override workbench-wide preferences on project or file level. The
+ naive approach is to implement these pages from scratch. However, writing the
+ same code twice is a boring task and leads to increased maintenance efforts. In
+ this article we show how existing preferences pages (with or without field
+ editors) can be easily converted into pages that can act as both preference and
+ property pages. We demonstrate this by implementing the abstract class <code>FieldEditorOverlayPage</code>
+ providing the necessary functionality.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Concurrency/jobs-api.html">
+ On the Job: The Eclipse Jobs API</a></b>&nbsp;Michael Valenta (IBM) September
+ 20, 2004<br>
+ This article looks at the new Jobs API available as part of Eclipse 3.0<b>.</b>
+ It describes the main portions of the Jobs API and the use of scheduling
+ rules. It also describes some changes to Eclipse resource management including
+ how the Resources plug-in integrates with the new API. Finally, it describes
+ some new UI functionality that has been added to provide feedback to users
+ about jobs that are run in the background.</font></td>
+ </tr>
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Team<a name="team"></a></font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><a href="Article-CVS-branching/eclipse_branch.html"><strong>Branching
+ with Eclipse and CVS</strong></a> Paul Glezen </font><font face="arial,helvetica,geneva" size=-1>(IBM)
+ July 3, 2003<br>
+ This article presents a brief branch and merge scenario designed to quickly
+ illustrate some branch and merge features of Eclipse's CVS integration.
+ I assume the reader already appreciates the value of branching and merging
+ in a source control environment. Little is said to justify it here. Rather,
+ a step-by-step scenario illustrates the common branch and merge operations
+ using Eclipse-based IDEs with CVS as the source control mechanism.</font></td>
+ </tr>
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Update<a name="update"></a></font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><a href="Article-Update/keeping-up-to-date.html"><strong>How
+ To Keep Up To Date</strong></a> Dejan Glozic (IBM) and Dorian Birsan (IBM)
+ August 27, 2003<br>
+ This article shows you how to create and publish bundles of plug-ins (called
+ features) to an update site so that customers can download and install them
+ directly into Eclipse using the Eclipse update manager. This has many advantages
+ over the low tech way of delivering new or updated plug-ins in a zip file that
+ someone manually unzips into the directory where Eclipse is installed.</font></td>
+ </tr>
+ <tr>
+ <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">Beyond
+ the Eclipse Platform<a name="other"></a></font></b></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP> <img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><strong><a href="Article-WTP-Persisting-EMF/persisting.html">Persisting
+ EMF models with WTP</a></strong> Daniel Rohe October 10, 2005<br>
+ This article will guide you through an example where an EMF model is created
+ without serialization and the serialization is done with the framework from
+ the WTP plugin org.eclipse.wst.common.emf.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-VE-Custom-Widget/customwidget.html">
+ Extending The Visual Editor</a></b>
+ Dave Orme (db4objects), Gili Mendel (IBM), Joe Winchester (IBM)
+ June 20, 2005
+ <br>
+ This tutorial
+ shows how to extend the Visual Editor to support a custom widget.
+ It covers topics such as adding to the Visual Editor's palette,
+ building a BeanInfo class, and working with
+ EMF .override files to
+ introduce custom editor behavior.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-GEF-EMF/gef-emf.html">
+ Using GEF with EMF</a></b>
+ Chris Aniszczyk (IBM)
+ June 8, 2005
+ <br>
+ The Graphical Editing Framework (GEF) provides a framework for
+ creating visual editors while being model agnostic. In most cases, people
+ bring their own model which tend to be based on Plain Old Java Objects
+ (POJOs). An alternative using POJOs is the Eclipse Modeling Framework
+ (EMF), which provides many features for manipulating models that aren't
+ found in POJOs. The purpose of this article is to build upon the shapes
+ example provided by GEF using the Eclipse Modeling Framework (EMF) and to
+ provide an introduction using EMF based models in GEF based editors.
+ </font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Using%20EMF/using-emf.html">
+ Using EMF</a></b>&nbsp;Catherine Griffin&nbsp;(IBM) December 9, 2002 (updated
+ May 2003 for EMF 1.1)<br>
+ This article introduces EMF, the Eclipse Modelling Framework, and will help
+ you get started using EMF in your own Eclipse plug-ins.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-JET/jet_tutorial1.html">
+ JET Tutorial Part 1 (Introduction to JET)</a></b>&nbsp;Remko Popma (Azzurri
+ Ltd.) July 30, 2003 (updated May 2004 for EMF 2.0)<br>
+ Generating source code can save you time in your projects and can reduce
+ the amount of tedious redundant programming. Generating source code can
+ be powerful, but the program that writes the code can quickly become very
+ complex and hard to understand. One way to reduce complexity and increase
+ readability is to use templates. The Eclipse Modeling Framework (EMF) project
+ contains two very powerful tools for generating source code: JET (Java Emitter
+ Templates) and JMerge (Java Merge). With JET you can use a JSP-like syntax
+ (actually a subset of the JSP syntax) that makes it easy to write templates
+ that express the code you want to generate. JET is a generic template engine
+ that can be used to generate SQL, XML, Java source code and other output
+ from templates. </font>In this article you will learn how to create JET
+ templates, how to use the JET Nature and JET Builder to automatically translate
+ templates into Java classes, and how to use these classes to generate source
+ code. This article also provides a short reference to the JET syntax.</td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-JET2/jet_tutorial2.html">
+ JET Tutorial Part 2 (Write Code that Writes Code)</a></b>&nbsp;Remko Popma
+ (Azzurri Ltd.) August 26, 2003 (updated May 2004 for EMF 2.0)<br>
+ In Part 2 of this JET (Java Emitter Templates) tutorial, we will take a
+ look at the JET engine API. You will learn how to write plug-ins that use
+ the classes in the JET package to generate Java source code. As a real-world
+ example, we will create a plug-in that takes user input and generates a
+ Typesafe Enumeration class. The generated source code is based on a JET
+ template that can be distributed with the plug-in, allowing users of the
+ plug-in to customize the generated code by editing the template. This article
+ also provides a short reference to the JET API.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-GEF-Draw2d/GEF-Draw2d.html">
+ Display a UML Diagram using Draw2D</a></b>&nbsp;Daniel Lee&nbsp;(IBM) August
+ 25, 2003<br>
+ The Graphical Editing Framework (GEF) ships with a painting and layout plug-in
+ called Draw2D. Draw2D provides figures and layout managers which form the
+ graphical layer of a GEF application. This article focuses only on the use
+ of Draw2D to render a simple UML class diagram. While Draw2D can be used
+ for standalone purposes, it is not an editing framework. Most applications
+ will use the GEF plug-in as the editing layer.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b> <a href="Article-GEF-dnd/GEF-dnd.html">Using
+ Native Drag and Drop with GEF</a></b>&nbsp;Eric Bordeau&nbsp;(IBM) August
+ 25, 2003<br>
+ Native drag and drop provides the ability to drag data from one GUI object to another GUI
+ object, which could potentially be in another application. GEF allows access to the operating
+ system's underlying drag and drop infrastructure through SWT. This article will provide an in-depth look at GEF&#39;s drag and drop functionality and show some simple
+ examples of how to take advantage of this API.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-GEF-editor/gef-schema-editor.html">
+ Building a Database Schema Diagram Editor with GEF</a></b>&nbsp;Phil Zoio
+ (Realsolve Solutions) September 27, 2004<br>
+ GEF is a very powerful framework for visually creating and editing models. With a small initial investment,
+ even the relative Eclipse novice can be quickly up and running, building applications with graphical editing capabilities.
+ To illustrate, this article uses a relational database schema diagram editor with a deliberately
+ simplified underlying model, but with enough bells and whistles to show some of the interesting features of GEF at work.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-EMF-goes-RCP/rcp.html">
+ EMF goes RCP</a></b>&nbsp;Marcelo Paternostro (IBM) October 12, 2004<br>
+ This article explains how you can use EMF to generate RCP applications. It assumes
+ that you have already used EMF, or have at least read the articles and references
+ available on the documentation section of the EMF web site.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-Rule%20Modeling%20With%20EMF/article.html">
+ Modeling Rule-Based Systems with EMF</a></b>&nbsp;Chaur G. Wu
+ November 30, 2004<br>
+ There are examples of meta-models defined in ECore for modeling objects and
+ relational data. However, not much has been said about how to model rules. This
+ article will define a meta-model in ECore for modeling rule-based systems. We
+ will then use the meta-model to model the solution of a logical problem. Then
+ we will compose some JET templates and generate code from the model, run the
+ generated code through a rule engine and see that the logical problem is
+ correctly solved.</font></td>
+ </tr>
+ <tr>
+ <td align=RIGHT valign=TOP><img src="images/Adarrow.gif" border=0 height=16 width=16></td>
+ <td><font face="arial,helvetica,geneva" size=-1><b><a href="Article-GEF-diagram-editor/shape.html">
+ A Shape Diagram Editor</a></b>&nbsp;Bo Majewski (Cisco) December 8, 2004<br>
+ Graphical Editing Framework (GEF) provides a powerful foundation for creating
+ editors for visual editing of arbitrary models. Its effectiveness lies in
+ a modular build, fitting use of design patterns, and decoupling of components
+ that comprise a full, working editor. To a newcomer, the sheer number and
+ variety of concepts and techniques present in GEF may feel intimidating. However,
+ once learned and correctly used, they help to develop highly scalable and
+ easy to maintain software. This article aims to provide a gentle yet comprehensive
+ introduction to GEF. It describes a shape diagram editor - a small, fully
+ functional test case of core concepts.</font></td>
+ </tr>
+</table>
+
+</body>
+</html> \ No newline at end of file
diff --git a/preferences/Idea.jpg b/preferences/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/preferences/Idea.jpg
Binary files differ
diff --git a/preferences/badwordpreference.jpg b/preferences/badwordpreference.jpg
new file mode 100644
index 0000000..6b53f4c
--- /dev/null
+++ b/preferences/badwordpreference.jpg
Binary files differ
diff --git a/preferences/colorpreference.jpg b/preferences/colorpreference.jpg
new file mode 100644
index 0000000..5c8d3b9
--- /dev/null
+++ b/preferences/colorpreference.jpg
Binary files differ
diff --git a/preferences/default_style.css b/preferences/default_style.css
new file mode 100644
index 0000000..d725483
--- /dev/null
+++ b/preferences/default_style.css
@@ -0,0 +1,11 @@
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
diff --git a/preferences/preferences.htm b/preferences/preferences.htm
new file mode 100644
index 0000000..cb8b5b3
--- /dev/null
+++ b/preferences/preferences.htm
@@ -0,0 +1,345 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+
+
+<title>Preferences and Properties in the Eclipse Workbench UI</title>
+<link rel="stylesheet" type="text/css" href="default_style.css">
+</head>
+
+<body>
+<DIV align=right>&nbsp; <FONT face="Times New Roman, Times, serif"
+size=2>Copyright © 2001 Object Technology International, Inc.</FONT> </DIV>
+<TABLE border=0 cellPadding=2 cellSpacing=0 width="100%">
+ <TBODY>
+ <TR>
+ <TD align=left bgColor=#0080c0 colSpan=2 vAlign=top><B><FONT
+ face=Arial,Helvetica><FONT color=#ffffff>&nbsp;Eclipse Corner
+ Article</FONT></FONT></B></TD></TR></TBODY></TABLE>
+<H1><img align=center
+src="Idea.jpg" width="120" height="86">
+<center>Preferences in the Eclipse Workbench UI</center></H1>
+<blockquote>
+<b>Summary</b><br>
+In the Eclipse Platform plug-in developers define preference pages for their plug-ins
+for use in the Workbench Preferences Dialog. This article explains when to use a
+preference and some of the features the Eclipse Platform provides to support
+preferences.
+<p><b>By Tod Creasey, OTI<br>
+ </b> December 15, 2001</p>
+</blockquote>
+<HR width="100%">
+
+<h2>Introduction</h2>
+<p>The Eclipse Platform has support for user defined preferences that are
+persisted along with the workbench. This article will discuss what type of data
+should be stored as a preference and will show how to develop and register a
+user interface to allow the user to set these preferences. It will also cover
+how to initialize and retrieve preferences for use by other other plug-ins that
+use your plug-in. This functionality will be shown using an example that
+searches documents for bad words. We will set our preferences for this tool
+using two preference pages, one simple one to set a highlight color and one more
+complex one to set the list of words.
+</p>
+<h2>When to Use a Preference
+</h2>
+<p>A preference is data that is persisted between workbench sessions to allow
+the user to keep the state of a plug-in consistent between Eclipse sessions. Typical preferences are
+default values for new instances, colors for editors and paths, or processing
+information for operations performed on data (such as a build path for a Java&trade;
+file).
+</p>
+<p>Preferences are not intended to reference any resource currently defined in
+the workspace and instead should be used for editors, views or other objects that
+perform operations on a resource. Data persisted on a resource instance is better suited to be
+a property which will be discussed in a later article.
+</p>
+<p>A preference can be made available to any plug-in that has your plug-in as a
+prerequisite. The usual way to do that is to provide API on your plug-in that
+allows for access to the preferences you want to make available. The values of
+these preferences are stored in the .metadata/.plugins directory of the
+workbench on a per plug-in basis. We demonstrate
+how to do this below.
+</p>
+<h2>The Preference Store and the Plug-in</h2>
+<p>Every UI plug-in has it's own preference store provided by the workbench. For
+ this example we will define a plug-in and use its preference store for our preferences.
+ As we are going to use this plug-in within the UI we define it as a subclass
+ of AbstractUIPlugin. Our constructor (see <img border="0" src="tag_2.gif" width="24" height="13">)
+ will create a singleton to allow easy access to the plug-in instance in the
+ workbench. We also implement the method initializeDefaultPreferences() to set
+ up our default values for our two preferences. We are defining a preference
+ for the bad words and a preference for the color of the highlight. Each preference
+ value is looked up using a given key. In the code below the keys we are using
+ are defined by the constants in <img src="tag_1.gif" width="24" height="13">.
+</p>
+<p>The default value should be set for all preferences to be sure that there is
+ a value to use at all times. A default value also ensures that the UI can provide
+ a way to reset a preference value back to a reasonable initial setting via the
+ Restore Defaults button.The default value of the preference should be initialized
+ in the plug-in so that it is set before any of the UI is created.&nbsp; </p>
+<p> IAbstractWorkbenchPlugin defines a method called initializeDefaultPreferences(IPreferenceStore)
+ which is called when the preference store is created the first time. In this
+ method (see <img border="0" src="tag_3.gif" width="24" height="13">) you should
+ set the default value for all values that you will be using the preference store
+ for. We set a default color using the helper methods in the PreferenceConverter
+ which allows the plug-in developer to set and get values for a preference of
+ commonly stored types like FontData, Point etc. This API is provided because
+ preferences are stored and retrieved as Strings in a human readable format in
+ order to leverage the java properties mechanism.&nbsp; Our more complex bad
+ words preference is initialized using a set of preselected bad words defined
+ in the format we are going to store them in as we do not have API on the PreferenceConvertor
+ to store or retreive arrays of Strings.</p>
+<pre>Color color= Display.getDefault().getSystemColor(SWT.COLOR_BLUE);
+PreferenceConverter.setDefault(store, HIGHLIGHT_PREFERENCE, color.getRGB());</pre>
+<pre>public class BadWordCheckerPlugin extends AbstractUIPlugin {
+ //The shared instance.
+ private static BadWordCheckerPlugin plugin;
+
+ //The identifiers for the preferences
+<img border="0" src="tag_1.gif" width="24" height="13"> public static final String BAD_WORDS_PREFERENCE =
+ &quot;org.eclipse.ui.articles.badwordchecker.badwords&quot;;
+ public static final String HIGHLIGHT_PREFERENCE =
+ &quot;org.eclipse.ui.articles.badwordchecker.highlight&quot;;
+
+ //The default values for the preferences
+ public static final String DEFAULT_BAD_WORDS = &quot;bug;bogus;hack;&quot;;
+ public static final int DEFAULT_HIGHLIGHT = SWT.COLOR_BLUE;
+
+ /**
+ * The constructor.
+ */
+ public BadWordCheckerPlugin(IPluginDescriptor descriptor) {
+ super(descriptor);
+<img border="0" src="tag_2.gif" width="24" height="13"> plugin = this;
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static BadWordCheckerPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Initializes a preference store with default preference values
+ * for this plug-in.
+ * @param store the preference store to fill
+ */
+ protected void initializeDefaultPreferences(IPreferenceStore store) {
+<img border="0" src="tag_3.gif" width="24" height="13"> store.setDefault(BAD_WORDS_PREFERENCE, DEFAULT_BAD_WORDS);
+ Color color= Display.getDefault().getSystemColor(DEFAULT_HIGHLIGHT);
+ PreferenceConverter.setDefault(store, HIGHLIGHT_PREFERENCE, color.getRGB());
+
+ }
+}</pre>
+<h2>Defining Preference Pages in plugin.xml</h2>
+<p>Now that we have defined the preference we want to provide a way for the user
+to set the preference value. Preference pages for the workbench can be found in
+the preferences dialog. The preferences dialog is accessible via the Window-&gt;Preferences
+menu group. Plug-in developers should add their preference pages to this dialog using the plugin.xml of their
+plug-in in order to maintain a consistent look and feel with other Eclipse
+plug-ins. The definition of the preference pages within plugin.xml looks like
+this:
+</p>
+<pre>&lt;extension point=&quot;org.eclipse.ui.preferencePages&quot;&gt;
+ &lt;page id=&quot;org.eclipse.ui.articles.BadWordsPreference&quot;
+<img border="0" src="tag_1.gif" width="24" height="13"> name=&quot;Bad Words&quot;
+<img border="0" src="tag_2.gif" width="24" height="13"> class=&quot;org.eclipse.ui.articles.badwordchecker.BadWordsPreferencePage&quot;&gt;
+ &lt;/page&gt;
+
+ &lt;page id=&quot;org.eclipse.ui.articles.BadWordsColorPreference&quot;
+ name=&quot;Colors&quot;
+ class=&quot;org.eclipse.ui.articles.badwordchecker.BadWordsColorPreferencePage&quot;
+<img border="0" src="tag_3.gif" width="24" height="13"> category=&quot;org.eclipse.ui.articles.BadWordsPreference&quot;&gt;
+ &lt;/page&gt;
+&lt;/extension&gt;</pre>
+<p>The definition above sets the name (<img border="0" src="tag_1.gif" width="24" height="13">)
+of the preference page for use in the list
+of pages in the preference dialog and also specifies the class(<img border="0" src="tag_2.gif" width="24" height="13">) to be
+instantiated for creating the preference page. This class must conform to
+IWorkbenchPreferencePage.</p>
+<p>In the second definition there is a category (<img border="0" src="tag_3.gif" width="24" height="13">)
+tag which is used to make one
+page the child of another in the list in the preferences dialog. Preference
+pages can be stored as the children of other pages. This is useful
+for keeping a series of pages together that are related to each other and also
+reduces the clutter in the workbench preferences page. A page can be made the
+child of another page by setting the id of the parent page as the value of the
+category field in the plugin.xml. A page with no parent is displayed as a child
+with no root.</p>
+<p>With the above declarations in our plugin.xml the list of preference pages
+shown in the preference dialog will look like:</p>
+<p align="center"><img border="0" src="tree.jpg" width="179" height="284"></p>
+<p align="center">The Preference Dialog Tree with the Bad Words and Color Page
+Added</p>
+<h2>The Color Preference Page
+</h2>
+<p>The color preference page is an example of a simple page that uses a single
+JFace field editor to manage its values. Initially a preference page class is
+defined.&nbsp; All
+classes used in the preference dialog must conform to IWorkbenchPreferencePage.
+Eclipse includes the class PreferencePage which implements most of the necessary API
+for a preference page. The class definition for our preference page is:</p>
+<pre>BadWordsColorPreferencePage
+ extends PreferencePage
+ implements IWorkbenchPreferencePage</pre>
+<p>Once we have defined the page we want to initialize it.&nbsp; IWorkbenchPreferencePage
+specifies a message init(IWorkbench) for this purpose. We will not use the Workbench
+argument for this page. Our implementation only sets
+the preference store for the page.</p>
+<pre>public void init(IWorkbench workbench) {
+ //Initialize the preference store we wish to use
+ setPreferenceStore(BadWordCheckerPlugin.getDefault().getPreferenceStore());
+}</pre>
+<p>The other required method we must implement is createContents().
+All we are going to do is use a ColorFieldEditor
+to set our preference. It is also suggested that performDefaults is
+implemented so that the current state can be reset to the defaults defined in
+the plug-in. We also need to implement performOK so that the settings defined by the user are
+stored in the preference store for our plug-in. Our
+implementation is simple as the ColorFieldEditor has the code to load defaults
+and store the results of an apply for a preference already defined and performOK
+and performDefaults can call the corresponding methods on ColorFieldEditor.</p>
+<pre>/**
+ * Performs special processing when this page's Restore Defaults button has
+ * been pressed.
+ * Sets the contents of the color field to the default value in the preference
+ * store.
+ */
+protected void performDefaults() {
+ colorEditor.loadDefault();
+}
+/**
+ * Method declared on IPreferencePage. Save the
+ * color preference to the preference store.
+ */
+public boolean performOk() {
+ colorEditor.store();
+ return super.performOk();
+}</pre>
+<p>&nbsp;</p>
+<p align="center"><img border="0" src="colorpreference.jpg" width="598" height="541"></p>
+<p align="center">The Color Preference Page</p>
+<h2>The Bad Words Preference Page
+</h2>
+<p>We have seen how to do a simple preference page with just a color and categorize it.
+Now we will show how to use a complex object as a
+preference and still have it persisted by the preference store and editable in a
+preference page. For this example
+we are going to add a bad words preference which is an array of Strings.
+</p>
+<p>As the PreferenceConverter does not have API for conversion of arrays of
+Strings we will implement it ourselves in the BadWordCheckerPlugin.
+By implementing it in the plug-in we put the API for the use of the preference in
+a place visible to all objects that have access to this plug-in. Normally we
+would use the PreferenceConverter for conversion to and from the storage format.</p>
+<p>Methods for getting the default value of the
+preference and a getter and a setter are
+defined first - getBadWordsDefaultPreference (which returns an array of Strings)&nbsp; getBadWordsPreference (which also returns an array of Strings) and
+setBadWordsPreference which takes an array of Strings as its argument. The
+String array is stored in the preference store as a single string separated by semicolons. We choose
+semicolons as this are only ever used as punctuation and will therefore never
+be part of a word we are searching for.</p>
+<pre>/**
+ * Return the bad words preference default
+ * as an array of Strings.
+ * @return String[]
+ */
+public String[] getDefaultBadWordsPreference(){
+ return convert(getPreferenceStore().getDefaultString(BAD_WORDS_PREFERENCE));
+}
+
+/**
+ * Return the bad words preference as an array of
+ * Strings.
+ * @return String[]
+ */
+public String[] getBadWordsPreference() {
+ return convert(getPreferenceStore().getString(BAD_WORDS_PREFERENCE));
+}
+
+/**
+ * Convert the supplied PREFERENCE_DELIMITER delimited
+ * String to a String array.
+ * @return String[]
+ */
+private String[] convert(String preferenceValue) {
+ StringTokenizer tokenizer =
+ new StringTokenizer(preferenceValue, PREFERENCE_DELIMITER);
+ int tokenCount = tokenizer.countTokens();
+ String[] elements = new String[tokenCount];
+ for (int i = 0; i &lt; tokenCount; i++) {
+ elements[i] = tokenizer.nextToken();
+ }
+
+ return elements;
+}
+
+/**
+ * Set the bad words preference
+ * @param String [] elements - the Strings to be
+ * converted to the preference value
+ */
+public void setBadWordsPreference(String[] elements) {
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i &lt; elements.length; i++) {
+ buffer.append(elements[i]);
+ buffer.append(PREFERENCE_DELIMITER);
+ }
+ getPreferenceStore().setValue(BAD_WORDS_PREFERENCE, buffer.toString());
+}
+</pre>
+<p>There is no field editor defined in JFace
+for&nbsp; editing String arrays so we will define a list that shows the
+items with widgets to add and remove them. Our performOK method will send the
+current contents of the list to the setBadWordsPreference method and the
+performDefaults method will reset the list of strings to be the result of
+getDefaultBadWordsPreference from BadWordCheckerPlugin. As a List widget takes an array of Strings as its
+content we can use the results of these helper methods directly
+in conjunction with the methods we defined for the bad words preference in the
+plug-in. The performOK and performDefaults for this preference page use these
+methods to update the preference and reset the values in the list widget.
+</p>
+<pre>/**
+ * Performs special processing when this page's Restore Defaults button has been pressed.
+ * Sets the contents of the nameEntry field to
+ * be the default
+ */
+protected void performDefaults() {
+ badWordList.setItems(BadWordCheckerPlugin.getDefault().getDefaultBadWordsPreference());
+}
+/**
+ * Method declared on IPreferencePage. Save the
+ * author name to the preference store.
+ */
+public boolean performOk() {
+ BadWordCheckerPlugin.getDefault().setBadWordsPreference(badWordList.getItems());
+ return super.performOk();
+}</pre>
+<p align="center"><img border="0" src="badwordpreference.jpg" width="596" height="539">
+</p>
+<p align="center">The Bad Word Preference Dialog
+</p>
+<h2>Conclusions
+</h2>
+<p>In this article we have demonstrated how to use the preferences store and
+preferences pages provided by Eclipse to allow a plug-in to maintain and update
+preferences between Eclipse sessions. By use of the preference store in
+conjunction with the preferences dialog and provided field editors a plug-in
+developer can quickly put together a user interface for managing preferences. To
+find out more about the preferences that Eclipse provides see the Platform
+Plug-in Developers Guide in the Help Perspective. The help information is in the
+Programmers Guide Preferences and Properties section.
+</p>
+<p>The full implementation of the example in this article can be found in <a href="preferences.zip">preferences.zip</a>.
+</p>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+
+</body>
+
+</html>
diff --git a/preferences/preferences.zip b/preferences/preferences.zip
new file mode 100644
index 0000000..1ae7b43
--- /dev/null
+++ b/preferences/preferences.zip
Binary files differ
diff --git a/preferences/readme.txt b/preferences/readme.txt
new file mode 100644
index 0000000..8481ea4
--- /dev/null
+++ b/preferences/readme.txt
@@ -0,0 +1,12 @@
+Aug. 15/2002
+
+The preference article has been revised for Eclipse 2.0.
+The new version of the article is in the folder named "Article-Preferences".
+
+This folder has been left in place for the benefit of anyone that has linked to
+"articles/preferences/preferences.htm". These links should be replaced by
+"articles/Article-Preferences/preferences.htm".
+
+This folder should be deleted 1Q2003.
+
+---jeem \ No newline at end of file
diff --git a/preferences/tag_1.gif b/preferences/tag_1.gif
new file mode 100644
index 0000000..4859d6f
--- /dev/null
+++ b/preferences/tag_1.gif
Binary files differ
diff --git a/preferences/tag_2.gif b/preferences/tag_2.gif
new file mode 100644
index 0000000..5ea43dc
--- /dev/null
+++ b/preferences/tag_2.gif
Binary files differ
diff --git a/preferences/tag_3.gif b/preferences/tag_3.gif
new file mode 100644
index 0000000..a69b68e
--- /dev/null
+++ b/preferences/tag_3.gif
Binary files differ
diff --git a/preferences/tree.jpg b/preferences/tree.jpg
new file mode 100644
index 0000000..3c9088e
--- /dev/null
+++ b/preferences/tree.jpg
Binary files differ
diff --git a/product-guide/TryIt.gif b/product-guide/TryIt.gif
new file mode 100644
index 0000000..f4927a4
--- /dev/null
+++ b/product-guide/TryIt.gif
Binary files differ
diff --git a/product-guide/default_style.css b/product-guide/default_style.css
new file mode 100644
index 0000000..0c5a763
--- /dev/null
+++ b/product-guide/default_style.css
@@ -0,0 +1,12 @@
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
+.legalfootnote { font-family: Arial, Helvetica, sans-serif; font-size: xx-small}
diff --git a/product-guide/final.jpg b/product-guide/final.jpg
new file mode 100644
index 0000000..f8ff613
--- /dev/null
+++ b/product-guide/final.jpg
Binary files differ
diff --git a/product-guide/guide.html b/product-guide/guide.html
new file mode 100644
index 0000000..f37ccce
--- /dev/null
+++ b/product-guide/guide.html
@@ -0,0 +1,854 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (Win98; I) [Netscape]">
+ <meta name="Author" content="Greg Adams">
+ <title>Creating product branding</title>
+ <link rel="stylesheet" href="default_style.css">
+</head>
+<body>
+
+<div align=right><font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2001 Object Technology International, Inc.</font></font></div>
+<div ALIGN=right><table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table></div>
+
+<h1>
+<img SRC="idea.jpg" height=86 width=120></h1>
+
+<center>
+<h1>
+Creating product branding</h1></center>
+
+<blockquote><b>Summary</b> <br>
+ In this document we will look at the steps needed to create a product. Before
+ we get too excited hoping the magic of product building will be revealed,
+ we should first confess that we will focus only on those aspects of the platform
+ which you will need to modify in order to give your product some branding.
+ This will include such items as the splash screen, about dialog, the program
+ executable and so forth.
+ <p><b>By Greg Adams, OTI</b> <br>
+ <font size=-1>November 27, 2001</font>
+ <p>Editor's note: This article describes Eclipse release 1.0. All aspects of
+ product branding were completely revamped for Eclipse release 2.0; an updated
+ version of this article is in preparation.
+</blockquote>
+<hr WIDTH="100%">
+
+<h2>The high level picture</h2>
+<p>You have written all the code and now it is time to bundle up your code with
+ the platform and change the identity to have your product brand. Before diving
+ into the details of each step let's take a sneak peak at the big picture and
+ get a flavor for the kinds of things we'll be doing. The high level steps are
+ as follows:</p>
+<ol>
+ <li>Replace the product level graphics (e.g. splash screen)</li>
+ <li>Create graphics for the executable</li>
+ <li>Create a new executable</li>
+ <li>Create a product configuration </li>
+ <li>Create a product plug-in corresponding to the configuration</li>
+ <li>Update the install information to use your new configuration.</li>
+ <li>Remove any existing license information</li>
+</ol>
+<p>As you work through the steps you may notice the occasional <b><img src="TryIt.gif" width="61" height="13"></b>.
+ These indicate points at which you may want to test out the work you have done
+ thus far. Once you have completed the test be sure to delete the <i>eclipse/workspace</i>
+ directory thus ensuring that the next test starts with a fresh state. Once you
+ have mastered the steps you should do a final run through the steps (starting
+ with a clean install) but be sure to skip the &quot;try it&quot; steps. These
+ steps require you to run the platform and consequently will cause information
+ to be cached. Your actual product production process should not run the platform
+ runtime.</p>
+<p>The steps in this document assume that you have the <i>runtime</i> build of
+ the platform installed on your machine. In some cases you will require access
+ to the SDK build but it is important to note that we will be working with and
+ modifying the platform build. In the remaining sections we assume that you have
+ a working knowledge of plug-ins.</p>
+<p>Before continuing make sure that you have installed a platform runtime build
+ and installed into it all of your own plug-ins. You should not consider branding/productization
+ unless you are also including your own plug-ins.</p>
+<p>This article is intended to be a guide to help you produce a release. You need
+ to ensure that you comply with any terms and conditions of the license under
+ which you received the platform runtime.</p>
+<p>&nbsp;</p>
+<h2>Replacing the splash screen</h2>
+<p>The splash screen (shown while the program starts) is contained in two files
+ found in the <i>eclipse/splash</i> directory. You must replace both of these
+ files with your product splash screens. The file <i>splash_basic</i> and <i>splash_full</i>
+ correspond to low color and high color versions of the splash screen. The low
+ color splash screen is used only when the display (color) depth is less than
+ or equal to eight. Typically most displays have sufficient color depth support
+ to allow the high color splash to be used. </p>
+<p><img src="win_only.gif" width="51" height="13"> On Windows&reg; replace the following
+ two files (in eclipse/splash) with your splash screen files: </p>
+<ul>
+ <li>splash_basic.bmp </li>
+ <li>splash_full.bmp </li>
+</ul>
+<p><img src="linux_only.gif" width="51" height="13"> On Linux replace the following
+ two files (in eclipse/splash) with your splash screen files:</p>
+<ul>
+ <li>splash_basic.xpm</li>
+ <li>splash_full.xpm</li>
+</ul>
+<p>&nbsp;</p>
+<p><b><img src="TryIt.gif" width="61" height="13"> </b>Start the program and confirm
+ that your splash screen is shown. Exit the program. Don't forget to delete the
+ <i>eclipse/workspace </i>directory thus ensuring things are in a completely
+ fresh state for our next test.</p>
+<p>&nbsp;</p>
+<h2>Creating the graphics for our executable</h2>
+<p>The executable is located in the <i>eclipse/ </i>root directory and the process
+ for replacing it is platform specific. Start by extracting the file <i>eclipse/launchersrc.zip
+ </i>found in the SDK and opening the resulting <i>library </i>subdirectory<i>.
+ </i>In the following sections, we will work with the <i>library/</i> directory
+ and once we are finished we will copy the resulting executable back to the runtime
+ platform build. This is the only time you will require access to files found
+ in the SDK.</p>
+<p><b><img src="win_only.gif" width="51" height="13"> </b>On Windows executable
+ programs can have an associated icon(s). To create our icon we first need to
+ replace several .BMP graphics located in the <i>library </i>directory<i>. </i>These
+ graphics represent 16x16, 32x32 and 48x48 pixel versions of both low color and
+ high color graphics. In the <i>library/ </i>directory replace the following
+ files:</p>
+<ul>
+ <li>icon16_basic.bmp</li>
+ <li>icon16_full.bmp</li>
+ <li>icon32_basic.bmp</li>
+ <li>icon32_full.bmp</li>
+ <li>icon48_basic.bmp</li>
+ <li>icon48_full.bmp</li>
+</ul>
+<p>Using an appropriate graphics tool (e.g. ICONPRO provided in the MSDN) of your
+ choice, combine these graphics into a single .ICO (icon) file called<i> eclipse.ico</i>
+ and replace <i>library/eclipse.ico</i> with your new eclipse.ico file. The <i>eclipse.ico</i>
+ is referenced by the file<i> library/eclipse.rc</i> which is automatically used
+ when the executable build script is run. Once the build script has finished
+ we will have a new program executable with an associated icon.</p>
+<p><img src="linux_only.gif" width="51" height="13"> Linux does not directly associate
+ an icon with an executable program however we can include an icon that users
+ can use when associating a shortcut with the program. Create yourself an xpm
+ graphic (representing your program icon) using your favorite graphics editor
+ and place it into <i>library/icon.xpm. </i>Once we have built the executable
+ we will copy both the executable and the <i>.xpm </i>file to the <i>eclipse/</i>
+ root directory of the platform runtime build.</p>
+<h2>&nbsp;</h2>
+<h2>Creating a new executable program</h2>
+<p>Executable icon in hand, it's time to make the executable. We will continue
+ to work with the <i>library/ </i>directory and once we have created our executable
+ we will copy it to the <i>eclipse/</i> root directory of the runtime platform
+ build. The process for creating the program executable is different for each
+ platform however the <i>library/</i> directory includes build scripts to help
+ make the process easier.</p>
+<h3><b>Preparing the build script</b></h3>
+<p><img src="win_only.gif" width="51" height="13"> In the <i>library/</i> directory
+ you will find the build script <i>build.bat</i>. We will need to edit this build
+ file to point it to the location of your compiler. To do this, simply uncomment
+ the following lines (by removing <i>rem</i>) and modify <i>MSVC_HOME </i>to
+ point to the root directory of your compiler installation.</p>
+<blockquote>
+ <pre>rem IF NOT &quot;%MSVC_HOME%&quot;==&quot;&quot; GOTO MAKE
+rem set MSVC_HOME=k:\dev\products\msvc60\vc98
+rem call %MSVC_HOME%\bin\vcvars32.bat</pre>
+</blockquote>
+<p>This script has been tested with Microsoft&reg; Visual C/C++ Compiler 6.0 however
+ it is possible that you may need to make additional modifications for your compiler.
+ If you are using Windows 98 you will also need to remove the line<i> rem Usage:
+ build &lt;PROGRAM_OUTPUT&gt; &lt;PROGRAM_NAME&gt;</i> to work around a known
+ problem.</p>
+<p><img src="linux_only.gif" width="51" height="13"> On Linux, the build script
+ (<i>build.csh)</i> has been tested against GNU C and C++ Compiler. You typically
+ should not need to make any changes to the Linux build script.</p>
+<p>&nbsp;</p>
+<h3><b>Running the build script</b></h3>
+<p>The build script takes two arguments, the filename of the executable file to
+ create and the title (name) of your program. If the program name has spaces
+ in it (as in the example below) you will need to put double-quotes around it.
+</p>
+<p>In the example below the program name <i>Cool Stuff &nbsp;</i>will be shown
+ in the task bar while the program is starting. As we will soon learn the icon
+ shown in the top left corner of each Workbench window is set separately and
+ is unrelated to the icons specified for the executable.</p>
+<p><img src="win_only.gif" width="51" height="13"> On Windows you can run the
+ build script (<i>build.bat)</i> as shown below. Prior to running the build script
+ you should delete any <i>.res</i> files from the <i>library</i> directory. These
+ files will typically only be present if you have run the build script previously.
+ This example will create an executable file named <i>cool.exe</i> with the icon
+ we created above.</p>
+<blockquote>
+ <pre>build cool.exe &quot;Cool Stuff&quot;</pre>
+</blockquote>
+<p><img src="linux_only.gif" width="51" height="13"> On Linux you can run the
+ build script (<i>build.csh)</i> as shown below. This example will create an
+ executable file named <i>cool</i>. On Linux an icon is not automatically associated
+ with the executable.</p>
+<blockquote>
+ <pre>csh build.csh cool &quot;Cool Stuff&quot;</pre>
+</blockquote>
+<p>&nbsp;</p>
+<h3><b>Replacing the existing executable</b> </h3>
+<p>Now that you have your own executable, you can copy it to the <i>eclipse/</i>
+ root directory of the runtime platform build. Next, delete the current executable
+ from the <i>eclipse/ </i>root directory. If you forget to delete the existing
+ executable a user will not know which executable to run so its important not
+ to forget this little step.</p>
+<p><img src="linux_only.gif" width="51" height="13"> On Linux we also need to
+ copy the <i>icon.xpm </i>(we created above) to the <i>eclipse/ </i>root replacing
+ the one already found there. </p>
+<p>&nbsp;</p>
+<p><b><img src="TryIt.gif" width="61" height="13"> </b>Let's give it a whirl!
+ Go to the<i> eclipse/</i> root directory of the runtime platform build and start
+ the program by running your executable. Confirm that your executable properly
+ starts, that your icons and program name are shown in the appropriate places
+ and that your splash screen is still shown. Don't worry about the icon or title
+ in the resulting Workbench window we'll fix those in a later section. Exit the
+ program. Don't forget to delete the <i>eclipse/workspace </i>directory thus
+ ensuring things are in a completely fresh state for our next test.</p>
+<p>&nbsp;</p>
+<h2>Create a product configuration</h2>
+<p>A product configuration and its corresponding plug-in define several key product
+ attributes including the icon and title shown in each window, the welcome page,
+ about dialog information and much more. Product configurations are defined in
+ the <i>eclipse/install/configurations </i>directory. If you take a glance at
+ this directory you will likely observe more than one product configuration.
+ Which one defines the product? The answer lies in the file <i>eclipse/install/install.properties
+ </i> that specifies which configuration is the <i>dominant</i> configuration.
+ At any given time only one configuration is the dominant configuration. Each
+ configuration also has a corresponding plug-in directory. We will start by finding
+ the dominant configuration and then proceed to create a new product configuration
+ and corresponding plug-in. Finally we will update the <i>install.properties</i>
+ file to point to the new configuration. </p>
+<h3><b>Discovering the dominant configuration</b> </h3>
+<p>Open the file <i>eclipse/install/install.properties</i> and go to the line
+ with <b>application.configuration = .</b> The information appearing on the right
+ hand side is the name (id and version) of the current <i>dominant</i> configuration.
+ Typically the <b>application.configuration</b> has the form <i>xyz_version</i>.
+ For example <i>xyz_1.0.0</i> indicates the configuration id is <i>xyz</i> and
+ the version level is <i>1.0.0</i>. </p>
+<p>Now that we know the name (id and version) of the dominant configuration take
+ another look at the <i>eclipse/install/configurations </i>directory<i>. </i>You
+ should see a subdirectory with the same name as the dominant configuration name.
+ For example if <i>install.properties </i>had the line <b>application.configuration
+ = xyz_1.0.0 </b>then we should expect to see a directory <i>xyz_1.0.0</i>. In
+ addition you should find a plug-in (in <i>eclipse/plugins</i>) with the exact
+ same name as the configuration directory. </p>
+<p>Make a note of the dominant configuration name (id and version) because we'll
+ want to copy both the configuration and the plug-in directories in the following
+ sections.</p>
+<h3><b>Choosing a name for our configuration</b></h3>
+<p>You may recall (from the section on creating the executable) that the name
+ of our program is &quot;Cool Stuff&quot;. To make things easier to follow let's
+ assume the id we want to give to our configuration and plug-in is <i>org.cool.stuff</i>
+ and the version number is <i>1.0.0</i>. Consequently our configuration and plug-in
+ directories will have the name <i>org.cool.stuff_1.0.0</i> and ultimately we
+ will edit the <i>install.properties</i> file to have application.configuration
+ <b>= </b>org.cool.stuff_1.0.0. </p>
+<h3><b></b> <b>Creating the configuration</b> </h3>
+<p>Open the <i>eclipse/install/configurations </i>directory and copy the current
+ dominant configuration (recall we recorded its name above) to a directory of
+ your own naming. For our example we need to copy the dominant configuration
+ to a directory named to <i>eclipse/install/configurations/<b>org.cool.stuff_1.0.0</b></i>.
+ It is important that you copy the directory, you must not simply rename the
+ existing dominant configuration directory. </p>
+<p>Next edit the file <i>install.xml</i> found in the new configuration directory.
+ You will need to edit the fields (lines) as follows:</p>
+<table width="80%" border="1" cellspacing="0" cellpadding="0">
+ <tr bgcolor="#CCCCCC">
+ <td width="30%"><b>Field</b></td>
+ <td width="80%"><b>Editing Instructions</b></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td width="20%"><b>label</b></td>
+ <td width="70%">Change this to be the name of your product (e.g. Cool Stuff)</td>
+ </tr>
+ <tr align="left" valign="top">
+ <td width="20%"><b>id</b></td>
+ <td width="80%">Change this to match the unique name of your configuration
+ (e.g. org.cool.stuff)</td>
+ </tr>
+ <tr align="left" valign="top">
+ <td width="20%"><b>version</b></td>
+ <td width="80%">Change this to the appropriate version number of your configuration
+ (e.g. 1.0). Note that 1.0 can be used in place of 1.0.0.</td>
+ </tr>
+ <tr align="left" valign="top">
+ <td width="20%"><b>provider-name</b></td>
+ <td width="80%">Change this to be the name of your company.</td>
+ </tr>
+ <tr align="left" valign="top">
+ <td width="20%"><b>description</b></td>
+ <td width="80%">Change this to be a description of the configuration.</td>
+ </tr>
+</table>
+<p>The following example shows what the<i> install.xml </i>file would look like
+ for the Cool example. </p>
+<blockquote>
+ <pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
+&lt;configuration
+ label=&quot;Cool Stuff&quot;
+ id=&quot;org.cool.stuff&quot;
+ version=&quot;1.0&quot;
+ provider-name=&quot;Cool Stuff Company&quot;&gt;</pre>
+ <pre> &lt;description&gt;
+ The Cool Stuff Configuration
+ &lt;/description&gt;<br>&lt;/configuration&gt;</pre>
+</blockquote>
+<p>&nbsp;</p>
+<h2><b>Create a plug-in</b> corresponding to the configuration</h2>
+<p>Every configuration has a corresponding plug-in. The name of the plug-in directory
+ is identical to the name of the configuration directory. Since our configuration
+ directory was named org.cool.stuff_1.0.0 we will create a plug-in with the same
+ name. </p>
+<p>Open the <i>eclipse/plugins </i>directory and copy the plug-in corresponding
+ to current dominant configuration (see above) to a directory matching the name
+ of your configuration (e.g. <i>org.cool.stuff_1.0.0</i>). It is important that
+ you copy the directory, you must not simply rename the existing dominant configuration
+ plug-in directory. </p>
+<p>Your new plug-in directory should contain the following files. If you do not
+ see all of these files, you may have copied a regular plug-in directory instead
+ of the plug-in directory corresponding to the dominant configuration.</p>
+<ol>
+ <ol>
+ <li>plugin.xml</li>
+ <li>plugin.properties</li>
+ <li>about.html</li>
+ <li>product.ini</li>
+ <li>product.properties</li>
+ <li>about_prod.gif</li>
+ <li>about_prod_basic.gif</li>
+ <li>prod.gif</li>
+ <li>prod_basic.gif</li>
+ <li>welcome.xml</li>
+ <li>platform.ini</li>
+ <li>platform.properties</li>
+ </ol>
+</ol>
+<p>Files 1-3 you might recognize because they appear in most other plugins. Files
+ 4-10 are unique to plug-ins corresponding to configurations. These represent
+ product attribution information including icon and title for Workbench windows,
+ graphics and text for the about dialog, and the text of the welcome page. Files
+ 11-12 (<i>platform.ini</i> and <i>platform.properties</i>) are also unique however
+ these <b>must not</b> be edited.</p>
+<h3>Editing the standard files plug-in</h3>
+<p>Let's start by modifying files 1-3 which are the three standard files <i>(plugin.xml,
+ plugin.properties and about.html) </i>found in most plug-ins.</p>
+<p><b>plugin.xml</b></p>
+<p>Edit the fields of plugin.xml as follows:</p>
+<table width="80%" border="1" cellspacing="0" cellpadding="0">
+ <tr bgcolor="#CCCCCC">
+ <td width="30%"><b>Field</b></td>
+ <td width="70%"><b>Editing Instructions</b></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td width="20%"><b>id</b></td>
+ <td width="80%">Change this to match the id of your configuration (e.g. <i>org.cool.stuff</i>).
+ Do not include the version number of your configuration.</td>
+ </tr>
+ <tr align="left" valign="top">
+ <td width="20%"><b>version</b></td>
+ <td width="80%">Change this to match the version number of your configuration
+ (e.g. 1.0). Note that 1.0 can be used in place of 1.0.0.</td>
+ </tr>
+ <tr align="left" valign="top">
+ <td width="20%"><b>Provider-name</b></td>
+ <td width="80%">Change this to be the name of your company.</td>
+ </tr>
+ <tr align="left" valign="top">
+ <td width="20%"><b>name</b></td>
+ <td width="80%">Do not edit this field. It has been externalized and will
+ edit the plugin.properties file next.</td>
+ </tr>
+</table>
+<p>The <i>plugin.xml</i> file for our Cool example should appear as follows:</p>
+<blockquote>
+ <pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;plugin
+ id=&quot;org.cool.stuff&quot;
+ name=&quot;%pluginName&quot;
+ version=&quot;1.0&quot;
+ provider-name=&quot;Cool Stuff Company&quot;&gt;
+&lt;/plugin&gt;</pre>
+</blockquote>
+<p><b>plugin.properties</b></p>
+<p>Notice that while editing the <i>plugin.xml</i> file we did not modify the
+ <b>name</b> field. This is because the name field has been externalized into
+ <i>plugin.properties</i>. Open <i>plugin.properties</i> and edit the <b>pluginName</b>
+ field. Our Cool example's <i>plugin.properties</i> file is as follows:</p>
+<blockquote>
+ <pre>pluginName = Cool Stuff Plug-In</pre>
+</blockquote>
+<p><b>about.html</b></p>
+<p> The last file commonly found in most plug-ins is <i>about.html</i>. This HTML
+ file allows you to provide any arbitrary information about your plug-in or company.
+ Some plug-in suppliers opt to include links to their company sites. A user can
+ view a plug-in's about.html by opening the About dialog from the Workbench's
+ Help menu and clicking &quot;Plugin Info...&quot; to open a dialog listing all
+ of the installed plug-ins. Selecting a plug-in and clicking &quot;More Info...&quot;
+ displays the plug-in's about.html.</p>
+<p>Edit the about.html file to include any interesting information about your
+ plug-in.</p>
+<p><b><img src="TryIt.gif" width="61" height="13"> </b>We have created a configuration
+ and its corresponding plug-in. We haven't wired in our configuration but we
+ can do a quick test to see that our plug-in and its about.html show up correctly
+ in the Workbench's About dialog. Start the platform and open the About dialog
+ (from the Workbench's Help menu). Click on the &quot;Plugin Info...&quot; button
+ and confirm the plug-in name, provider and version number are correct for your
+ plug-in (i.e. correspond to the values you entered above). Next select the plug-in
+ and choose &quot;More Info..&quot;. and confirm the contents of your about.html
+ are properly displayed. Exit the program. Don't forget to delete the <i>eclipse/workspace
+ </i>directory thus ensuring things are in a completely fresh state for our next
+ test.</p>
+<h3><b>Editing the plug-in product files</b></h3>
+<p>Plug-in's corresponding to configurations contain two special files, <i>product.ini</i>
+ and <i>product.properties</i>. These files provide product level information.
+ The latter of these (<i>product.properties</i>) contains strings externalized
+ from the <i>product.ini</i>. The configuration plug-in also contains two other
+ files, <i>platform.ini</i> and <i>platform.properties</i>, these files <b>must
+ not </b>be modified. These files are reserved for the platform itself.</p>
+<p><b>product.ini</b></p>
+<p>Although you are allowed to edit any field in product.ini it is strongly recommended
+ that you follow the advice provided below. There are several fields which are
+ either unnecessary to modify, or have potentially serious implications if you
+ modify them (e.g. <b>application</b>). Some fields have been externalized from
+ <i>product.ini</i> consequently we will edit them by modifying <i>product.properties</i>.
+ Fields referencing graphics (e.g. product icon, about graphic) do not need to
+ be altered, because we will replace their corresponding graphic files in subsequent
+ sections. </p>
+<table width="100%" border="1" cellspacing="0" cellpadding="0">
+ <tr bgcolor="#CCCCCC">
+ <td><b>Field</b></td>
+ <td><b>Editing Instructions</b></td>
+ <td><b>Where is it shown</b></td>
+ </tr>
+ <tr valign="top" align="left">
+ <td><b>name</b></td>
+ <td>Change this to match the name of your product (e.g. Cool Stuff). If your
+ product name is lengthy you may want to use a shorter version of it for
+ this field. The value of this field is shown in the title of Workbench windows.</td>
+ <td>Workbench windows</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td>detailedName</td>
+ <td>Do not edit this field since it has been externalized. We will edit it
+ by changing <i>product.properties</i>. Typically this field is the same
+ as the <i>name</i> field however if your product name is lengthy you may
+ opt to use the <i>name</i> field for a shorter version of the product name.</td>
+ <td>About dialog</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td>image</td>
+ <td>Do not edit this field. We will replace prod.gif with our product graphic.</td>
+ <td>Workbench windows (icon in top left corner of window)</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td>image_basic</td>
+ <td>Do not edit this field. We will replace prod_basic.gif with our product
+ graphic.</td>
+ <td>Workbench windows (icon in top left corner of window). This image is only
+ shown for low color displays.</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td><b>Version</b></td>
+ <td>Change this to match the version number of your product. This string is
+ a &quot;pretty&quot; name (e.g. R1.0, Beta-1) that will appear in the Workbench's
+ about dialog. It does not have to match the configuration version number
+ or plug-in version number. </td>
+ <td>About dialog</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td>application</td>
+ <td>Do not edit this field. There are very small set of cases under which
+ this needs to be edited (e.g. headless product). Before attempting to edit
+ this field you should thoroughly read the Platform Plug-in Developer Guide.
+ In addition, modifying this attribute may prevent other third party plug-ins
+ from running. </td>
+ <td>N/A</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td><b>productURL</b></td>
+ <td>Change this to be your company or product URL (e.g. http://www.cool-stuff.org)</td>
+ <td>Currently this field is not automatically shown. Consequently many product
+ teams include a URL in their copyright text (see product.properties below).
+ </td>
+ </tr>
+ <tr valign="top" align="left">
+ <td>aboutImage</td>
+ <td>Do not edit this field. We will replace about_prod.gif with our about
+ graphic.</td>
+ <td>About dialog (large graphic in top left corner)</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td>aboutImage_basic</td>
+ <td>Do not edit this field. We will replace about_prod_basic.gif with our
+ graphic.</td>
+ <td>About dialog (large graphic in top left corner). This image is only shown
+ for low color displays.</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td>welcomePage</td>
+ <td>Do not edit this field. We will replace welcome.xml with our own welcome
+ page.</td>
+ <td>Shown in the welcome page.</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td><b>baseInfosets</b></td>
+ <td>This field identifies the id's of infosets (documentation books) and the
+ order they should be shown in the Workbench's help system. You can edit
+ this list to include the books appropriate to your product, and alter the
+ order as necessary.</td>
+ <td>Help perspective and associated views.</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td><b>defaultPerspectiveId</b></td>
+ <td>Change this field to be the perspective the Workbench should initially
+ show. By default the Resources perspective is shown.</td>
+ <td>N/A</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td>copyright</td>
+ <td>Do not edit this field since it has been externalized. We will change
+ it by editing <i>product.properties</i>.</td>
+ <td>About dialog.</td>
+ </tr>
+ <tr valign="top" align="left">
+ <td><b>buildID</b></td>
+ <td>Change this field to describe the build number of your product build (e.g.
+ 2.100). The build version is shown in the Workbench's About dialog. </td>
+ <td>About dialog.</td>
+ </tr>
+</table>
+<p>Following is the product.ini file for our Cool example. The fields we have
+ changed for the purpose of the example have been marked in bold. For the sake
+ of illustration the PDE infoset has been moved to be the first infoset listed
+ in <i>baseInfosets. </i>The default perspective has been left unchanged.</p>
+<blockquote>
+ <pre> <b>name</b> = Cool Stuff
+ detailedName = %detailedName
+ image = prod.gif
+ image_basic = prod_basic.gif
+ <b>version</b> = R1.0 Sneak Peak
+ application = org.eclipse.ui.workbench
+ <b>productURL</b> = http://www.cool-and-neat-stuff.org
+ aboutImage = about_prod.gif
+ aboutImage_basic = about_prod_basic.gif
+ welcomePage = welcome.xml
+ <b>baseInfosets</b> = org.eclipse.pde.doc.user.infoset_Guide,\
+ org.eclipse.platform.doc.user.infoset_Guide,\
+ org.eclipse.jdt.doc.user.infoset_Guide,\
+ org.eclipse.platform.doc.isv.infoset_Guide,\
+ org.eclipse.jdt.doc.isv.infoset_Guide
+ defaultPerspectiveId = org.eclipse.ui.resourcePerspective
+ copyright = %copyright
+ <b>buildID</b> = 2.345</pre>
+</blockquote>
+<p><b>product.properties</b></p>
+<p>While we were editing the above product.ini file there were several fields
+ we skipped over because they had been externalized. The time has come to edit
+ those fields by editing them in the file <i>product.properties</i> as follows:<br>
+</p>
+<table width="100%" border="1" cellspacing="0" cellpadding="0">
+ <tr bgcolor="#CCCCCC">
+ <td width="20%"><b>Field</b></td>
+ <td width="80%"><b>Editing Instructions</b></td>
+ <td width="80%"><b>Where is it shown</b></td>
+ </tr>
+ <tr>
+ <td width="20%">detailedName</td>
+ <td width="80%">Change this to match the name of your product (e.g. Cool Stuff).
+ </td>
+ <td width="80%">About dialog</td>
+ </tr>
+ <tr>
+ <td width="20%">copyright</td>
+ <td width="80%">Change this to be the copyright text for your application.
+ You can use \n and \ (line continuation) for lengthy copyright messages.
+ You may also want to include a URL in your copyright text.</td>
+ <td width="80%">About dialog</td>
+ </tr>
+</table>
+<p>The <i>product.properties</i> file for our Cool example might look something
+ like this. <br>
+</p>
+<blockquote>
+ <pre>
+copyright = (c) Copyright Cool and Neat Stuff\n\
+ \n\
+ Visit the website at http://www.cool-and-neat-stuff.org\n\
+detailedName = Cool Stuff for Developers </pre>
+</blockquote>
+<h3>Editing the welcome page</h3>
+<p>The next plug-in file we need to edit is <i>welcome.xml. </i>When the Workbench
+ first opens you may recall seeing a Welcome page displayed. This page is defined
+ by the file <i>welcome.xml</i> found in the dominant configuration's corresponding
+ plug-in. The purpose of the Welcome page is to provide initial introductory
+ information to help a user get started. Here is the <i>welcome.xml</i> for our
+ Cool example. For additional information on the types of things you can include
+ in the <i>welcome.xml</i> consult the Platform Plug-in Develop Guide.</p>
+<blockquote>
+ <pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
+&lt;welcomePage
+ title=&quot;Welcome to Cool Stuff&quot;&gt;
+ &lt;intro&gt;This page will help familiarize you with many fun things.
+To get started, read the section below and click on the related links. &lt;/intro&gt;</pre>
+ <pre>&lt;item&gt;&lt;b&gt;Create your first cool thing &lt;/b&gt;
+To begin doing cool things you need to start by creating a cool project
+and then creating several cool files.
+&lt;/item&gt;
+&lt;/welcomePage&gt;</pre>
+</blockquote>
+<p>&nbsp;</p>
+<h3><b>Updating some more graphics</b></h3>
+<p>The last thing we need to do with our plug-in is to replace several of the
+ graphics files. The graphics we are replacing are those referenced from the
+ <i>product.ini</i> by the fields: image, image_basic, aboutImage and aboutImage_basic.
+ Files with the suffix &quot;basic&quot; represent low color graphics.</p>
+<p>Replace the following graphic files that are used to provide the icon for the
+ top left corner of every window.</p>
+<ul>
+ <li>prod.gif</li>
+ <li>prod_basic.gif</li>
+</ul>
+<p></p>
+<p></p>
+<p>Replace the following graphic files that are used for the large graphic in
+ the top left corner of the about dialog.</p>
+<ul>
+ <li>about_prod.gif</li>
+ <li>about_prod_basic.gif</li>
+</ul>
+<p></p>
+<h2>&nbsp;</h2>
+<h2><b>Updating the install.properties to use our configuration</b></h2>
+<p>We have our configuration and after a number of edits and file replacements
+ we hopefully have a corresponding plug-in. Now comes the moment of truth as
+ we edit the<i> install.properties</i> file to point to our new configuration.
+ Edit <i>eclipse/install/install.properties </i>and change the <b>application.configuration
+ </b>line to point to the new configuration. You may recall (from above) the
+ <b>application.configuration</b> has the form <i>xyz_version</i>. For example
+ <i>xyz_1.0.0</i> indicates the configuration name is <i>xyz</i> and the version
+ level is <i>1.0.0</i>. For our Cool example the line will need to be:</p>
+<blockquote>
+ <pre>application.configuration=org.cool.stuff_1.0.0</pre>
+</blockquote>
+<p>Remove any other lines that may exist in <i>install.properties</i>. If you
+ have done any of the earlier &quot;try it&quot; tests, you may have additional
+ lines in <i>install.properties </i>representing cached information. In addition,
+ if there is a cached file<i> update.cfg</i> you should delete this. There may
+ be additional files in this directory (also cached by the platform) but you
+ do not need to worry about them.</p>
+<h2>&nbsp;</h2>
+<h2>License and notice</h2>
+<p>You should check legal notices such as: license.html, notice.html, cpl-v05.html
+ and the about.html files in the root directory and plugin subdirectories to
+ make sure they are appropriate for your distribution and that you comply with
+ them or their terms. We can't tell you what to do here, you need to get your
+ own legal advice.</p>
+<p>&nbsp;</p>
+<h2>Wrapping it up</h2>
+<p>Now that all the pieces are in place we can run our program executable one
+ more time. Our Cool example should look something like the screen snapshot below.
+</p>
+<p align="center"><img src="final.jpg" width="800" height="602"></p>
+<p>&nbsp;</p>
+<p>Before celebrating the branding of your product you should take a moment to
+ confirm the following:</p>
+<ul>
+ <li>welcome page is correct</li>
+ <li>the icon and title shown in the window title bar is correct</li>
+ <li>the Help pulldown properly indicate the name of the about dialog (e.g. About
+ Cool Stuff)</li>
+ <li>the about dialog properly include your graphic, copyright text, version
+ and build numbers</li>
+ <li>the about dialog properly includes the platform version information in the
+ lower half of the dialog</li>
+</ul>
+Now that you have mastered the steps you should do a final run through the steps
+(starting with a clean install) but be sure to skip the &quot;try it&quot; steps.
+These steps require you to run the platform and consequently will cause information
+to be cached. Your actual product production process should not run the platform
+runtime.
+<h2>&nbsp;</h2>
+<h2>A brief word on NL enablement</h2>
+<p>In the previous sections we did not discuss NL (National Language) support
+ for your product branding. There are two important parts to localizing the product
+ branding:</p>
+<ul>
+ <li>localizing the configuration's plug-in</li>
+ <li>localizing the splash screen</li>
+</ul>
+<p>Configuration plug-ins are localized in a manner similar to the many other
+ plug-ins you have probably seen. That means creating one or more NL plug-in
+ fragments to contain the localized information. </p>
+<p>To localize the splash screen you will need to create locale subdirectories
+ under <i>eclipse/splash.</i> The names of these directories follow the standard
+ Java&trade; locale naming conventions. For example the platform looks up the splash
+ screen for USA english locale (en_US) as follow:</p>
+<ol>
+ <li>eclipse\splash\en_US\&lt;image file&gt;</li>
+ <li>eclipse\splash\en\&lt;image file&gt;</li>
+ <li>eclipse\splash\&lt;image file&gt;</li>
+</ol>
+<p>where &lt;image file&gt; is the name of the splash file (e.g. splash_full.bmp
+ or splash_full.xpm).</p>
+<p>For additional information on localizing plug-ins consult the Platform Plug-in
+ Developer Guide.</p>
+<p>&nbsp;</p>
+<h2>Product directory</h2>
+<p>In the previous sections we have been working in the <i>eclipse/</i> directory.
+ You are probably asking yourself whether or not you should rename the <i>eclipse</i>
+ directory. The answer is no. Doing so may prevent future fixes and updates from
+ installing. The correct approach is to include the <i>eclipse/</i> directory
+ inside your own product directory. For example our Cool product would look as
+ follows:</p>
+<blockquote>
+ <p>\cool<br>
+ \cool\<b>eclipse<br>
+ </b>\cool\<b>eclipse\cool.exe</b><br>
+ \cool\product-readme<br>
+ \cool\.... </p>
+ </blockquote>
+It is also worth noting that the steps we have gone through describe the complete
+set of steps you need to follow in order to productize/brand your work. Other
+than adding more of your own plug-ins you should not make other modifications
+in the <i>eclipse/</i> directory.
+<h2>Summary</h2>
+<p>We have covered the tasks required to add branding to a product based on the
+ platform. The process involves rebuilding the executable, replacing a number
+ of graphics and creating a product configuration and corresponding plug-in.
+ Once you have mastered the steps you should do a final run through the steps
+ but be sure to skip the &quot;try it&quot; steps. These steps require you to
+ run the platform and consequently will cause information to be cached. Your
+ actual product production process should not run the platform runtime. Here
+ is a quick checklist (ignoring NL issues) to help refresh your memory on what
+ we modified.</p>
+<table width="80%" border="1" cellspacing="0" cellpadding="0">
+ <tr bgcolor="#CCCCCC">
+ <td width="20%"><b>Item</b></td>
+ <td width="40%"><b>Windows</b></td>
+ <td width="40%"><b>Linux</b></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>Splash</td>
+ <td>
+ <p>Replace the following:</p>
+ <ul>
+ <li>eclipse/splash/splash_basic.bmp</li>
+ <li>eclipse/splash/splash_full.bmp</li>
+ </ul>
+ </td>
+ <td>
+ <p>Replace the following: </p>
+ <ul>
+ <li>eclipse/splash/splash_basic.xpm</li>
+ <li>eclipse/splash/splash_full.xpm</li>
+ </ul>
+ </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>Executable graphics</td>
+ <td>
+ <p>Replace the following in <i>library/</i> (obtained from the SDK)</p>
+ <ul>
+ <li>icon16_basic.bmp</li>
+ <li>icon16_full.bmp</li>
+ <li>icon32_basic.bmp</li>
+ <li>icon32_full.bmp</li>
+ <li>icon48_basic.bmp</li>
+ <li>icon48_full.bmp</li>
+ </ul>
+ <p>and build them into single ICO file by replacing:</p>
+ <ul>
+ <li>library/eclipse.ico</li>
+ </ul>
+ </td>
+ <td>
+ <p>Replace the following:</p>
+ <ul>
+ <li>eclipse/icon.xpm</li>
+ </ul>
+ </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>Executable</td>
+ <td colspan="2">
+ <p>Remove existing executable from eclipse/ and replace with your product's
+ executable program built using the build scripts in <i>library/ </i>of
+ the SDK<i> </i>. </p>
+ </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>Product configuration</td>
+ <td colspan="2">
+ <p>Copy the dominant configuration directory to eclipse/install/configurations/<i>your_configuration_id_and_version</i></p>
+ <p>Modify the following files in the new configuration directory</p>
+ <ul>
+ <li>install.xml</li>
+ </ul>
+ </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>Product plug-in</td>
+ <td colspan="2">Copy the dominant configuration plug-in directory to eclipse/plugins/<i>your_configuration_id_and_version</i></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>Standard plug-in files </td>
+ <td colspan="2">
+ <p>Modify the following files in eclipse/plugins/<i>your_configuration_id_and_version</i></p>
+ <ul>
+ <li>plugin.xml</li>
+ <li>plugin.properties</li>
+ <li>about.html</li>
+ </ul>
+ </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>Plug-in product files</td>
+ <td colspan="2">
+ <p>Modify the following product files in eclipse/plugins/<i>your_configuration_id_and_version.
+ </i>These provide product naming, About dialog text and the welcome page.</p>
+ <ul>
+ <li>product.ini</li>
+ <li>product.properties</li>
+ <li>welcome.xml</li>
+ </ul>
+ </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>Plug-in product graphics</td>
+ <td colspan="2">
+ <p>Replace the following product graphics files in eclipse/plugins/<i>your_configuration_id_and_version</i>.
+ These represent the about dialog and the icon shown in the top left corner
+ of all windows:</p>
+ <ul>
+ <li>about_prod.gif</li>
+ <li>about_prod_basic.gif</li>
+ <li>prod.gif</li>
+ <li>prod_basic.gif</li>
+ </ul>
+ </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>Installation </td>
+ <td colspan="2">Update eclipse/install/install.properties to reference <i>your_configuration_id_and_version</i></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>License</td>
+ <td colspan="2">You should check legal notices such as: license.html, notice.html,
+ cpl-v05.html and the about.html files in the root directory and plugin subdirectories
+ to make sure they are appropriate for your distribution and that you comply
+ with them or their terms. We can't tell you what to do here, you need to
+ get your own legal advice.</td>
+ </tr>
+</table>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html>
diff --git a/product-guide/idea.jpg b/product-guide/idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/product-guide/idea.jpg
Binary files differ
diff --git a/product-guide/linux_only.gif b/product-guide/linux_only.gif
new file mode 100644
index 0000000..7c135cf
--- /dev/null
+++ b/product-guide/linux_only.gif
Binary files differ
diff --git a/product-guide/tip.gif b/product-guide/tip.gif
new file mode 100644
index 0000000..77b2451
--- /dev/null
+++ b/product-guide/tip.gif
Binary files differ
diff --git a/product-guide/win_only.gif b/product-guide/win_only.gif
new file mode 100644
index 0000000..895f9ca
--- /dev/null
+++ b/product-guide/win_only.gif
Binary files differ
diff --git a/swt-design-2/Idea.jpg b/swt-design-2/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/swt-design-2/Idea.jpg
Binary files differ
diff --git a/swt-design-2/LeakExample.java.htm b/swt-design-2/LeakExample.java.htm
new file mode 100644
index 0000000..2999468
--- /dev/null
+++ b/swt-design-2/LeakExample.java.htm
@@ -0,0 +1,130 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>LeakExample.java</title>
+</head>
+
+<body>
+
+<b>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055">import </font></b>org.eclipse.swt.*;</p>
+<b>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055">import </font></b>org.eclipse.swt.graphics.*;</p>
+<b>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055">import </font></b>org.eclipse.swt.widgets.*;</p>
+<b>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055">import </font></b>org.eclipse.swt.events.*;</p>
+<b>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055">import </font></b>org.eclipse.swt.layout.*;</p>
+<b>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055">import </font></b>org.eclipse.swt.program.*;</p>
+<b>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;</p>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055">public class </font></b>LeakExample
+{</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;
+static </font></b>Display display;</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;
+static </font></b>Shell shell;</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;
+static </font></b>List list;</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;
+static </font></b>Canvas canvas;</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;
+static </font></b>Image image;</p>
+<font SIZE="2">
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;</p>
+</font><b>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055">public static
+void </font></b>main(String[] args) {</p>
+<p style="margin-top: 0; margin-bottom: 0"><font color="#3F7F5F">&nbsp;&nbsp;&nbsp;
+// DeviceData data = <b>new </b>DeviceData();</font></p>
+<p style="margin-top: 0; margin-bottom: 0"><font color="#3F7F5F">&nbsp;&nbsp;&nbsp;
+// data.tracking = <b>true</b>;</font></p>
+<p style="margin-top: 0; margin-bottom: 0"><font color="#3F7F5F">&nbsp;&nbsp;&nbsp;
+// display = <b>new </b>Display(data);</font></p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; display = <b><font COLOR="#7f0055">new
+</font></b>Display();</p>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#3f7f5f">&nbsp;&nbsp;&nbsp;
+// Sleak sleak = new Sleak();</font></p>
+<font SIZE="2">
+<p style="margin-top: 0; margin-bottom: 0"></font><font COLOR="#3f7f5f">&nbsp;&nbsp;&nbsp;
+// sleak.open();</font></p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; shell = <b><font COLOR="#7f0055">new
+</font></b>Shell(display);</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; shell.setLayout(<b><font COLOR="#7f0055">new
+</font></b>FillLayout());</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; list = <b><font COLOR="#7f0055">new
+</font></b>List(shell, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL);</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;
+list.setItems(Program.getExtensions());</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; canvas = <b><font COLOR="#7f0055">new
+</font></b>Canvas(shell, SWT.BORDER);</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;
+canvas.addPaintListener(<b><font COLOR="#7f0055">new </font></b>PaintListener()
+{</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+public void </font></b>paintControl(PaintEvent e) {</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if </font></b>(image != <b><font COLOR="#7f0055">null</font></b>) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+e.gc.drawImage(image, 0, 0);</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; });</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;
+list.addSelectionListener(<b><font COLOR="#7f0055">new </font></b>SelectionAdapter()
+{</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+public void </font></b>widgetSelected(SelectionEvent e) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+image = <b><font COLOR="#7f0055">null</font></b>; <font color="#3F7F5F">
+// potentially leak one image&nbsp;</font></p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+String[] selection = list.getSelection();</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if </font></b>(selection.length != 0) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Program program = Program.findProgram(selection[0]);</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if </font></b>(program != <b><font COLOR="#7f0055">null</font></b>) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ImageData imageData = program.getImageData();</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if </font></b>(imageData != <b><font COLOR="#7f0055">null</font></b>) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+<b><font COLOR="#7f0055">if </font></b>(image != <b><font COLOR="#7f0055">null</font></b>)
+image.dispose();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+image = <b><font COLOR="#7f0055">new </font></b>Image(display, imageData);</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+canvas.redraw();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; });</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;
+shell.setSize(shell.computeSize(SWT.DEFAULT, 200));</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; shell.open();</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;
+while </font></b>(!shell.isDisposed()) {</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;
+if </font></b>(!display.readAndDispatch()) display.sleep();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; }</p>
+<p style="margin-top: 0; margin-bottom: 0">}</p>
+<p style="margin-top: 0; margin-bottom: 0">}</p>
+
+</body>
+
+</html>
diff --git a/swt-design-2/Sleak.java.htm b/swt-design-2/Sleak.java.htm
new file mode 100644
index 0000000..2c7dd5d
--- /dev/null
+++ b/swt-design-2/Sleak.java.htm
@@ -0,0 +1,274 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!-- saved from url=(0086)http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-swt-home/tools/sleak.html -->
+<HTML><HEAD>
+<META http-equiv=Content-Type content="text/html; charset=windows-1252">
+<META content="MSHTML 6.00.2800.1141" name=GENERATOR></HEAD>
+<BODY><PRE>/*
+ * Copyright (c) 2000, 2002 IBM Corp. All rights reserved.
+ * This file is made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ */
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+import java.io.*;
+
+public class Sleak {
+ Display display;
+ Shell shell;
+ List list;
+ Canvas canvas;
+ Button start, stop, check;
+ Text text;
+ Label label;
+
+ Object [] oldObjects = new Object [0];
+ Error [] oldErrors = new Error [0];
+ Object [] objects = new Object [0];
+ Error [] errors = new Error [0];
+
+public void open () {
+ display = Display.getCurrent ();
+ shell = new Shell (display);
+ shell.setText ("S-Leak");
+ list = new List (shell, SWT.BORDER | SWT.V_SCROLL);
+ list.addListener (SWT.Selection, new Listener () {
+ public void handleEvent (Event event) {
+ refreshObject ();
+ }
+ });
+ text = new Text (shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
+ canvas = new Canvas (shell, SWT.BORDER);
+ canvas.addListener (SWT.Paint, new Listener () {
+ public void handleEvent (Event event) {
+ paintCanvas (event);
+ }
+ });
+ check = new Button (shell, SWT.CHECK);
+ check.setText ("Stack");
+ check.addListener (SWT.Selection, new Listener () {
+ public void handleEvent (Event e) {
+ toggleStackTrace ();
+ }
+ });
+ start = new Button (shell, SWT.PUSH);
+ start.setText ("Snap");
+ start.addListener (SWT.Selection, new Listener () {
+ public void handleEvent (Event event) {
+ refreshAll ();
+ }
+ });
+ stop = new Button (shell, SWT.PUSH);
+ stop.setText ("Diff");
+ stop.addListener (SWT.Selection, new Listener () {
+ public void handleEvent (Event event) {
+ refreshDifference ();
+ }
+ });
+ label = new Label (shell, SWT.BORDER);
+ label.setText ("0 object(s)");
+ shell.addListener (SWT.Resize, new Listener () {
+ public void handleEvent (Event e) {
+ layout ();
+ }
+ });
+ check.setSelection (false);
+ text.setVisible (false);
+ Point size = shell.getSize ();
+ shell.setSize (size.x / 2, size.y / 2);
+ shell.open ();
+}
+
+void refreshLabel () {
+ int colors = 0, cursors = 0, fonts = 0, gcs = 0, images = 0, regions = 0;
+ for (int i=0; i&lt;objects.length; i++) {
+ Object object = objects [i];
+ if (object instanceof Color) colors++;
+ if (object instanceof Cursor) cursors++;
+ if (object instanceof Font) fonts++;
+ if (object instanceof GC) gcs++;
+ if (object instanceof Image) images++;
+ if (object instanceof Region) regions++;
+ }
+ String string = "";
+ if (colors != 0) string += colors + " Color(s)\n";
+ if (cursors != 0) string += cursors + " Cursor(s)\n";
+ if (fonts != 0) string += fonts + " Font(s)\n";
+ if (gcs != 0) string += gcs + " GC(s)\n";
+ if (images != 0) string += images + " Image(s)\n";
+ /* Currently regions are not counted. */
+// if (regions != 0) string += regions + " Region(s)\n";
+ if (string.length () != 0) {
+ string = string.substring (0, string.length () - 1);
+ }
+ label.setText (string);
+}
+
+void refreshDifference () {
+ DeviceData info = display.getDeviceData ();
+ if (!info.tracking) {
+ MessageBox dialog = new MessageBox (shell, SWT.ICON_WARNING | SWT.OK);
+ dialog.setText (shell.getText ());
+ dialog.setMessage ("Warning: Device is not tracking resource allocation");
+ dialog.open ();
+ }
+ Object [] newObjects = info.objects;
+ Error [] newErrors = info.errors;
+ Object [] diffObjects = new Object [newObjects.length];
+ Error [] diffErrors = new Error [newErrors.length];
+ int count = 0;
+ for (int i=0; i&lt;newObjects.length; i++) {
+ int index = 0;
+ while (index &lt; oldObjects.length) {
+ if (newObjects [i] == oldObjects [index]) break;
+ index++;
+ }
+ if (index == oldObjects.length) {
+ diffObjects [count] = newObjects [i];
+ diffErrors [count] = newErrors [i];
+ count++;
+ }
+ }
+ objects = new Object [count];
+ errors = new Error [count];
+ System.arraycopy (diffObjects, 0, objects, 0, count);
+ System.arraycopy (diffErrors, 0, errors, 0, count);
+ list.removeAll ();
+ text.setText ("");
+ canvas.redraw ();
+ for (int i=0; i&lt;objects.length; i++) {
+ list.add (objectName (objects [i]));
+ }
+ refreshLabel ();
+ layout ();
+}
+
+String objectName (Object object) {
+ String string = object.toString ();
+ int index = string.lastIndexOf ('.');
+ if (index == -1) return string;
+ return string.substring (index + 1, string.length ());
+}
+
+void toggleStackTrace () {
+ refreshObject ();
+ layout ();
+}
+
+void paintCanvas (Event event) {
+ canvas.setCursor (null);
+ int index = list.getSelectionIndex ();
+ if (index == -1) return;
+ GC gc = event.gc;
+ Object object = objects [index];
+ if (object instanceof Color) {
+ if (((Color)object).isDisposed ()) return;
+ gc.setBackground ((Color) object);
+ gc.fillRectangle (canvas.getClientArea());
+ return;
+ }
+ if (object instanceof Cursor) {
+ if (((Cursor)object).isDisposed ()) return;
+ canvas.setCursor ((Cursor) object);
+ return;
+ }
+ if (object instanceof Font) {
+ if (((Font)object).isDisposed ()) return;
+ gc.setFont ((Font) object);
+ FontData [] array = gc.getFont ().getFontData ();
+ String string = "";
+ String lf = text.getLineDelimiter ();
+ for (int i=0; i&lt;array.length; i++) {
+ FontData data = array [i];
+ String style = "NORMAL";
+ int bits = data.getStyle ();
+ if (bits != 0) {
+ if ((bits &amp; SWT.BOLD) != 0) style = "BOLD ";
+ if ((bits &amp; SWT.ITALIC) != 0) style += "ITALIC";
+ }
+ string += data.getName () + " " + data.getHeight () + " " + style + lf;
+ }
+ gc.drawString (string, 0, 0);
+ return;
+ }
+ //NOTHING TO DRAW FOR GC
+// if (object instanceof GC) {
+// return;
+// }
+ if (object instanceof Image) {
+ if (((Image)object).isDisposed ()) return;
+ gc.drawImage ((Image) object, 0, 0);
+ return;
+ }
+ if (object instanceof Region) {
+ if (((Region)object).isDisposed ()) return;
+ String string = ((Region)object).getBounds().toString();
+ gc.drawString (string, 0, 0);
+ return;
+ }
+}
+
+void refreshObject () {
+ int index = list.getSelectionIndex ();
+ if (index == -1) return;
+ if (check.getSelection ()) {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream ();
+ PrintStream s = new PrintStream (stream);
+ errors [index].printStackTrace (s);
+ text.setText (stream.toString ());
+ text.setVisible (true);
+ canvas.setVisible (false);
+ } else {
+ canvas.setVisible (true);
+ text.setVisible (false);
+ canvas.redraw ();
+ }
+}
+
+void refreshAll () {
+ oldObjects = new Object [0];
+ oldErrors = new Error [0];
+ refreshDifference ();
+ oldObjects = objects;
+ oldErrors = errors;
+}
+
+void layout () {
+ Rectangle rect = shell.getClientArea ();
+ String [] strings = new String [objects.length];
+ int width = 0;
+ String [] items = list.getItems ();
+ GC gc = new GC (list);
+ for (int i=0; i&lt;objects.length; i++) {
+ width = Math.max (width, gc.stringExtent (items [i]).x);
+ }
+ gc.dispose ();
+ Point size1 = start.computeSize (SWT.DEFAULT, SWT.DEFAULT);
+ Point size2 = stop.computeSize (SWT.DEFAULT, SWT.DEFAULT);
+ Point size3 = check.computeSize (SWT.DEFAULT, SWT.DEFAULT);
+ Point size4 = label.computeSize (SWT.DEFAULT, SWT.DEFAULT);
+ width = Math.max (size1.x, Math.max (size2.x, Math.max (size3.x, width)));
+ width = Math.max (64, Math.max (size4.x, list.computeSize (width, SWT.DEFAULT).x));
+ start.setBounds (0, 0, width, size1.y);
+ stop.setBounds (0, size1.y, width, size2.y);
+ check.setBounds (0, size1.y + size2.y, width, size3.y);
+ label.setBounds (0, rect.height - size4.y, width, size4.y);
+ int height = size1.y + size2.y + size3.y;
+ list.setBounds (0, height, width, rect.height - height - size4.y);
+ text.setBounds (width, 0, rect.width - width, rect.height);
+ canvas.setBounds (width, 0, rect.width - width, rect.height);
+}
+
+public static void main (String [] args) {
+ Display display = new Display ();
+ Sleak sleak = new Sleak ();
+ sleak.open ();
+ while (!sleak.shell.isDisposed ()) {
+ if (!display.readAndDispatch ()) display.sleep ();
+ }
+ display.dispose ();
+}
+
+}
+</PRE></BODY></HTML>
diff --git a/swt-design-2/default_style.css b/swt-design-2/default_style.css
new file mode 100644
index 0000000..d725483
--- /dev/null
+++ b/swt-design-2/default_style.css
@@ -0,0 +1,11 @@
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
diff --git a/swt-design-2/sleak.1.gif b/swt-design-2/sleak.1.gif
new file mode 100644
index 0000000..a60b5fb
--- /dev/null
+++ b/swt-design-2/sleak.1.gif
Binary files differ
diff --git a/swt-design-2/sleak.2.gif b/swt-design-2/sleak.2.gif
new file mode 100644
index 0000000..2437061
--- /dev/null
+++ b/swt-design-2/sleak.2.gif
Binary files differ
diff --git a/swt-design-2/sleak.3.gif b/swt-design-2/sleak.3.gif
new file mode 100644
index 0000000..c1b6c68
--- /dev/null
+++ b/swt-design-2/sleak.3.gif
Binary files differ
diff --git a/swt-design-2/sleak.4.gif b/swt-design-2/sleak.4.gif
new file mode 100644
index 0000000..a9ed215
--- /dev/null
+++ b/swt-design-2/sleak.4.gif
Binary files differ
diff --git a/swt-design-2/sleak.5.gif b/swt-design-2/sleak.5.gif
new file mode 100644
index 0000000..d206bf7
--- /dev/null
+++ b/swt-design-2/sleak.5.gif
Binary files differ
diff --git a/swt-design-2/sleak.6.gif b/swt-design-2/sleak.6.gif
new file mode 100644
index 0000000..632b6e0
--- /dev/null
+++ b/swt-design-2/sleak.6.gif
Binary files differ
diff --git a/swt-design-2/sleak.7.gif b/swt-design-2/sleak.7.gif
new file mode 100644
index 0000000..ec7af01
--- /dev/null
+++ b/swt-design-2/sleak.7.gif
Binary files differ
diff --git a/swt-design-2/sleak.8.gif b/swt-design-2/sleak.8.gif
new file mode 100644
index 0000000..89b9ba6
--- /dev/null
+++ b/swt-design-2/sleak.8.gif
Binary files differ
diff --git a/swt-design-2/sleak.htm b/swt-design-2/sleak.htm
new file mode 100644
index 0000000..800a294
--- /dev/null
+++ b/swt-design-2/sleak.htm
@@ -0,0 +1,225 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Sleak</title>
+</head>
+
+<body>
+
+<h3>
+Sleak
+</h3>
+
+<p>
+<i>Sleak</i> is a simple tool that monitors SWT <i> graphics</i> resources.
+(Applications typically don't leak <i>widget</i> resources because of rule 2). You can use
+<i>Sleak</i> to detect leaks in SWT application code.
+</p>
+
+<p>
+Here is the source code: <a href="Sleak.java.htm">Sleak.java</a>.
+</p>
+
+<p>
+To use the tool, put the <i> Sleak</i> class on your class path and then find the place
+in your application code where you create the <i>Display</i>:
+</p>
+
+<p>
+&nbsp;&nbsp;&nbsp; Display display = <b><font COLOR="#7f0055">new
+</font></b>Display();
+</p>
+
+<p>
+Before creating the display, create a <i>DeviceData</i> and set the <b>data.tracking</b>
+flag to true.<br>
+Then create the <i>Display</i> with this new <i>DeviceData</i> object.<br>
+Then create an instance of <i>Sleak</i> and open it.<br>
+Your new code will look something like this:&nbsp;
+</p>
+
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; DeviceData data = <b><font COLOR="#7f0055">new
+</font></b>DeviceData();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; data.tracking = <b><font COLOR="#7f0055">true</font></b>;</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; Display display = <b><font COLOR="#7f0055">new
+</font></b>Display(data);</p>
+
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; Sleak sleak = <b><font SIZE="2" COLOR="#7f0055">new
+</font></b>Sleak();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; sleak.open();</p>
+
+<p>
+Now run your code as usual. When the <i>Sleak</i> window comes up, it looks like
+this:
+</p>
+
+<p style="margin-top: 0; margin-bottom: 0">
+<img border="0" src="sleak.1.gif" width="384" height="268">
+</p>
+
+<p>When you press the &quot;Start&quot; button, <i>Sleak</i> collects and
+displays a list of the SWT graphics resources that are currently allocated. At this point, perform
+the action in your application that you suspect is leaking. When you press the
+&quot;Stop&quot; button, <i>Sleak</i> displays the list of resources
+that were allocated since you pressed &quot;Start&quot;. Select a resource in
+the list on the left and it will be drawn in the canvas on the right. Select the &quot;Stack&quot;
+checkbox to see a stack trace showing where the resource was created. This does not
+necessarily imply that this resource was leaked - just that it currently exists.
+If you believe that this particular resource is no longer needed and should have
+been disposed, then you have discovered a leak.
+</p>
+
+<h3>
+Example
+</h3>
+
+<p>
+Look at <a href="LeakExample.java.htm">LeakExample.java</a>. You suspect that
+this code is
+leaking, and decide to use <i>Sleak</i> to verify your theory, and to
+investigate a possible fix.
+</p>
+
+<p>
+Find the line of code that creates the <i>Display</i>:
+</p>
+
+<p>
+&nbsp;&nbsp;&nbsp; display = <b><font SIZE="2" COLOR="#7f0055">new
+</font></b>Display();
+</p>
+
+<p>
+And rewrite the beginning of the <b>main()</b>
+method as follows:
+</p>
+
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">public
+static void </font></b>main(String[] args) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; DeviceData data = <b><font COLOR="#7f0055">new
+</font></b>DeviceData();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; data.tracking = <b><font COLOR="#7f0055">true</font></b>;</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; display = <b><font COLOR="#7f0055">new
+</font></b>Display(data);</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; Sleak sleak = <b><font COLOR="#7f0055">new
+</font></b>Sleak();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; sleak.open();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; ...</p>
+<p style="margin-top: 0; margin-bottom: 0">}</p>
+
+<p>
+Run the <i>LeakExample</i> class as usual, and two windows open: your
+application, and the <i>Sleak</i> window. Press <i>Sleak</i>'s &quot;Start&quot;
+button, and
+notice that no resources have yet been allocated - nothing shows up in <i>Sleak</i>'s
+resource list.
+</p>
+
+<p>
+<img border="0" src="sleak.2.gif" width="222" height="227">&nbsp;&nbsp;&nbsp; <img border="0" src="sleak.3.gif" width="222" height="227">
+</p>
+
+<p>
+Return to the <i>LeakExample</i> window and click on an item in the list that
+has an associated image, say, '.gif'. Press &quot;Start&quot; again,
+and now you can see that one image has been created. Select the image and see
+that it is the one currently being displayed in the example. This will be your
+&quot;starting point&quot;. No resources have been leaked yet because there is only one image, and it
+is still being used.
+</p>
+
+<p>
+<img border="0" src="sleak.4.gif" width="222" height="227">&nbsp;&nbsp;&nbsp; <img border="0" src="sleak.5.gif" width="222" height="227">
+</p>
+
+<p>
+Now click on some other items in the example list, and press &quot;Stop&quot;. <i>Sleak</i>
+shows 2 images that were both created since &quot;Start&quot; was pressed, but
+only one is being displayed in the application.
+</p>
+
+<p>
+<img border="0" src="sleak.6.gif" width="222" height="228">&nbsp;&nbsp;&nbsp; <img border="0" src="sleak.8.gif" width="222" height="227">
+</p>
+
+<p>
+&nbsp;Select one of the new images, and check &quot;Stack&quot; to see where the image was created:
+</p>
+
+<p>
+<img border="0" src="sleak.7.gif" width="587" height="228">
+</p>
+
+<p>The image was created in the <b>widgetSelected</b> method in the <i>LeakExample</i>
+class, so this is the method to look at to see if the example is leaking. Here
+is the code for the method:
+</p>
+
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+public void </font></b>widgetSelected(SelectionEvent e) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+image = <b><font COLOR="#7f0055">null</font></b>;</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+String[] selection = list.getSelection();</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if </font></b>(selection.length != 0) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Program program = Program.findProgram(selection[0]);</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if </font></b>(program != <b><font COLOR="#7f0055">null</font></b>) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ImageData imageData = program.getImageData();</p>
+<p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if </font></b>(imageData != <b><font COLOR="#7f0055">null</font></b>) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+<b><font COLOR="#7f0055">if </font></b>(image != <b><font COLOR="#7f0055">null</font></b>)
+image.dispose();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+image = <b><font COLOR="#7f0055">new </font></b>Image(display, imageData);</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+canvas.redraw();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+
+<p>The <b>image = null</b> at the beginning of the method looks suspicious.
+This was added so that the paint did not draw the old image if an item with no
+image was
+selected. Before setting <b>image</b> to null, the image should be disposed, as follows:
+</p>
+
+<b>
+<p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if </font></b>(image != <b><font COLOR="#7f0055">null</font></b>) {</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+image.dispose();</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+image = <b><font COLOR="#7f0055">null</font></b>;</p>
+<p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p>
+
+<p>After adding this dispose code, notice that you can delete the old line that
+disposed the image right before creating a new one:
+</p>
+
+<p><b><font COLOR="#7f0055">
+if </font></b>(image != <b><font COLOR="#7f0055">null</font></b>) image.dispose();
+</p>
+
+<p>Now the code has been cleaned up, so run it under <i>Sleak</i> again and
+verify that nothing is leaking. One last thing for completeness and to get into
+good habits: you should also check if <b>image</b> needs disposing after the read and
+dispatch loop, or in a dispose listener on the shell.
+</p>
+
+</body>
+
+</html>
diff --git a/swt-design-2/swt-design-2.html b/swt-design-2/swt-design-2.html
new file mode 100644
index 0000000..c2acef4
--- /dev/null
+++ b/swt-design-2/swt-design-2.html
@@ -0,0 +1,526 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Carolyn MacLeod">
+ <link rel="stylesheet" href="default_style.css">
+ <title>Managing Operating System Resources</title>
+</head>
+<body>
+<div align=right><font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2001 Object Technology International, Inc.</font></font></div>
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table>
+
+<h1>
+<img SRC="Idea.jpg" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+SWT: The Standard Widget Toolkit</h1></center>
+
+<center>
+<h3>
+PART 2: Managing Operating System Resources</h3></center>
+
+<center><i>The second in a series of articles about the design ideas behind
+SWT.</i></center>
+
+<blockquote><b>Summary</b>
+<br>SWT uses operating system resources to deliver its native graphics and widget
+functionality. Allocating
+and freeing operating system resources is traditionally an area of programming
+that is error prone. Languages that include garbage collection, such as the
+ Java&trade; language, relieve the programmer from the burden of managing memory, but not
+ from the allocation and freeing of operating system resources. This article discusses the simple strategy used by
+SWT to help application designers manage operating system resources.
+ <p><b>By Carolyn MacLeod and Steve Northover, OTI</b><br>
+ <span style="font-size: 10pt; mso-bookmark: _Toc496069418">November 27, 2001</span></p>
+</blockquote>
+<p>
+<hr WIDTH="100%">
+<h3>
+Simple rules to help get it right!</h3>
+<p>When programming in a GUI operating system, you allocate operating system
+resources for widgets, images, fonts, and other graphical objects.&nbsp; Since
+there is a platform limit on the amount of resources you can allocate, you must
+be careful to free any objects that you allocate in your application.&nbsp; If you
+allocate a resource and do not free it when you are done with it, your application is &quot;leaking&quot;
+resources. An application that repeatedly leaks resources will
+eventually consume all of the available resources, forcing the user to reboot
+the operating system.</p>
+<p>Fortunately, SWT makes resource allocation and disposal a straightforward
+process. There are only two rules that you need to remember when allocating and
+freeing SWT resource-based objects:</p>
+<p align="center" style="border-style: solid"><b>Rule 1: </b><i>If you created it, you dispose it</i>.<p>This is
+a simple rule.&nbsp;SWT makes it easy for you to remember when
+operating system resources are allocated: <i>all</i> SWT resource-based objects (like <i>Color</i>,
+<i>Cursor</i>,
+<i>Display</i>,
+<i>Font</i>,
+<i>GC</i>,
+<i>Image</i>,
+<i>Printer</i>,
+<i>Region</i>,
+<i>Widget
+and subclasses</i>) allocate any needed operating system resources in their constructor.&nbsp;
+There are no exceptions to this rule.&nbsp; There are no methods in SWT (other
+than constructors) that allocate operating system resources that the programmer
+must manage. If
+you didn't call the constructor, then you don't need to free the resources,
+so don't call dispose on the object.&nbsp; For example, in the following
+line of code, an operating system font is allocated:
+<p>&nbsp;&nbsp;&nbsp; <font size=-1>Font font = new Font
+(display, "Courier",
+10, SWT.NORMAL);</font>
+<p>Since you called the <i>Font</i> constructor to create the resource,
+you must dispose the font when
+you are finished with it, as follows:
+<p>&nbsp;&nbsp;&nbsp; <font size=-1>font.dispose();</font>
+<p>In the following line of code, however, a constructor is not called:
+<p>&nbsp;&nbsp;&nbsp; <font size=-1>Font font = control.getFont
+();</font>
+<p>Therefore, you must not call dispose. The <b>font</b> variable does contain
+an operating system font resource, but you did not allocate it. If you
+were to dispose of this font, you would be leaving the <b>control</b> without
+a font!&nbsp; The results are undefined.&nbsp; So, if you are using <i>any</i>
+getter that returns an SWT resource-based object that you did not allocate, do not dispose the object.
+<p>This rule occasionally leads to API that seems artificial.&nbsp; For
+example, <b>GC.getClipping (Region)</b> forces the programmer to create
+a <i>Region</i> in order to get the clipping region from a <i>GC</i>. Although it
+might have been a bit "prettier" to provide GC.getClipping () that
+returned a <i>Region</i>, this would break the rule because it would have to allocate an operating system
+resource outside of a constructor.
+While it could be documented that the programmer needs to free the <i>Region</i>
+returned by GC.getClipping (), programmers don't always read the documentation.&nbsp;
+Making the programmer call the constructor for the <i>Region</i> makes
+it clear that it is the <i><u>programmer's</u></i> responsibility to free
+the resource.
+<p align="center" style="border-style: solid"><b>Rule 2: </b><i>Disposing the parent disposes the children.</i>&nbsp;
+<p>
+ When you dispose a <i>Shell</i>,
+its children are disposed.&nbsp; In fact, disposing any <i>Composite</i>
+will dispose all of the <i>Composite</i>'s children.&nbsp; Disposing a
+<i>Menu</i>
+disposes all menu items.&nbsp; Disposing a <i>Tree</i> or
+<i>TreeItem</i>
+disposes all child items.
+<p>Why does this make sense?&nbsp; Apart from the obvious burden of having
+to dispose each child if this were not the case, the fact that a widget
+cannot exist in the operating system without a parent implies that when
+the parent is disposed, the child <i>must</i> also be disposed.
+<p>What about the fonts and colors that you created and set into a
+<i>Widget</i>?&nbsp;
+Since they are not children of the widget, they are not disposed
+when the parent&nbsp; is disposed.&nbsp; A widget will never dispose
+a resource that you allocated.&nbsp; To do so would mean that the widget was
+breaking rule 1.&nbsp; Because fonts
+and colors can be shared by different widgets, disposing a resource in one
+widget would dispose it in another, leading to unpredictable results.
+<h4>Extensions to Rule 2</h4>
+<p>There are two extensions to rule 2. These are places where a relationship
+exists that is not strictly a parent-child relationship, but where it still
+makes sense for rule 2 to apply.
+<p><b> MenuItem.setMenu: </b>Disposing a cascade <i>MenuItem</i>
+that has a submenu set with <b>setMenu (Menu)</b> disposes the submenu. This is a natural extension of rule 2.&nbsp; It would be a burden
+to the programmer to dispose each individual submenu. It's also common behavior in most operating systems to do this automatically.
+Both Windows&reg; and X dispose submenus when a cascade menu item is
+disposed.<p><b> Control.setMenu: </b>Disposing a <i>Control</i>
+that has a pop-up menu set with <b>setMenu (Menu)</b> disposes the pop-up
+menu. Many application programmers expected this behavior, even though many operating systems don't
+do this automatically. Leaving the
+application programmer responsible for disposing a pop-up menu when disposing the
+<i>Control</i>
+led to temporary leaks. (The leak was only temporary because the pop-up menu is eventually disposed when
+the shell is disposed).
+<h3>
+Why free at all?</h3>
+The operating system frees all of a program's resources when the program
+exits. Why not just rely on this? Operating system resources are
+not infinite. If your program doesn't free up resources as they are no
+longer needed, it can run out of resources. It can also cause other programs
+to run out of resources. So waiting until the program exits to free up resources
+is generally a bad idea. Leak tools exist to help detect resource leaks.
+You can use the <i><a href="sleak.htm">Sleak</a></i> tool to look for leaks in your SWT application.
+<h3>
+The Java language has Garbage Collection - Why not use it?</h3>
+The Java language successfully uses a garbage collector to manage the memory used by
+Java objects.&nbsp; Why doesn't SWT use the Java garbage collector to manage
+operating system resources too? Many Java programmers ask this question. We will answer it with the following discussion on finalization.<h4><b>Finalization</b></h4>
+<p>Most attempts to use the Java garbage collector to
+manage operating system resources involve finalization.&nbsp; When an object
+is about to become garbage, the garbage collector sends it the finalize message. This seems
+like a logical place to free the resource, right?<p>Conventional wisdom says that managing operating system
+resources in finalization is difficult and error prone.&nbsp; To quote Joshua
+Bloch in his &quot;Java Series&quot; book <i>Effective Java</i>,
+<blockquote>
+ <p><i>&quot;Finalizers are
+unpredictable, often dangerous, and generally unnecessary.&nbsp; Their use can
+cause erratic behavior, poor performance, and portability problems.&quot;</i>&nbsp;
+[JB, 2.6].
+</blockquote>
+<p>One of
+the main reasons that this statement is true is that there is no guarantee how
+soon after an object becomes garbage that the finalize method for the object will run. Even if you could predict
+this time interval for a particular VM, you
+certainly couldn't guarantee it for new versions of the VM. Worse still, if there
+is plenty of memory or if an exception occurs in an object's finalize method, there is no
+guarantee that the object will be finalized at all! All of this is stated right in <i>The Java
+Language Specification</i>:
+<blockquote>
+ <p><i>&quot;<span style="mso-fareast-font-family: Times New Roman; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">The
+ Java programming language does not specify how soon a finalizer will be
+ invoked, except to say that it will happen before the storage for the object
+ is reused. ... If an uncaught exception is thrown during the finalization, the
+ exception is ignored and finalization of that object terminates.</span>&quot;</i>&nbsp;
+ <span style="mso-fareast-font-family: Times New Roman; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">[JLS,
+ 12.6]</span>.
+</blockquote>
+<p>Releasing operating system resources is
+critical to correct program execution.&nbsp; Freeing resources at some unknown time in the future (or not at all) typically leads to program
+failure. Here are some examples of typical problems encountered when using
+finalization:
+<ul>
+<li>
+If a non-garbage object references another object, that object is not garbage
+and won't be collected. If the object has operating system resources that it
+frees in its finalize method, those resources will never be freed because finalize
+will never be called. This is a classic programming error because it's easy to hang on to objects
+accidentally in an inner class or a static variable.<br>
+</li>
+
+<li>
+It is possible to starve other operating system processes by creating lots
+of "garbage resources" that have not yet been finalized.&nbsp; When another
+program attempts to acquire a resource, it fails because it cannot run
+the Java finalizer.&nbsp; SWT could run the finalizer if it couldn't get a resource, but
+other programs (i.e. non-Java programs or even Java programs running in a
+different VM) - and operating system calls that allocate
+and free resources internally - can't run the Java finalizer.<br>
+</li>
+
+<li>
+Some resources are very limited.&nbsp; For example, only a small number
+of cached HDCs are available on Windows 98.&nbsp; It is essential to free
+these up right away, instead of waiting for finalization.<br>
+</li>
+
+<li>
+Different types of resource are shared on the same operating system heap, so a
+failure to acquire one resource may be caused by failure to free another.&nbsp;
+For example, on Windows 98, HBRUSH and HFONT are both allocated from the
+GDI heap, so failure to create an HBRUSH can happen if too many HFONTs are
+awaiting finalization. This can cause applications to have some strange
+dependencies on the timing of finalizer runs.</li>
+
+</ul>
+<p class="MsoNormal">The non-deterministic nature of finalization is sufficient reason to avoid using
+it to free
+resources, but even if we decided to go against conventional wisdom and implement a resource management scheme using finalization, we
+would still face many other problems. The implementation would require the addition of some very
+complex, platform-specific code that would be difficult to get right, and tough
+to debug. Here are a
+few examples of some of the tricky issues that would need to be carefully coded
+around in each object's finalize method:</p>
+<ul>
+ <li>
+ <p class="MsoNormal">Operating system objects can have subtle limitations on when particular objects can be
+ disposed. For example in the X Window System, a GC can contain a Font. If you
+ dispose the Font before the GC, you leave the operating system in an
+ indeterminate state. The following quote from <i>The Java Language
+ Specification</i> hints at the complexity of the code that would be required
+ to handle such limitations for each object finalizer:</li>
+</ul>
+<blockquote>
+ <blockquote>
+ <p class="MsoNormal"><i>&quot;The Java programming language imposes no
+ ordering on finalize method calls. Finalizers may be called in any order, or
+ even concurrently.&quot;</i><span style="mso-spacerun: yes">&nbsp; </span>[JLS
+ 12.6.2]</p>
+ </blockquote>
+ <p class="MsoNormal">Add to this that for some operating systems, subtle
+ platform behavior in this area may be undocumented and can change in future
+ versions of the operating system.</p>
+</blockquote>
+<ul>
+ <li>
+ <p class="MsoNormal">On some platforms, operating system resources need to be disposed
+ in the UI thread. According to <i>The Java Language Specification</i>:</li>
+</ul>
+<blockquote>
+ <blockquote>
+ <p class="MsoNormal"><i>&quot;... the language does not specify which
+ thread will invoke the finalizer for any given object.&quot;</i> [JLS 12.6]</p>
+ </blockquote>
+ <p class="MsoNormal">This means that SWT finalize methods would need to
+ synchronize with the UI thread, which would mean that there would be a significant cost overhead for each
+ dispose. In addition, given the previous point that disposal order is
+ important for some resources, we think it is possible to get into a deadlock
+ situation if we are trying to reorder multiple concurrent threads that are
+ trying to synchronize with the UI thread.</p>
+</blockquote>
+<ul>
+
+<li>
+The Java objects that model operating system objects need to capture all of the subtle
+relationships between the operating system objects. For example, on Windows, an HBRUSH
+can be referenced in the operating system by an HDC, but not referenced
+in Java code.&nbsp; When the Java object representing the HBRUSH becomes garbage,
+freeing it will cause unexpected results.&nbsp; In fact, it's necessary
+to break the reference from the HDC first before attempting to free the HBRUSH.
+If these relationships are not captured and managed, it is possible for a resource to be finalized when there are still references
+to it in the operating system.&nbsp;&nbsp;<br>
+</li>
+
+<li>
+Freeing some resources automatically frees others. For example, on Windows,
+destroying a parent HWND automatically destroys the children HWNDs.&nbsp;
+On some operating systems, freeing a top level window also frees the icon
+associated with the window.&nbsp; Different rules for freeing resources need to be custom coded
+on a per platform basis.&nbsp;&nbsp;<br>
+</li>
+
+<li>
+Freeing resources can be time
+consuming, so a critical memory allocation may need to wait until finalization
+is complete.<br>
+</li>
+
+<li>
+Long waits in finalizers can also make it difficult to get good benchmarks when
+you are trying to performance tune your code.</li>
+
+</ul>
+<p>Our final point against finalization is this: SWT keeps as much state in the operating system as possible to simplify
+the implementation (less code, smaller objects).&nbsp; If we were to use
+finalization, we could not store resources only in the operating system.&nbsp; We would have
+to hold on to them in Java code so that they would not get garbage collected.&nbsp;
+For example, when you set a <i>Font</i> into a <i>Button</i>, SWT sets the font
+resource in the OS button.&nbsp; The <i>Button</i> doesn't keep a reference
+to the font resource, because it doesn't need to.&nbsp; The state is in
+the operating system. In order to determine the <i>Button</i>'s font, we query the OS.&nbsp; There is
+no point caching the font resource in Java code, because it just takes up space
+and complicates the <i>Button</i> code, which now has to make sure there
+are no stale cache problems.</p>
+<p>
+Given that there are many problems when trying to use finalization to free
+resources, we think it’s dangerous to offer it as a solution in SWT, which is
+designed to expose operating system functionality.&nbsp; We believe it is reasonable to expect programs to explicitly free operating
+system resources.&nbsp; We see this as simply a fact of life because the
+current generation of operating systems do not support garbage collection.
+<h3>When should you free?</h3>
+<p class="MsoNormal">You have created an SWT resource, so when do you free it?
+First of all, for many of the reasons mentioned above, we do not recommend that you use finalization to manage
+your SWT resources either. If you feel you absolutely must implement a finalize
+method in your classes, do
+so only as a &quot;safety net&quot; or &quot;backup&quot;, and dispose your resource as
+usual. Remember to synchronize with the UI thread, as follows:</p>
+<font size=-1><p style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; protected void finalize() {<span style="mso-spacerun:
+yes">&nbsp;&nbsp; </span>// NOT recommended
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>super.finalize();</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>display.asyncExec(new Runnable() {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>public void run() {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>if (!myResource.isDisposed()) {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>myResource.dispose();</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>}</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>}</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>});</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp; }</p>
+</font>
+<p class="MsoNormal">Even this minimal &quot;safety net&quot; use of finalizers is not recommended, because if memory is limited,
+your application could end up having to wait for a bunch of your finalize
+methods to run before the memory from those
+objects can be
+reclaimed.</p>
+<p class="MsoNormal">The best way to manage SWT resources is to dispose them as
+soon as you are through with them. In the case of certain resource types, such as
+GC and Printer, you almost always create them and dispose them within the scope of
+the same method.<span style="mso-spacerun: yes">&nbsp;This makes it easy to
+verify that the resource is being disposed properly, because you only have to go
+to one place to see the code to create the resource and the code to dispose it. </span>For example:</p>
+<font size=-1><p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>GC gc = new GC(canvas);</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+gc.draw...&nbsp;&nbsp; </span>// do some drawing on the canvas using the GC</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>gc.dispose();</p></font>
+<p class="MsoNormal">In the case of resources that are set into a GC for
+drawing, you need to be careful not to dispose them while they are still set
+into the GC. Dispose the GC before the resource. For example:</p>
+<font size=-1><p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span><font color="#000000">Font font </font> = new Font
+(display, "Courier",
+10, SWT.NORMAL);</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;<span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>GC gc = new GC(canvas);</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+gc.setFont(font);</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+gc.drawText...&nbsp;&nbsp;&nbsp; </span>// do some text drawing on the canvas using the GC</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>gc.dispose();</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+font.dispose();</p></font>
+<p class="MsoNormal">Remember that you do not dispose the GC that is
+passed to you in a paint listener, because you did not allocate it!</p>
+<font size=-1><p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>public void paintControl(PaintEvent event) {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span> event.gc.draw...</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>&nbsp;&nbsp;&nbsp;<span style="mso-tab-count: 1"> // do NOT call event.</span>gc.dispose();</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</p></font>
+<p class="MsoNormal">If you are using graphics resources in a widget - for example,
+widget.setFont(font) - it is often best to clean these up when the
+widget they are used in is disposed, so you can hook a dispose listener on the
+widget as follows:</p>
+<font size=-1><p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>widget.addDisposeListener(new DisposeListener() {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>public void widgetDisposed(DisposeEvent e) {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>font.dispose();</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>}</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>}</p></font>
+<p class="MsoNormal">If resources are shared by multiple widgets (or other
+objects) in your application, then you may want to implement a
+reference-counting scheme in a &quot;resource manager&quot; class, which would
+keep track of the number of references to a resource, and dispose the resource
+when the reference count reaches 0.<span style="mso-spacerun: yes">&nbsp; </span>In
+this case, you would ask your resource manager for each resource you need,
+perhaps something like this:</p>
+<font size=-1><p class="MsoNormal"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>Image image = myResourceManager.getNamedResource(&quot;imageName&quot;);</p>
+</font>
+<p class="MsoNormal">and the dispose listener on your widget(s) might look
+something like this:</p>
+<font size=-1>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>widget.addDisposeListener(new DisposeListener() {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>public void widgetDisposed(DisposeEvent e) {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>myResourceManager.dispose(image);</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>}</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>});</p></font>
+<p class="MsoNormal">Whether or not to use a reference-counting scheme, and how
+to implement it, are design decisions that must be made on a per-application
+basis.</p>
+<p class="MsoNormal">Widgets themselves do not usually need to be disposed
+programmatically. A shell and its children are disposed when the user closes its
+window. There are a couple of places where shells are typically disposed programmatically: when the user
+selects File-&gt;Exit in an application window, or OK in a dialog. Here is an
+example of disposing a shell when File-&gt;Exit is selected:</p>
+<font size=-1>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// Create menu bar
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span><span style="mso-tab-count:1">Menu menuBar = new Menu(shell, SWT.BAR);
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// Create File menu
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+MenuItem item = new MenuItem(menuBar, SWT.CASCADE);
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+item.setText(&quot;File&quot;);
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+item.setMenu(fileMenu);
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// Create File -> Exit menu item and add selection listener
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+item = new MenuItem(fileMenu, SWT.NULL);
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+item.setText(&quot;Exit&quot;);
+</span></p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>item.addSelectionListener(new SelectionAdapter() {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>public void widgetSelected(SelectionEvent event) {</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>shell.close(); // calls dispose() - see note below</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>}</p>
+<p class="MsoNormal" style="margin-top: 0; margin-bottom: 0"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>});</p></font>
+<p class="MsoNormal">Note that we actually call <b>close()</b> instead of <b>dispose()</b>.
+This gives the application a chance to cancel the close operation if necessary
+(for example, if something was not saved) inside of a shell listener. We could
+call <b>dispose()</b>, which would simply destroy the shell without invoking the
+shell listener, but it's better style to call <b>close()</b>.</p>
+<h3>
+A note about Color</h3>
+<i>Color</i> is just like any other SWT resource-based object. To ensure
+that your application works on all platforms for all display types, always
+follow rule 1. If you are using a high-color (direct palette) display and you forget to follow
+the rules for disposing <i>Color</i>, you may notice that nothing bad happens.
+But if the rules for disposing <i>Color</i>
+are not followed on a low-color (indexed palette) display, real problems can occur. You
+should always program your application with the assumption that some of
+your customers will be using low-color displays. For more information,
+see the <i>SWT Color Model</i> article.
+<h3>
+Conclusion</h3>
+When you use SWT, you will probably need to manage operating system resources
+allocated by SWT objects. Resource management
+takes thought to get right. Getting into good habits and following the rules
+reduces the programming effort significantly. Simple rules help make
+it clear who has responsibility for disposing resources:
+<ul>
+<li>
+<i>If you created it, you dispose it</i> (<i>if you didn't create it, don't dispose it)</i>.</li>
+
+<li>
+<i>Disposing the parent disposes the children.</i></li>
+</ul>
+<h3>Further reading</h3>
+<p>JFace provides a registry mechanism on top of SWT
+for image and font resource management. See the article <i>Using Images
+in the Eclipse UI</i> for more information on the JFace image management
+facilities.</p>
+<h3>References</h3>
+<p>[JB]&nbsp;&nbsp;&nbsp; Bloch, Joshua. <i>Effective Java - Programming Language
+Guide</i>. Addison-Wesley, Boston, 2001.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ISBN:
+0-201-31005-8.</p>
+<p>[JLS]&nbsp; Gosling James, Bill Joy, Guy Steele, Gilad Bracha. <i>The Java
+Language Specification</i>, <i>Second Edition<br>
+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://java.sun.com/docs/books/jls/second_edition/html/j.title.doc.html</i></p>
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+<p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p>
+
+</body>
+</html>
diff --git a/update_landing_page.php b/update_landing_page.php
deleted file mode 100644
index 58546d3..0000000
--- a/update_landing_page.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php"); require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/nav.class.php"); require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/menu.class.php"); $App = new App(); $Nav = new Nav(); $Menu = new Menu(); include($App->getProjectCommon()); # All on the same line to unclutter the user's desktop'
-
- #*****************************************************************************
- #
- # template.php
- #
- # Author: Denis Roy
- # Date: 2005-06-16
- #
- # Description: Type your page comments here - these are not sent to the browser
- #
- #
- #****************************************************************************
-
- #
- # Begin: page-specific settings. Change these.
- $pageTitle = "Update Page for Eclipse Corner Articles";
- $pageKeywords = "";
- $pageAuthor = "Wayne Beaton";
-
- # Add page-specific Nav bars here
- # Format is Link text, link URL (can be http://www.someothersite.com/), target (_self, _blank), level (1, 2 or 3)
- # $Nav->addNavSeparator("My Page Links", "downloads.php");
- # $Nav->addCustomNav("My Link", "mypage.php", "_self", 3);
- # $Nav->addCustomNav("Google", "http://www.google.com/", "_blank", 3);
-
- # End: page-specific settings
- #
- include("classes/articles_from_xml.php");
- compute_and_cache_articles_as_html();
-
- # Paste your HTML content between the EOHTML markers!
- $html = <<<EOHTML
-
-<div id="midcolumn">
- Updated!
- </div>
-EOHTML;
-
- # Generate the web page
- $App->generatePage($theme, $Menu, $Nav, $pageAuthor, $pageKeywords, $pageTitle, $html);
-?>
diff --git a/using-perspectives/Idea.jpg b/using-perspectives/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/using-perspectives/Idea.jpg
Binary files differ
diff --git a/using-perspectives/PerspectiveArticle.html b/using-perspectives/PerspectiveArticle.html
new file mode 100644
index 0000000..9497948
--- /dev/null
+++ b/using-perspectives/PerspectiveArticle.html
@@ -0,0 +1,822 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Build">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
+ <title>Using Perspectives in the Eclipse UI</title>
+<link rel="stylesheet" href="default_style.css">
+</head>
+<body>
+
+<div align=right>&nbsp; <font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2001 Object Technology International, Inc.</font></font></div>
+
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<caption><TBODY>
+<br></TBODY></caption>
+
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table>
+
+<h1>
+<img SRC="Idea.jpg" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+Using Perspectives in the Eclipse UI</h1></center>
+
+<h3>
+Summary</h3>
+In the Eclipse Platform a Perspective determines the visible actions and
+views within a window.&nbsp; Perspectives also go well beyond this by providing
+mechanisms for task oriented interaction with resources in the Eclipse
+Platform, multi-tasking and information filtering.&nbsp; In this article
+the concepts behind perspectives are examined.&nbsp; The process for perspective
+definition, extension and instantiation will also be covered in detail
+with coding examples and sample scenarios.
+<p><b>By Dave Springgay, OTI</b>
+<br>August 27, 2001
+<h3>
+
+<hr WIDTH="100%"></h3>
+
+<h3>
+Introduction</h3>
+In the Eclipse Platform there are two main layers: the model layer and
+the user interface layer.&nbsp; The underlying model, known as the Workspace,
+is a collection of resources (projects, folders and files).&nbsp; The user
+interface, or Workbench, defines the presentation for those resources.&nbsp;
+Within the workbench the Perspective feature is used to control the visibility
+of items in the model and the user interface.&nbsp; It controls what you
+see in the model (which project, folder or files) and what you see in the
+user interface (which actions or views).&nbsp; These controls make it possible
+to navigate through and modify the workspace in a way which suits the user
+task.
+<p>In this article the perspective concept will be explored in detail.&nbsp;
+In particular, we'll look at how it relates to task oriented interaction,
+multi-tasking and information filtering.&nbsp; We'll also look at the techniques
+to define a new perspective, extend an existing perspective, or instantiate
+a new perspective at runtime within the workbench.&nbsp; Coding samples
+are provided for each technique.
+<h3>
+What is a Perspective?</h3>
+A perspective is a visual container for a set of views and editors (parts).&nbsp;
+These parts exist wholly within the perspective and are not shared.&nbsp;
+A perspective is also like a page within a book.&nbsp; It exists within
+a window along with any number of other perspectives and, like a page within
+a book, only one perspective is visible at any time.
+<p>Each perspective has an <i>input</i> and a <i>type</i>.&nbsp; The <i>input</i>
+attribute is used to define which resources are visible in the workspace
+and the
+<i>type</i> attribute is used to define which actions and views
+are visible in the user interface.&nbsp; This design is a reflection of
+3 key concepts.
+<br>&nbsp;
+<ol>
+<li>
+Information Filtering</li>
+
+<li>
+Task Oriented Interaction with Your Information</li>
+
+<li>
+Two is Always Better than One</li>
+</ol>
+
+<p><br>Each of these will be covered in detail below.&nbsp; But before
+getting into the details, let's explore the idea of input and type.
+<p>On startup the workbench will most likely consist of one window with
+one perspective.&nbsp; For instance, the window may contain a Resource
+perspective on the entire workspace.&nbsp; This perspective has<i> input
+= the Workspace</i> and <i>type = Resource</i>.&nbsp; If you select a project
+or folder in the Navigator you can open a new perspective by invoking Open
+Perspective > Java&trade; from the object context menu.&nbsp; This new perspective
+has a different input and type: <i>input = the Project</i> and <i>type
+= Java</i>.&nbsp; Now there are two perspectives.&nbsp; The visible resources
+in the second perspective are a subset of those in the first.&nbsp; Each
+perspective contains a set of views and editors which exist wholly within
+the perspective and are not shared with the other.&nbsp; These parts define
+the presentation for a shared, underlying model.
+<h4>
+Information Filtering</h4>
+In a large, real world project the Eclipse Workspace may contain hundreds
+or thousands of resources.&nbsp; For instance, consider the following project
+in Eclipse.&nbsp; It may be small, but this project represents a typical
+three tier B2C web application.&nbsp; There are three folders: ClientSide,
+MiddleTier and DatabaseServer.&nbsp; Each folder represents a different
+tier in the application.&nbsp; The files types in each folder are also
+different.
+<pre>WebApplicationProject
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClientSide
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index.html
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; link1.html
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image1.html
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MiddleTier
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; script1.jsp
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; script2.cgi
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; script3.perl
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Main.java
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataBase.java
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DatabaseServer
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sqlScripts.script
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; serverConguration.config
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...</pre>
+The contents of this project are very typical of application development
+in the Internet age.&nbsp; No single language or technology can do it all,
+and software development involves the application of many technologies
+rather than just one.
+<p>An important tool for comprehension is information filtering.&nbsp;
+In other words, remove the irrelevant so you can see the relevant.&nbsp;
+In Eclipse this is performed in two ways, by using the inherent structure
+of the information (the resource tree) and the unstructured attributes
+of the information (file name, nature, resource type, etc.).&nbsp; For
+this discussion only the first style of information filtering is relevant.
+<p>In a large project the resources are usually structured within a hierarchy.&nbsp;
+The workspace contains many projects containing many folders containing
+many files.&nbsp; It's a tree, and each subtree within the whole defines
+a physical subset of information. This idea is the basis for information
+filtering within the workbench.&nbsp; The user can open a perspective on
+any resource subtree within the workspace.&nbsp; In the resulting perspective
+only the children of the subtree root are visible.&nbsp; The subtree root
+is known as the <i>input</i>.&nbsp; For example, if you open a perspective
+on MiddleTier within the WebApplicationProject only the children of MiddleTier
+are visible within the resulting perspective.&nbsp; The <i>input = MiddleTier</i>.
+<h4>
+Task Oriented Interaction with Your Information</h4>
+As a development platform Eclipse was designed to fulfill the needs of
+a large product development team, from product manager to content developer
+to product tester.&nbsp; It is fully extensible and may be configured with
+hundreds of action, wizard, view and editor extensions for any number of
+languages, tasks, roles, and phases within the development life cycle.&nbsp;
+In other words, it may contain a lot of junk you'll never use.&nbsp; To
+avoid the visual overload and confusion which would occur if everything
+was visible in the UI some mechanism is required to filter the user interface.
+<p>In Eclipse a task oriented approach was taken to filtering. Consider
+a Java developer.&nbsp; Within a single development cycle a Java developer
+may iterate through the following phases: Analysis and Design, Implementation,
+Debug, Testing and Documentation.&nbsp; In one phase the developer may
+use a UML modeling tool.&nbsp; In another you use a Problem Reporting tool.&nbsp;
+The time spent in each phase will vary but rapid transition between phases
+may occur several times a day.&nbsp; If we say that each phase is a "task"
+then it is possible to say there is rapid transition between tasks.&nbsp;
+In addition, the preferred way to look at resources in the workspace will
+change with the active task.
+<p>In Eclipse task orientation is embodied by perspective type.&nbsp; A
+perspective determines the visible actions, views, and view layout within
+the window.&nbsp; There are many types of perspective, and each one defines
+the layout in a different way.&nbsp; Ideally, the layout should be tailored
+to suit a particular set of related tasks.&nbsp; For instance, the standard
+Eclipse platform includes a Java perspective and a Team perspective.&nbsp;
+The Java perspective defines a layout containing the Package, Hierarchy,
+Outline and Tasks view.&nbsp; This is useful for java development.&nbsp;
+The Team perspective defines a layout containing the Repositories and Synchronize
+view.&nbsp; This is useful for code sharing and versioning.&nbsp; In Eclipse
+the user can open a new perspective with a particular type, switch from
+one perspective to another with different type, or change the type (layout)
+of an existing perspective as they move from one task to another.
+<h4>
+Two is Always Better than One</h4>
+In an earlier section we saw how information filtering can be used to limit
+information overload.&nbsp; When information filtering is implemented a
+new need develops: the need to see information which is not visible.&nbsp;
+For instance, a Java developer may explore one class hierarchy while they
+modify code in another.&nbsp; In Eclipse this functionality is provided
+by opening a second perspective on the information required.&nbsp; The
+ability to create two separate perspectives (or more) makes it possible
+to switch between information without loss of context.
+<p>The ability to open more than one perspective is also crucial for multi-tasking
+support.&nbsp; Developers often multi-task without even knowing it.&nbsp;
+For instance, in a team environment a coworker may walk into your office
+to ask a question.&nbsp; In response, you open up a class hierarchy and
+explore the code for a few minutes.&nbsp; This is a new task and it should
+have no impact upon your previous task.&nbsp; It demands good task separation.&nbsp;
+In Eclipse the creation of the second task can be accomplished by just
+opening a new perspective.&nbsp; When the task is complete you can close
+the perspective and return to the old task without loss of context.
+<h3>
+Moving from Concept to Implementation</h3>
+At a conceptual level a perspective is quite simple.&nbsp; A perspective
+is a visual container for a set of views and editors.&nbsp; It has an input
+and type.&nbsp; A perspective is also like a page within a book.&nbsp;
+It exists within a window along with any number of other perspectives and,
+like a page within a book, only one perspective is visible at any time.
+<p>At the implementation level things become more complex.&nbsp; The platform
+user interface is exposed through a series of interfaces in <tt>org.eclipse.ui</tt>.&nbsp;
+The root of the user interface is accessed by invoking <tt>PlatformUI.getWorkbench(
+)</tt>.&nbsp; This returns an object of type <tt>IWorkbench</tt>.&nbsp;
+A workbench has one or more windows of type <tt>IWorkbenchWindow</tt>.&nbsp;
+And each window has a collection of pages of type <tt>IWorkbenchPage</tt>.&nbsp;
+In the user interface a page is known as a "perspective".&nbsp; Within
+each window there is at most one active and visible page.
+<p>The structure of the workbench is exposed within the following diagram.&nbsp;
+The workbench window is outlined in red.&nbsp; Within this window there
+is a single open perspective.&nbsp; It's purple.&nbsp; But to be truly
+accurate, the user calls it a "perspective".&nbsp; At the implementation
+level it is an <tt>IWorkbenchPage</tt>.
+<center>
+<p><img SRC="workbench_decomposed.jpg" height=578 width=480 align=ABSCENTER></center>
+
+<p>While the workbench is running new windows and pages can be created
+interactively by invoking Open Perspective from the window menu or from
+the Navigator context menu.&nbsp; A page can also be created programmatically
+using public API on <tt>IWorkbenchWindow</tt>.&nbsp; For instance, the
+following code demonstrates the creation of a new page.
+<pre>// fWindow is an IWorkbenchWindow.
+fWindow.openPage("org.eclipse.ui.resourcePerspective", ResourcesPlugin.getWorkspace());</pre>
+In this example the two parameters to <tt>openPage</tt> identify the perspective
+type and input, in that order.&nbsp; The perspective type is identified
+by a string.&nbsp; Each perspective has a unique id.&nbsp; In this case
+<tt>"org.eclipse.ui.resourcePerspective"</tt>
+identifies the Resource perspective.&nbsp; The perspective input may be
+any object of type <tt>IAdaptable</tt>.&nbsp; In this case the input is
+the entire workspace.
+<p>The <tt>openPage</tt> method creates and returns an object of type <tt>IWorkbenchPage</tt>.&nbsp;
+Given a page, you can get the input and perspective type by using the following
+methods.
+<pre>public IAdaptable getInput();
+public IPerspectiveDescriptor getPerspective();</pre>
+There is an interesting twist here.&nbsp; When a new page is created you
+identify the perspective type by id.&nbsp; In the <tt>openPage</tt> method
+the id is mapped to a perspective descriptor within a list of known perspectives
+types and the result is stored within the return page.&nbsp; The <tt>getPerspective</tt>
+method on <tt>IWorkbenchPage</tt> returns an object of type <tt>IPerspectiveDescriptor</tt>.&nbsp;
+This object has accessor methods for the perspective id, label and icon.
+<p>The page input determines which resources are visible in the page.&nbsp;
+In practice, resource visibility in a page is implemented through collaboration
+between the page and the views within that page.&nbsp; The page itself
+is a visual container for views and editors.&nbsp; It doesn't provide any
+presentation for resources. That is delegated to the parts within the page.&nbsp;
+The hand-off usually occurs during part creation.&nbsp; In the early stages
+of part life cycle a part can obtain a handle to the containing <tt>IWorkbenchPage</tt>
+and from this it may call <tt>getInput</tt>.&nbsp; The result will be used
+as the initial input for this view.&nbsp; For instance, if a new perspective
+containing the Navigator is opened the Navigator will use the page input
+as its own input.&nbsp; The Packages view does the same.&nbsp; In some
+cases the view may provide additional actions to dynamically change the
+view input.&nbsp; In the Navigator the Go Into, Go Up, Go Back, and Go
+Forward actions can be used to navigate around the workspace tree.
+<p>The perspective determines which views are visible in a page.&nbsp;
+For instance, if you open a new page with the Resource perspective the
+Navigator, Outline, and editor area will be visible.&nbsp; If you open
+a new page with the Java perspective the Packages, Hierarchy, Tasks, and
+editor area will be visible.&nbsp; The visible views are determined by
+the perspective type. The type also influences the visible action sets
+within a page.&nbsp; For instance, the Java and Debug Action Sets are typically
+visible in the Java perspective but not in the Team perspective.&nbsp;
+This influence will be discussed in greater detail in <a href="#Adding a New Perspective">Adding
+a New Perspective</a>.
+<h3>
+<a NAME="Adding a New Perspective"></a>Adding a New Perspective</h3>
+Within the workbench a new perspective can be defined in two ways.&nbsp;
+An ISV can add a new perspective using the perspective extension point
+in the plug-in registry.&nbsp; A user can add a new perspective or override
+an existing perspective by using the customization and persistence features
+built in to the Eclipse user interface.&nbsp; This section will focus on
+the ISV scenario.
+<p>The definition of a new perspective is a three step process.
+<br>&nbsp;
+<ol>
+<li>
+Create a plug-in.</li>
+
+<li>
+Add a perspective extension to the plugin.xml file.</li>
+
+<li>
+Define a perspective class for the extension within the plug-in.</li>
+</ol>
+
+<p><br>This process will be illustrated by defining a plugin with a perspective
+called "Test".&nbsp; The Test Perspective will contain the Navigator View,
+the Outline View, and an editor area.&nbsp; The layout for the perspective
+is illustrated in the quick sketch below.
+<center>
+<p><img SRC="TestPerspectiveSketch.jpg" height=281 width=374></center>
+
+<p>In the first step a new plug-in is created.&nbsp; The process of plug-in
+creation is explained in detail in <a href="http://www.eclipsecorner.org/articles/Your%20First%20Plug-in.html">Your
+First Plugin</a>, by Jim Amsden, so I won't go into the details here.&nbsp;
+For this article I created a Perspective Plugin with following plugin.xml
+file.
+<pre>&lt;plugin
+&nbsp;&nbsp; id="org.eclipse.ui.articles.perspective"
+&nbsp;&nbsp; name="Perspective Article Plugin"
+&nbsp;&nbsp; version="1.0.0"></pre>
+
+<pre>&lt;requires>
+&nbsp;&nbsp; &lt;import plugin="org.eclipse.core.runtime"/>
+&nbsp;&nbsp; &lt;import plugin="org.eclipse.core.resources"/>
+&nbsp;&nbsp; &lt;import plugin="org.eclipse.ui"/>
+&lt;/requires></pre>
+
+<pre>&lt;runtime>
+&nbsp;&nbsp; &lt;library name="perspective.jar"/>
+&lt;/runtime></pre>
+
+<pre>&lt;/plugin></pre>
+The <tt>org.eclipse.ui</tt> plug-in defines a single extension point for
+perspective contribution: <tt>org.eclipse.ui.perspectives</tt>.&nbsp; A
+new perspective is added to the workbench by defining an extension for
+this point.&nbsp; In the example below a perspective extension is defined
+for the Test Perspective.&nbsp; This declaration contains the basic elements:
+id, name and class.
+<pre>&lt;extension point="org.eclipse.ui.perspectives">
+&nbsp;&nbsp; &lt;perspective
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="Test"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.eclipse.ui.articles.perspective.TestPerspective"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="org.eclipse.ui.articles.perspective.Test">
+&nbsp;&nbsp; &lt;/perspective>
+&lt;/extension></pre>
+A complete description of the extension point and the syntax are available
+in the developer documentation for <tt>org.eclipse.ui</tt>. The attributes
+are described as follows.
+<br>&nbsp;
+<ul>
+<li>
+<b>id</b> - a unique name that will be used to identify this perspective.</li>
+
+<li>
+<b>name</b> - a translatable name that will be used in the workbench window
+menu bar to represent this perspective.</li>
+
+<li>
+<b>class</b>&nbsp; – a fully qualified name of the class that implements
+<tt>org.eclipse.ui.IPerspectiveFactory</tt>
+interface.</li>
+
+<li>
+<b>icon</b> - a relative name of the icon that will be associated with
+this perspective.</li>
+</ul>
+
+<p><br>Perhaps the most important attribute in the perspective declaration
+is <i>class</i>.&nbsp; This attribute names a class that will define the
+initial layout for the perspective.&nbsp; In this example the layout for
+the Test perspective is defined by <tt>org.eclipse.ui.articles.perspective.TestPerspective</tt>.&nbsp;
+The implementation of <tt>TestPerspective</tt> will be examined in a few
+paragraphs.
+<p>Once a perspective extension has been declared for the Test Perspective
+it will appear in the Perspective > Open menu and in the Open Perspective
+menu of the Navigator.&nbsp; If the user invokes either of these actions
+a new workbench page will be created.&nbsp; During this process the following
+steps are taken.
+<br>&nbsp;
+<ol>
+<li>
+A new <tt>IWorkbenchPage</tt> object is created with perspective id = "org.eclipse.ui.articles.perspective.Test".</li>
+
+<li>
+The perspective id is used to lookup the actual perspective extension in
+the plugin registry.&nbsp; Within the workbench a list of the registered
+perspective extensions are stored within the <tt>IPerspectiveRegistry</tt>
+(available from the <tt>IWorkbench</tt> interface).&nbsp; The <tt>findPerspectiveWithId</tt>
+method is called to get a complete description of the perspective.&nbsp;
+This method returns an object of type <tt>IPerspectiveDescriptor</tt>.</li>
+
+<li>
+The perspective class is retrieved from the <tt>IPerspectiveDescriptor</tt>.&nbsp;
+This class must implement <tt>IPerspectiveFactory</tt>.</li>
+
+<li>
+An instance of the perspective class is created, yielding a <tt>IPerspectiveFactory</tt>.</li>
+
+<li>
+The <tt>createInitialLayout</tt> method is called on the <tt>IPerspectiveFactory</tt>.&nbsp;
+This method defines the initial layout for a page. Implementors may add
+views, folders, actions and action sets to the page layout.</li>
+
+<li>
+The <tt>IPerspectiveFactory</tt> is dereferenced and is not used again
+during the life cycle of the page.</li>
+
+<li>
+The <tt>IWorkbenchPage</tt> is activated.</li>
+</ol>
+
+<p><br>In the next few paragraphs we'll concentrate on point # 5.&nbsp;
+When <tt>createInitialLayout</tt> is called on an <tt>IPerspectiveFactory</tt>
+the page layout consists of an editor area with no additional views.&nbsp;
+Within <tt>createInitialLayout</tt> you can add views, folders, and view
+place holders to the page layout.&nbsp; A <i>folder</i> is a stack of views.&nbsp;
+A <i>place holder</i> marks the position of a view within the page.&nbsp;
+The view itself is not initially open, but when opened will occupy the
+position marked by the place holder.
+<p>In the example below you can see how <tt>createInitialLayout</tt> is
+implemented in the <tt>TestPerspective</tt> class.&nbsp; For clarity the
+algorithm has been split into two parts which define the actions and layout:
+<tt>defineActions</tt>
+and <tt>defineLayout</tt>.
+<pre>public void createInitialLayout(IPageLayout layout) {
+&nbsp;&nbsp;&nbsp; defineActions(layout);
+&nbsp;&nbsp;&nbsp; defineLayout(layout);
+}</pre>
+In <tt>defineActions</tt> a number of items and action sets are added to
+the window.&nbsp; A perspective may add items to the File > New, Show View,
+or Perspective > Open menus of the window.&nbsp; You can also add complete
+action sets to the menu or toolbar of the window.&nbsp; In this example
+a few File > New and Show View items are added.
+<pre>public void defineActions(IPageLayout layout) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add "new wizards".
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.folder");
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.file");
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add "show views".
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layout.addShowViewShortcut(IPageLayout.ID_RES_NAV);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layout.addShowViewShortcut(IPageLayout.ID_BOOKMARKS);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layout.addShowViewShortcut(IPageLayout.ID_OUTLINE);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layout.addShowViewShortcut(IPageLayout.ID_PROP_SHEET);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layout.addShowViewShortcut(IPageLayout.ID_TASK_LIST);
+}</pre>
+In <tt>defineLayout</tt> the TestPerspective factory adds two views to
+the layout.&nbsp; When <tt>createInitialLayout</tt> is called the page
+layout consists of an editor area with no additional views.&nbsp; Additional
+views are added using the editor area as the initial point of reference.&nbsp;
+In <tt>defineLayout</tt> the factory gets the id of the editor area.&nbsp;
+Then it creates a folder to the left of this area and adds the Navigator
+view and Outline view to this folder.
+<pre>public void defineLayout(IPageLayout layout) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Editors are placed for free.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String editorArea = layout.getEditorArea();
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Place navigator and outline to left of
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // editor area.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IFolderLayout left =
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layout.createFolder("left", IPageLayout.LEFT, (float) 0.26, editorArea);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; left.addView(IPageLayout.ID_RES_NAV);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; left.addView(IPageLayout.ID_OUTLINE);
+}</pre>
+The <tt>createFolder</tt> method adds a new folder to the page layout.&nbsp;
+The position and relative size of the folder are expressed as a fraction
+of an existing part.&nbsp; In the example above a folder is created with
+the name "left".&nbsp; It is positioned to the left of the editor area
+and occupies 26% of the original space of the editor area.&nbsp; The positioning
+constants are defined on <tt>IPageLayout</tt>, and include <tt>TOP, BOTTOM,
+LEFT </tt>and<tt> RIGHT</tt>.
+<p>In some situations a perspective within one plug-in may be referenced
+by another plug-in.&nbsp; For convenience, the unique id for each perspective
+should be declared on a public interface in the source plug-in.&nbsp; The
+unique id is usually derived by concatenating the plug-in id with some
+plug-in unique perspective id.&nbsp; For instance, the following approach
+was used for the Perspective plugin and perspective.
+<pre>public interface IPerspectivePlugin {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Plugin id.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public final static String PLUGIN_ID = "org.eclipse.ui.articles.perspective";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Test perspective id.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public final static String TEST_PERSPECTIVE_ID = PLUGIN_ID + ".Test";
+}</pre>
+The Test perspective is now ready to use.&nbsp; To test the new perspective
+I installed the Perspective plugin in the Eclipse plugins directory and
+then restarted Eclipse.&nbsp; From the Perspective > Open > Other... dialog
+I selected the Test perspective.&nbsp; After pressing OK the following
+page appeared within my window.
+<center>
+<p><img SRC="TestPerspective.jpg" height=406 width=559></center>
+
+<h4>
+Why is Layout Declaration done in Code Rather than XML?</h4>
+During the design of perspectives both options were considered.&nbsp; Within
+Eclipse XML is typically used to declare the presence of an extension and
+the circumstances under which it should be loaded.&nbsp; The information
+is used to load the extension and its plugin lazily for better startup
+performance.&nbsp; Now let's apply this logic to perspectives.&nbsp; When
+a perspective is selected from the Open Perspective menu the load conditions
+are met, so we can load the extension and move forward using Java.&nbsp;
+Java code provides the benefits of code completion and error detection
+at development time.
+<h4>
+Can I Remove the Editor Area Completely?</h4>
+In some scenarios the ideal layout for a perspective may be made up of
+one or more views with no editor area.&nbsp; To achieve this you can invoke
+<tt>IPageLayout.setEditorAreaVisible(boolean)</tt> to hide or show the
+editor area.&nbsp; This state will be honored unless the user decides to
+override it from the Perspective menu.
+<p>As a philosophical point, wouldn't it be great if you could punt the
+editor area completely?&nbsp; In fact, the workbench user interface favors
+the user more than the ISV.&nbsp; While the ISV may wish to define a closed
+environment with a fixed set of views, the user always has the ability
+to show any view from the Perspective > Show View menu.&nbsp; If the user
+can show any view they can also open any resource in an editor, and this
+necessitates an editor area.&nbsp; This underscores a very important point.&nbsp;
+A perspective definition is just a suggestion.&nbsp; The user can override
+it at any time and probably will.&nbsp; For more information on this idea
+see <a href="#User Customization and Persistance">User Customization and
+Persistence</a>.
+<h4>
+Do I Need a Perspective?</h4>
+The temptation to create a new perspective is strong.&nbsp; The dark side
+beckons.&nbsp; As an ISV, if you add a view extension to the platform you'd
+like some way to make it visible.&nbsp; One way to do that is to copy an
+existing perspective, say the Resource perspective, and add your view to
+the factory class.&nbsp; If every ISV took this approach the user would
+soon be overwhelmed by perspective choices.&nbsp; In all likelihood the
+user would ignore them all and create their own.
+<p>In general, a perspective should only be created when there is a certain
+group of related tasks which would benefit from a predefined configuration
+of actions and views.&nbsp; For instance, the Java Perspective is a good
+context for the completion of Java related tasks.&nbsp; It contains a Packages
+view and Hierarchy view for class navigation.&nbsp; The Tasks view is good
+for problem navigation.&nbsp; And the Outline view is useful for navigation
+within an editor.&nbsp; Together, these views are useful for many Java
+oriented tasks and the creation of a Java Perspective is justified.
+<p>In some situations it may be better to augment an existing perspective.&nbsp;
+For instance, if you create a single view which is Java centric it is probably
+better to add that view to the standard Java perspective rather than defining
+a new perspective.&nbsp; This strategy provides better integration with
+the existing platform.&nbsp; For more information on this process check
+out <a href="#Extend an Existing Perspective">Extending an Existing Perspective</a>.
+<h3>
+<a NAME="User Customization and Persistance"></a>User Customization and
+Persistence</h3>
+In the previous section we examined the techniques an ISV would use to
+add a perspective to the workbench.&nbsp; The user can also add a new perspective
+to the Eclipse user interface or override an existing perspective.&nbsp;
+This section will focus on those aspects of user customization.
+<p>When Eclipse is installed the plug-in registry contains a number of
+perspective extensions.&nbsp; These extensions are contributed by plug-ins
+from various ISV's and form the initial set of perspectives available to
+the user.&nbsp; In my own experience the perspectives contributed by an
+ISV usually fail to completely meet my needs, so I quickly customize them.&nbsp;
+I add views, remove views, add action sets, customize the menus, etc.,
+until the user interface reflects the way I work.&nbsp; Then I save the
+new layout to the original perspective.
+<p>The initial layout for a page is determined by the perspective.&nbsp;
+To be more precise, it is determined by an <tt>IPerspectiveFactory</tt>
+as explained in <a href="#Adding a New Perspective">Adding a New Perspective</a>.&nbsp;
+Once a page is open the user may modify the part layout or the visible
+action sets within the page.&nbsp; If this page is closed the new layout
+is discarded.&nbsp; However, if this page is open when the workbench is
+closed the state of the page (and in fact every window, page and part)
+is saved to an XML file in the <tt>org.eclipse.ui</tt> plug-in.&nbsp; This
+file is used to restore the state of the page when the workbench is restarted
+and contains every important attribute of the page: the visible views,
+their layout, the visible action sets and other state attributes.&nbsp;
+In fact, the <tt>IPerspectiveFactory</tt> which defined the initial layout
+for the page is not consulted when the page is restored.
+<p>The user can also create a new perspective by invoking Perspective >
+Save.&nbsp; In response a dialog appears where the user can type a user
+friendly name for the new perspective.&nbsp; Depending on the option chosen
+by the user, this action will create a new perspective with the layout
+of the current page or override the layout for an existing perspective.&nbsp;
+The resulting perspective has all of the privileges of an ISV perspective.&nbsp;
+The user can open a page with the custom perspective, use it as the default
+perspective, or delete it.&nbsp; The layout of the custom perspective is
+saved as an XML file using the same mechanism described above for workbench
+session persistence, so there is no <tt>IPerspectiveFactory</tt>.
+<h3>
+Opening a New Perspective</h3>
+In the workbench a new perspective can be created interactively by the
+user or programmatically through public API on <tt>IWorkbench, IWorkbenchWindow
+or IWorkbenchPage</tt>.&nbsp; For instance, the user may select a container
+in the Navigator and invoke Open Perspective > Java.&nbsp; This is an explicit
+command from the user to the view to create a new perspective.&nbsp; A
+new perspective may also be created as a step within some other action.&nbsp;
+For instance, if Project > Open Type is invoked an option exists to open
+a new Hierarchy Perspective.&nbsp; In this section the implementation of
+both will be discussed.
+<p>In the Navigator a user may open a new perspective with specific input
+and type by invoking Open Perspective from the context menu.&nbsp; This
+ability is an important element of information filtering and should be
+included in any view where the resource tree is visible.&nbsp; This will
+lead to user interface consistency and ease of use.
+<p>The easiest way to add Open Perspective functionality to a view or menu
+is with the <tt>OpenPerspectiveMenu</tt>.&nbsp; This class is supplied
+in
+<tt>org.eclipse.ui.actions</tt> and can be included in any popup menu.&nbsp;
+For instance, the following code demonstrates its use within the Navigator.
+<pre>/**
+&nbsp;* Add "open to" actions to the context sensitive menu.
+&nbsp;* @param menu the context sensitive menu
+&nbsp;* @param selection the current selection in the project explorer
+&nbsp;*/
+void fillOpenToMenu(IMenuManager menu, IStructuredSelection selection)&nbsp;
+{
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // If one file is selected get it.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Otherwise, do not show the "open with" menu.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (selection.size() != 1)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IAdaptable element = (IAdaptable) selection.getFirstElement();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!(element instanceof IContainer))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create a menu flyout.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MenuManager submenu = new MenuManager(ResourceNavigatorMessages.getString("ResourceNavigator.openPerspective")); //$NON-NLS-1$
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; submenu.add(new OpenPerspectiveMenu(getSite().getWorkbenchWindow(), element));
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; menu.add(submenu);
+
+}</pre>
+In this example the popup menu for the navigator is populated dynamically
+just before the menu is about to show.&nbsp; The <tt>fillOpenToMenu</tt>
+method is called from within <tt>menuAboutToShow</tt>.&nbsp; If the selection
+is a container (project or folder) the Open Perspective submenu is created
+and then populated automatically using the <tt>OpenPerspectiveMenu</tt>.&nbsp;
+The contents of this submenu are determined by the customized settings
+of the active perspective.&nbsp; For instance, if the Perspective > Open
+menu contains "Resource, Java, and Team" your context menu will also contain
+"Resource, Java, and Team".
+<p>In the workbench the behavior of Open Perspective in flexible.&nbsp;
+In fact, the user can configure this behavior in the workbench preferences.&nbsp;
+The "Open a New Perspective" behavior may be defined as "Open in Same Window",
+"Open in New Window", or "Replace Current".&nbsp;&nbsp; The meaning of
+"Open in Same Window" and "Open in New Window" are obvious.&nbsp; The meaning
+of "Replace Current" is less so.&nbsp; Each page has a perspective.&nbsp;
+If "Replace Current" is invoked the active perspective within the page
+is replaced by a new perspective.&nbsp; This causes the view layout and
+visible action sets within the page to change, and is equivalent to changing
+the layout in MS Studio.
+<p>The <tt>OpenPerspectiveMenu </tt>class implements the preferred behavior
+for "Open Perspective" and supports the selection of alternate behaviors
+when the Control or Shift keys are pressed.&nbsp; After the addition of
+an <tt>OpenPerspectiveMenu</tt> object to the context menu no other action
+is required to implement the Open Perspective behavior.
+<p>A new perspective may also be created as a step within some other action.&nbsp;
+For instance, if Project > Open Type is invoked the implementing action
+will open a new page with the Hierarchy perspective.&nbsp;&nbsp; In this
+scenario a new IWorkbenchPage must be created explicitly using the API's
+available on <tt>IWorkbenchWindow</tt>.&nbsp; The following code illustrates
+this process.
+<pre><tt>// Open the page.
+try {
+&nbsp;&nbsp; getWindow().openPage(IPerspectivePlugin.TEST_PERSPECTIVE_ID, pageInput);
+} catch (WorkbenchException e) {
+&nbsp;&nbsp; MessageDialog.openError(getWindow().getShell(),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Problem Opening Perspective",
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.getMessage());
+}</tt></pre>
+In the code above the active workbench window is retrieved and then <tt>openPage</tt>
+is invoked with a perspective type and input.&nbsp; As we saw in <a href="#Adding a New Perspective">Adding
+a New Perspective</a>, the id of each perspective should be exposed on
+a public interface in the source plug-in for convenient access by other
+plug-ins in Java code.&nbsp; In this example the Test perspective id is
+referenced from the <tt>IPerspectivePlugin</tt> class.&nbsp; The perspective
+id is mapped to an <tt>IPerspectiveDescriptor</tt> within the perspective
+registry.&nbsp; Then the page is opened.&nbsp; If any problems occur during
+the creation of the page an exception will be thrown.
+<p>As a philosophical point, should a hard coded constant be used to specify
+perspective type?&nbsp; In my own experience it is difficult to predict
+the usage pattern for any perspective.&nbsp; For instance, one user may
+prefer to develop java code in the Java perspective.&nbsp; Another may
+prefer to develop java code in the Resource perspective.&nbsp; If a hard
+coded constant is used to specify a perspective type the user may become
+frustrated if the wrong perspective is chosen.&nbsp; It may be better to
+let the user choose the perspective type or disable this behavior completely.
+<p>If you need to open a perspective from within an action there is one
+detail to be aware of: the user may change the default behavior for Open
+Perspective in the workbench preferences.&nbsp; In most scenarios your
+action should honor this preference.
+<p>To demonstrate the use of the Open Perspective preference I created
+an Action Set containing one action: "Open Test Perspective".&nbsp; When
+this action is invoked a new Test Perspective is opened using the preferred
+behavior.&nbsp;&nbsp; At the implementation level the action implements
+<tt>IWorkbenchWindowActionDelegate</tt>.&nbsp;
+Within the <tt>run</tt> method the preference is retrieved from the workbench
+plugin and then the perspective is opened.&nbsp; Here is an snippet containing
+the relevant details of my action delegate class.
+<pre>public void run(IAction action) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; openPerspective(IPerspectivePlugin.TEST_PERSPECTIVE_ID,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResourcesPlugin.getWorkspace());
+}
+
+/**&nbsp;
+&nbsp;* Implements Open Perspective.&nbsp;
+&nbsp;*/
+private void openPerspective(String perspId, IAdaptable input) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Get "Open Behavior" preference.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AbstractUIPlugin plugin = (AbstractUIPlugin)Platform.getPlugin(PlatformUI.PLUGIN_ID);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPreferenceStore store = plugin.getPreferenceStore();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pref = store.getString(IWorkbenchPreferenceConstants.OPEN_NEW_PERSPECTIVE);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Implement open behavior.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pref.equals(IWorkbenchPreferenceConstants.OPEN_PERSPECTIVE_WINDOW))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; workbench.openWorkbenchWindow(perspId, input);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (pref.equals(IWorkbenchPreferenceConstants.OPEN_PERSPECTIVE_PAGE))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; window.openPage(perspId, input);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (pref.equals(IWorkbenchPreferenceConstants.OPEN_PERSPECTIVE_REPLACE)) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPerspectiveRegistry reg = workbench.getPerspectiveRegistry();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; window.getActivePage().setPerspective(reg.findPerspectiveWithId(perspId));
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (WorkbenchException e) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+}</pre>
+
+<h3>
+<a NAME="Extend an Existing Perspective"></a>Extending an Existing Perspective</h3>
+In many scenarios the extension of an existing perspective is a good way
+to introduce new action sets, wizards, or views into the workbench.&nbsp;
+For instance, as an ISV you may create a new Java centric view to the workbench.&nbsp;
+Rather than defining a new perspective to show off your view, you can extend
+the standard Java perspective.&nbsp; This strategy provides better integration
+with the existing platform.&nbsp; In this section the details of perspective
+extension will be covered.
+<p>The extension of an existing perspective is a three step process.
+<br>&nbsp;
+<ol>
+<li>
+Create a plug-in for your extensions.</li>
+
+<li>
+Define an action set or view extension in the plugin.xml file.</li>
+
+<li>
+Add a perspectiveExtension extension to the plug-in registry.</li>
+</ol>
+
+<p><br>This process will be illustrated using the Test Perspective which
+was defined in a <a href="#Adding a New Perspective">Adding a New Perspective</a>.
+<p>The first step is to create a plug-in with an action set or view extension.&nbsp;
+In this example I chose to reuse a few extensions which already exist within
+<tt>org.eclipse.jdt.ui</tt>
+(the Java plug-in).&nbsp; This plug-in defines a Java Action Set, a New
+Java Project Wizard, a Packages View and a Hierarchy View.
+<p>The <tt>org.eclipse.ui</tt> plug-in defines an extension point for perspective
+extension: <tt>org.eclipse.ui.perspectiveExtensions</tt>.&nbsp; This extension
+point can be used to contribute any of the following objects to an existing
+extension perspective.
+<br>&nbsp;
+<ul>
+<li>
+Action Sets</li>
+
+<li>
+File New Items</li>
+
+<li>
+Show View Items</li>
+
+<li>
+Open Perspective Items</li>
+
+<li>
+Views</li>
+</ul>
+
+<p><br>In the following example the extension point is used to add the
+Java extensions discussed above to the Test perspective.&nbsp; In the first
+two lines of XML the target perspective extension is declared: <tt>org.eclipse.ui.articles.perspective.TestPerspective</tt>.&nbsp;
+Following this the specific extensions for this perspective are declared.&nbsp;
+An action set is added.&nbsp; Then menu items for Show View, File > New,
+and Open Perspective are added.&nbsp; And then the Packages view is stacked
+on top of the Navigator.
+<pre>&lt;extension point="org.eclipse.ui.perspectiveExtensions">
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;perspectiveExtension targetID="org.eclipse.ui.articles.perspective.Test">
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;actionSet id="org.eclipse.jdt.ui.JavaActionSet"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;viewShortcut id="org.eclipse.jdt.ui.PackageExplorer"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;newWizardShortcut
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="org.eclipse.jdt.ui.wizards.NewProjectCreationWizard"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;perspectiveShortcut id="org.eclipse.jdt.ui.JavaPerspective"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;view id="org.eclipse.jdt.ui.PackageExplorer"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; relative="org.eclipse.ui.views.ResourceNavigator"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; relationship="stack"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/perspectiveExtension>
+&lt;/extension></pre>
+In the next few paragraphs a brief description of each element within the
+perspectiveExtensions extension point is provided.&nbsp; A complete description
+of the extension point and the syntax are available in the developer documentation
+for org.eclipse.ui.
+<p>In the example an <tt>actionSet</tt>, <tt>viewShortcut</tt>, <tt>newWizardShortcut</tt>
+and <tt>perspectiveShortcut</tt> extension are demonstrated.&nbsp; The
+format of these elements is very simple.&nbsp; There is one attribute,
+<tt>id</tt>, which identifies an existing extension which should be added
+to the perspective.&nbsp; It must identify an action set, view, wizard,
+or perspective which has been registered using the standard extension point
+for each.
+<p>The XML for view extension is a little more complicated.&nbsp; A new
+view may be stacked on or placed relative to an existing view.&nbsp; Minimally,
+you must define an <tt>id</tt> (of the view being added), <tt>relative</tt>
+id, and <tt>relationship</tt> ( <tt>left, right, bottom, top, stack</tt>
+).&nbsp; If the relationship is not <tt>stack</tt> a <tt>ratio</tt> must
+also be supplied.&nbsp; This will be interpreted using the same heuristics
+as <tt>IPageLayout.addView(id, relationship, ratio, refID)</tt>.
+<p>In the current implementation of perspective extension there is one
+limitation.&nbsp; Perspective extension is only possible when the user
+has not modified the default layout for a perspective.&nbsp; If modification
+has occurred perspective extensions will be ignored. However, given the
+customizable nature of the workbench the user can always introduce an action
+set or view into the perspective by invoking the Perspective > Customize
+action or by opening a view from the Perspective > Show View menu.
+<h3>
+Conclusion</h3>
+In this article we have examined the role of perspectives within the workbench
+and their implementation.&nbsp; Perspectives are complex and will certainly
+evolve over time.&nbsp; Hopefully this article will get you started.&nbsp;
+Further information is available in the Platform Plug-in Developer Guide
+and in the javadoc for <tt>org.eclipse.ui</tt>.
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+
+</body>
+</html>
diff --git a/using-perspectives/TestPerspective.jpg b/using-perspectives/TestPerspective.jpg
new file mode 100644
index 0000000..d6d0d29
--- /dev/null
+++ b/using-perspectives/TestPerspective.jpg
Binary files differ
diff --git a/using-perspectives/TestPerspectiveSketch.jpg b/using-perspectives/TestPerspectiveSketch.jpg
new file mode 100644
index 0000000..7bd6d20
--- /dev/null
+++ b/using-perspectives/TestPerspectiveSketch.jpg
Binary files differ
diff --git a/using-perspectives/default_style.css b/using-perspectives/default_style.css
new file mode 100644
index 0000000..16277c9
--- /dev/null
+++ b/using-perspectives/default_style.css
@@ -0,0 +1,11 @@
+p { font-family: arial, helvetica, geneva; font-size: 10pt}
+td { font-family: arial,helvetica,geneva; font-size: -1}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+th { font-family: arial,helvetica,geneva; font-size: 11px; font-weight: bold}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
diff --git a/using-perspectives/workbench_decomposed.jpg b/using-perspectives/workbench_decomposed.jpg
new file mode 100644
index 0000000..d580da0
--- /dev/null
+++ b/using-perspectives/workbench_decomposed.jpg
Binary files differ
diff --git a/viewArticle/Idea.jpg b/viewArticle/Idea.jpg
new file mode 100644
index 0000000..119ce70
--- /dev/null
+++ b/viewArticle/Idea.jpg
Binary files differ
diff --git a/viewArticle/LabelView.jpg b/viewArticle/LabelView.jpg
new file mode 100644
index 0000000..acb5b05
--- /dev/null
+++ b/viewArticle/LabelView.jpg
Binary files differ
diff --git a/viewArticle/ListenerView.jpg b/viewArticle/ListenerView.jpg
new file mode 100644
index 0000000..91c3ce1
--- /dev/null
+++ b/viewArticle/ListenerView.jpg
Binary files differ
diff --git a/viewArticle/ViewArticle2.html b/viewArticle/ViewArticle2.html
new file mode 100644
index 0000000..0ecc4c2
--- /dev/null
+++ b/viewArticle/ViewArticle2.html
@@ -0,0 +1,1212 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Build">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
+ <title>Creating an Eclipse View</title>
+<link rel="stylesheet" href="default_style.css">
+</head>
+<body>
+
+<div align=right>&nbsp; <font face="Times New Roman, Times, serif"><font size=-1>Copyright
+&copy; 2001 Object Technology International, Inc.</font></font></div>
+
+<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" >
+<caption><TBODY>
+<br></TBODY></caption>
+
+<tr>
+<td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF">&nbsp;Eclipse
+Corner Article</font></font></b></td>
+</tr>
+</table>
+
+<h1>
+<img SRC="Idea.jpg" height=86 width=120 align=CENTER></h1>
+
+<center>
+<h1>
+Creating an Eclipse View</h1></center>
+
+<blockquote>
+<b>Summary</b>
+<br>
+In the Eclipse Platform a view is typically used to navigate a hierarchy
+of information, open an editor, or display properties for the active editor.&nbsp;
+In this article the design and implementation of a view will be examined
+in detail.&nbsp; You'll learn how to create a simple view based on SWT,
+and a more advanced view using the JFace viewer hierarchy.&nbsp; We'll
+also look at ways to achieve good integration with many of the existing
+features in the workbench, such as the window menu and toolbar, view linking,
+workbench persistence and action extension.
+<p><b>By Dave Springgay, OTI</b>
+<br> <font size="-1">November 2, 2001</font>
+
+</blockquote>
+ <hr WIDTH="100%">
+
+
+<h2>
+Introduction</h2>
+In the Eclipse Platform the workbench contains a collection of workbench
+windows.&nbsp; Each workbench window contains one or more pages, and each
+page contains a collection of editors and views.&nbsp; An editor is typically
+used to edit or browse a document or input object.&nbsp; Modifications
+made in an editor follow an open-save-close lifecycle model.&nbsp; A view
+is typically used to navigate a hierarchy of information, open an editor,
+or display properties for the active editor.&nbsp; In contrast to an editor,
+modifications made in a view are saved immediately.&nbsp; The layout of
+editors and views within a page is controlled by the active perspective.
+<p>The workbench contains a number of standard components which demonstrate
+the role of a view.&nbsp; For instance, the Navigator view is used to display
+and navigate through the workspace.&nbsp; If you select a file in the Navigator,
+you can open an editor on the contents of the file.&nbsp; Once an editor
+is open, you can navigate the structure in the editor data using the Outline
+view, or edit the properties of the file contents using the Properties
+view.
+<p>In this article we'll look at how you, as a plug-in developer, can add
+new views to the workbench.&nbsp; First we'll examine the process through
+the creation of a simple Label view.&nbsp; This view just displays the
+words "Hello World".&nbsp; Then we'll design and implement a more comprehensive
+view, called Word view, which displays a list of words which can be modified
+through addition and deletion.&nbsp; And finally, we'll look at ways to
+achieve good integration with many of the existing features in the workbench.
+<h2>
+Source Code</h2>
+<p>To run the example or view the source for code for this article you can unzip
+ <a href="viewArticleSrc.zip">viewArticleSrc.zip</a> into your <i>plugins/ </i>subdirectory.
+</p>
+<p>&nbsp; </p>
+<h2>
+<a NAME="Adding a New Perspective"></a>Adding a New View</h2>
+A new view is added to the workbench using a simple three step process.
+<br>&nbsp;
+<ol>
+<li>
+Create a plug-in.</li>
+
+<li>
+Add a view extension to the plugin.xml file.</li>
+
+<li>
+Define a view class for the extension within the plug-in.</li>
+</ol>
+
+<p><br>To illustrate this process we'll define a view called "Label", which
+just displays the words "Hello World".
+<h3>
+Step 1: Create a Plug-in</h3>
+In step 1 we need to create a new plug-in.&nbsp; The process of plug-in
+creation is explained in detail in <a href="http://www.eclipse.org/articles/Your%20First%20Plug-in.html">Your
+First Plugin</a>, by Jim Amsden, so we won't go into the details here.&nbsp;
+To be brief, we need to create a plugin project, and then define a plugin.xml
+file (shown below).&nbsp; This file contains a declaration of the plug-in
+id, name, pre-requisites, etc.
+<pre>&lt;?xml version="1.0" encoding="UTF-8"?>
+&lt;plugin
+&nbsp;&nbsp; name="Views Plugin"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp; id="org.eclipse.ui.articles.views"
+&nbsp;&nbsp; version="1.0.0"
+&nbsp;&nbsp; provider-name="OTI">
+
+&lt;requires>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;import plugin="org.eclipse.core.boot"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;import plugin="org.eclipse.core.runtime"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;import plugin="org.eclipse.core.resources"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;import plugin="org.eclipse.swt"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;import plugin="org.eclipse.ui"/>
+&lt;/requires>
+
+&lt;runtime>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;library name="views.jar"/>
+&lt;/runtime>
+
+&lt;/plugin></pre>
+
+<h3>
+Step 2: Add a View Extension to the plugin.xml file</h3>
+Once we have a plugin, we can define a view extension.&nbsp; The org.eclipse.ui
+plug-in defines a single extension point for view contribution: org.eclipse.ui.views.&nbsp;
+In the XML below, we use this extension point to add the Label view extension.&nbsp;
+This XML is added to the plugin.xml file, after the runtime element, and
+contains the basic attributes for the view: id, name, icon and class.
+<pre>&lt;extension point="org.eclipse.ui.views">
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;view id="org.eclipse.ui.articles.views.labelview"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="Label View"
+<img SRC="tag_a.jpg" BORDER=0 height=13 width=24>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.eclipse.ui.articles.views.LabelView"
+<img SRC="tag_b.jpg" BORDER=0 height=13 width=24>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icon="icons\view.gif"/>
+&lt;/extension></pre>
+A complete description of the view extension point and the syntax are available
+in the developer documentation for <tt>org.eclipse.ui</tt>.&nbsp; The attributes
+are described as follows.
+<br>&nbsp;
+<ul>
+<li>
+<b>id</b> - a unique name that will be used to identify this view</li>
+
+<li>
+<b>name</b> - a translatable name that will be used in the UI for this
+view</li>
+
+<li>
+<b>class</b> - a fully qualified name of the class that implements <tt>org.eclipse.ui.IViewPart</tt>.
+A common practice is to subclass <tt>org.eclipse.ui.part.ViewPart</tt>
+in order to inherit the default functionality.</li>
+
+<li>
+<b>icon</b> - a relative name of the icon that will be associated with
+the view.</li>
+</ul>
+
+<p><br>Perhaps the most important attribute is <i>class </i>(<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+This attribute must contain the fully qualified name of a class that implements
+<tt>org.eclipse.ui.IViewPart</tt>.&nbsp;
+The <tt>IViewPart</tt> interface defines the minimal responsibilities of
+the view, the chief one being to create an SWT Control within the workbench.&nbsp;
+This provides the presentation for an underlying model.&nbsp; In the XML
+above, the class for the Label view is defined as <tt>org.eclipse.ui.articles.views.LabelView</tt>.&nbsp;
+The implementation of <tt>LabelView</tt> will be examined in a few paragraphs.
+<p>The <i>icon</i> attribute (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>)
+contains the name of an image that will be associated with the view.&nbsp;
+This image must exist within the plugin directory or one of the sub directories.
+<h3>
+Step 3: Define a View Class for the Extension within the Plug-in</h3>
+Now we need to define the view class.&nbsp; To help us out, the platform
+contains an abstract class, named <tt>org.eclipse.ui.part.ViewPart</tt>,
+which implements most of the default behavior for an <tt>IViewPart</tt>.&nbsp;
+By subclassing this, we inherit all of the behavior.&nbsp; The result is
+LabelView (shown below).&nbsp; The methods in this class implement the
+view specific presentation.&nbsp; The <tt>createPartControl</tt> method
+(<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>)&nbsp; creates
+an SWT <tt>Label</tt> object to display the phrase "Hello World".&nbsp;
+The <tt>setFocus</tt> (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>)
+method gives focus to this control.&nbsp; Both of these methods will be
+called by the platform.
+<pre>package org.eclipse.ui.articles.views;
+
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.part.ViewPart;
+
+public class LabelView extends ViewPart {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Label label;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public LabelView() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>&nbsp;&nbsp;&nbsp;&nbsp; public void setFocus() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label.setFocus();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>&nbsp;&nbsp;&nbsp;&nbsp; public void createPartControl(Composite parent) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label = new Label(parent, 0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label.setText("Hello World");
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+
+}</pre>
+Once the LabelView class has been declared and compiled, we can test the
+results.&nbsp; To do this, invoke the Perspective > Show View > Other menu
+item.&nbsp; A dialog will appear containing all of the view extensions:
+the Label View item will appear in the Other category.&nbsp; If you select
+the Label View item and press OK, the view will be instantiated and opened
+in the current perspective.&nbsp; Here is a screen snapshot of the Label
+view after it has been opened within the Resource perspective.
+<center>
+<p><img SRC="LabelView.jpg" height=397 width=534></center>
+
+<h3>
+View Lifecycle</h3>
+The lifecycle of a view begins when the view is added to a workbench page.&nbsp;
+This can occur during the creation of the page, or afterwards, if the user
+invokes Perspective > Show View.&nbsp; In either case the following lifecycle
+is performed.
+<br>&nbsp;
+<ol>
+<li>
+An instance of the view class is instantiated.&nbsp; If the view class
+does not implement <tt>IViewPart</tt> an <tt>PartInitException</tt> is
+thrown.</li>
+
+<li>
+The <tt>IViewPart.init</tt> method is called to initialize the context
+for the view.&nbsp; An <tt>IViewSite</tt> object is passed, and contains
+methods to get the containing page, window, and other services is passed.</li>
+
+<li>
+The <tt>IViewPart.createPartControl</tt> method is called.&nbsp; Within
+this method the view can create any number of SWT controls within a parent
+<tt>Composite</tt>.&nbsp;
+These provide the presentation for some underlying, view specific model.</li>
+</ol>
+
+<p><br>When the view is closed the lifecycle is completed.
+<br>&nbsp;
+<ol>
+<li>
+The parent <tt>Composite</tt> passed to <tt>createPartControl</tt> is disposed.&nbsp;
+This children are also implicitly disposed.&nbsp; If you wish to run any
+code at this time, you must hook the control dispose event.</li>
+
+<li>
+The <tt>IViewPart.dispose</tt> method is called to terminate the part lifecycle.&nbsp;
+This is the last method which the workbench will call on the part.&nbsp;
+It is an ideal time to release any fonts, images, etc.</li>
+</ol>
+
+<h3>
+View Position</h3>
+As we have already seen, the user can open a view by invoking Perspective
+> Show View.&nbsp; In this scenario, the initial position of the new view
+is determined by the active perspective within the current page.&nbsp;
+You can think of a perspective as a layout containing views, folders, and
+place holders.&nbsp; A <i>folder</i> is a stack of views.&nbsp; A <i>place
+holder</i> marks the desired position of a view, should the user open it.&nbsp;
+When a new view is opened the platform will search the perspective for
+a place holder with the same <tt>id</tt> as the view.&nbsp; If such a place
+holder is found, it will be replaced by the new view.&nbsp; Otherwise,
+the new view will be placed on the right hand side of the page.
+<p>As a plugin developer, you may also define a new perspective which contains
+your view, or add your view to a perspective which has been contributed
+by another plug-in. In either case, you have greater control over view
+position.&nbsp; For more information about the use of perspectives see
+<a href="http://www.eclipse.org/articles/using-perspectives/PerspectiveArticle.html">Using
+Perspectives in the Eclipse UI</a>.
+<h3>
+Can I Declare A View Through API?</h3>
+Every view within the workbench must be declared in XML.&nbsp; There are
+two reasons for this.
+<br>&nbsp;
+<ol>
+<li>
+Within Eclipse, XML is typically used to declare the presence of an extension
+and the circumstances under which it should be loaded.&nbsp; This information
+is used to load the extension and its plugin lazily for better startup
+performance.&nbsp; For views in particular, the declaration is used to
+populate the Show View menu item before the plugin is loaded.</li>
+
+<li>
+The view declaration is also used for workbench persistence.&nbsp; When
+the workbench is closed, the id and position of each view within the workbench
+is saved to a file.&nbsp; It is possible to save the specific view class.&nbsp;
+However, the persistence of class names in general is brittle, so view
+id's are used instead.&nbsp; On startup, the view id is mapped to a view
+extension within the plugin registry.&nbsp; Then a new instance of the
+view class is instantiated.</li>
+</ol>
+
+<h2>
+The Word View</h2>
+In this section we'll implement a more comprehensive view, called Word
+view, which displays a list of words which can be modified through addition
+and deletion.
+<h3>
+Adding a View Extension to the plugin.xml file</h3>
+To start out, we add another view extension to the plugin.xml (shown below).&nbsp;
+This extension has the same format as the Label view: id, name, icon and
+class.&nbsp; In addition, the extension contains a <i>category</i> element
+(<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>).&nbsp; A <i>category</i>
+is used to group a set of views within the Show View dialog.&nbsp; A category
+must be defined using a category element.&nbsp; Once this has been done,
+we can populate the category by including the category attribute in the
+Word view declaration (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+The category, and the Word view within it, will both be visible in the
+Show View dialog.
+<pre>&lt;extension point="org.eclipse.ui.views">
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp; &lt;category&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="org.eclipse.ui.article"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="Article">
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/category>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;view id="org.eclipse.ui.articles.views.wordview"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="Word View"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icon="icons\view.gif"
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; category="org.eclipse.ui.article"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.eclipse.ui.articles.views.WordView"/>
+&lt;/extension></pre>
+
+<h3>
+Defining a View Class for the Extension within the Plug-in</h3>
+Now we need to define a view class for the Word view.&nbsp; For simplicity,
+we subclass ViewPart to create a WordView class (shown below), and then
+implement <tt>setFocus</tt> and <tt>createPartControl</tt>.&nbsp; The implementation
+of this class is discussed after the code.
+<pre>public class WordView extends ViewPart&nbsp;
+{
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WordFile input;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ListViewer viewer;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Action addItemAction, deleteItemAction, selectAllAction;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IMemento memento;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Constructor
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp; public WordView() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; input = new WordFile(new File("list.lst"));
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @see IViewPart.init(IViewSite)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp; public void init(IViewSite site) throws PartInitException {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.init(site);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Normally we might do other stuff here.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @see IWorkbenchPart#createPartControl(Composite)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+<img SRC="tag_c.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp; public void createPartControl(Composite parent) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create viewer.
+<img SRC="tag_d.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer = new ListViewer(parent);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.setContentProvider(new WordContentProvider());
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.setLabelProvider(new LabelProvider());
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.setInput(input);
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create menu and toolbars.
+<img SRC="tag_e.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createActions();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createMenu();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createToolbar();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createContextMenu();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hookGlobalActions();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Restore state from the previous session.
+<img SRC="tag_f.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; restoreState();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @see WorkbenchPart#setFocus()
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setFocus() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.getControl().setFocus();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+In the <tt>WordView</tt> constructor, the model, a <tt>WordFile</tt>, is
+created (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+The actual shape of the model is somewhat irrelevant, as we wish to focus
+on the details of view creation, and the appropriate model will vary with
+the problem domain.&nbsp; To be brief, a <tt>WordFile</tt> is simply a
+list of words which are stored in a file.&nbsp; The storage location of
+the <tt>WordFile</tt> is passed to the constructor.&nbsp; If this file
+exists the <tt>WordFile</tt> will read it.&nbsp; Otherwise it will create
+the file.&nbsp; The <tt>WordFile</tt> also has simple methods to add, remove,
+and get all of the words.&nbsp; Each word is stored in a <tt>Word</tt>
+object, which is just a wrapper for a <tt>String</tt>.&nbsp; The Word and
+WordFile classes are supplied with the source of this article.
+<p>After the view is instantiated, the <tt>IViewPart.init</tt> method is
+called with an <tt>IViewSite</tt> (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+The site is the primary interface between the view part and the outside
+world.&nbsp; Given the site, you can access the view menu, toolbar, status
+line, containing page, containing window, shell, etc.&nbsp; In the code
+above we simply call the superclass, ViewPart, where the site is stored
+in an instance variable.&nbsp; It can be retrieved at any time by calling
+getViewSite().
+<p>The <tt>createPartControl</tt> method (<img SRC="tag_c.jpg" height=13 width=24 align=ABSCENTER>)
+is called to create an SWT Control for the <tt>WordFile</tt> model.&nbsp;
+The creation of this presentation can be done with raw SWT widgets.&nbsp;
+However, the platform UI contains a class framework, known as JFace, which
+provides a viewer hierarchy for list, tree, table, and text widgets.&nbsp;
+A <i>viewer</i> is a wrapper for an SWT control, adding a model based interface
+to it.&nbsp;&nbsp; If you need to display a simple list model, tree model,
+or table model, use a viewer.&nbsp; Otherwise, it is probably easier to
+use raw SWT widgets.&nbsp; In the Word view the model is a simple list
+of words, so a ListViewer is used for the presentation.
+<p>On the first line of <tt>createPartControl</tt> the <tt>ListViewer</tt>
+is created (<img SRC="tag_d.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+The constructor chosen here automatically creates an SWT List control in
+the parent.&nbsp; Then a <i>content provider</i> is defined.&nbsp; A content
+provider is an adapter for a domain specific model, wrapping it in an abstract
+interface which the viewer invokes to get the model root and its children.&nbsp;
+If the model (the <tt>WordFile</tt>) changes, the content provider will
+also refresh the state of the <tt>ListViewer</tt> to make the changes visible.&nbsp;
+A <i>label provider</i> is also defined.&nbsp; This serves up a label and
+image for each object which is supplied by the content provider.&nbsp;
+And finally, we set the input for the <tt>ListViewer</tt>.&nbsp; The input
+is just the
+<tt>WordFile</tt> created in the <tt>WordView</tt> constructor.
+<p>The <tt>createPartControl</tt> method also contains several method calls for
+ the creation of a menu, toolbar, context menu, and global actions (<img SRC="tag_e.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+ These methods will be examined in later sections.&nbsp; For now, it is sufficient
+ to say that each view has a local menu and toolbar which appear in the view
+ title area.&nbsp; The view itself may contribute menu and toolbar items to these
+ areas.&nbsp; The view may define a context menu (pop-up menu) for each control
+ it creates, or hook a global action in the parent window.&nbsp; A <i>global
+ action</i> refers to those actions in the window menu and toolbar which are
+ always visible, but delegate their implementation to the active part.&nbsp;
+ For instance, the Cut, Copy and Paste actions are always visible in the Edit
+ menu.&nbsp; If invoked, their implementation is delegated to the active part.&nbsp;
+ The last line (<img SRC="tag_f.jpg" height=13 width=24 align=ABSCENTER>) relates
+ to state persistence between sessions.&nbsp; We will examine the code for each
+ of these features in later sections.
+<p>Once the Word view has been declared and compiled we can test the results.&nbsp;
+To do this, invoke Perspective > Show View > Other, and then select the
+Word View in the Show View dialog.&nbsp; The Word view will appear in the
+Resource perspective, as shown below.
+<center>
+<p><img SRC="WordView.jpg" height=397 width=534></center>
+
+<h2>
+Menus and Toolbars</h2>
+As the Word view exists now it isn't very useful.&nbsp; We can browse a
+list of words, but we can't modify that list.&nbsp; In this section we'll
+add some menu and toolbar items to the view so the user can add and delete
+words within the list.
+<p>But first, some background information.&nbsp; Each view has a local
+menu and toolbar.&nbsp; The toolbar is located to the right of the view
+caption.&nbsp; The menu is initially invisible, but becomes visible if
+you click on the menu button, which is just to the left of the close button.&nbsp;
+For instance, here is a snapshot of the Word view with the menu and toolbar
+we are about to define.
+<center>
+<p><img SRC="menus.jpg" height=247 width=264></center>
+
+<p>The menu and toolbar controls for a view are initially empty and invisible.&nbsp;
+As the view adds items to each, the menu or toolbar will become visible.&nbsp;
+A view can also contribute items to the status line which appears at the
+bottom of the parent window.&nbsp; Together, the local menu, toolbar and
+status line are known as the <i>action bars</i>.
+<p>In code, access to the action bars is provided by the view site.&nbsp;
+The site is the primary interface between the view part and the outside
+world.&nbsp; If your view is a subclass of ViewPart, the site can be accessed
+by calling ViewPart.getViewSite.&nbsp; If not, then you must manage your
+own storage and retrieval of the site, which is passed to the view in the
+IViewPart.init method.&nbsp; Given the site, you can call <tt>getActionBars().getMenuManager</tt>
+to get an <tt>IMenuManager</tt>, or getActionBars().getToolBarManager()
+to get an IToolBarManager.
+<p>The IMenuManager and IToolBarManager interfaces are a JFace abstraction.&nbsp;
+They wrap an SWT <tt>Menu</tt> or <tt>Toolbar</tt> object so that you,
+the developer, can think in terms of action and action contribution. An
+<i>action</i>
+represents a command which can be triggered by the user from a menu or
+toolbar.&nbsp; It has a run method, plus other methods which return the
+menu or tool item presentation (text, image, etc.).&nbsp; In JFace, you
+create a menu or toolbar by adding instances of org.eclipse.jface.action.IAction
+to an IMenuManager or IToolBarManager.
+<h3>
+Defining our Actions</h3>
+We will contribute an "Add..." and "Delete" action to the Word view toolbar,
+and a "Select All" action to the view menu.&nbsp; In general, the initial
+actions within a view are contributed using Java&trade; code, and other plugin
+developers extend the menus and toolbars of a view using XML.
+<p>In the WordView class, the actions are created in the createActions
+method (shown below), which is called from createPartControl.&nbsp; For
+simplicity, each action is defined as anonymous subclass (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>)
+of <tt>org.eclipse.jface.actions.Action</tt>.&nbsp; We override the run
+method (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>) to implement
+the actual behavior of the action.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void createActions() {
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addItemAction = new Action("Add...") {
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addItem();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };
+<img SRC="tag_c.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addItemAction.setImageDescriptor(getImageDescriptor("add.gif"));</pre>
+
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteItemAction = new Action("Delete") {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteItem();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteItemAction.setImageDescriptor(getImageDescriptor("delete.gif"));</pre>
+
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; selectAllAction = new Action("Select All") {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; selectAll();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add selection listener.
+<img SRC="tag_d.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void selectionChanged(SelectionChangedEvent event) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateActionEnablement();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+The label of each action is defined in the action constructor (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+In addition, an image is defined for the "Add..." and "Delete" actions
+(<img SRC="tag_c.jpg" height=13 width=24 align=ABSCENTER>), since they
+will appear in the toolbar.&nbsp; These images are defined by invoking
+getImageDescriptor (shown below), a method which returns an image descriptor
+for a file stored in the plugin directory.&nbsp; Within this method the
+ViewsPlugin object is retrieved, the install URL (plugin directory) is
+determined, and then an ImageDescriptor is created for a path based on
+this URL.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Returns the image descriptor with the given relative path.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private ImageDescriptor getImageDescriptor(String relativePath) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String iconPath = "icons/";
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ViewsPlugin plugin = ViewsPlugin.getDefault();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL installURL = plugin.getDescriptor().getInstallURL();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL url = new URL(installURL, iconPath + relativePath);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ImageDescriptor.createFromURL(url);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (MalformedURLException e) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // should not happen
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ImageDescriptor.getMissingImageDescriptor();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+
+<p><br>On the last line of createActions (<img SRC="tag_d.jpg" height=13 width=24 align=ABSCENTER>),
+a selection listener is created and added to the list viewer.&nbsp; In
+general, the enablement state of a menu or tool item should reflect the
+view selection.&nbsp; If a selection occurs in the Word view, the enablement
+state of each action will be updated in the updateActionEnablement method
+(shown below).
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void updateActionEnablement() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IStructuredSelection sel =&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (IStructuredSelection)viewer.getSelection();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteItemAction.setEnabled(sel.size() > 0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+
+<p><br>The approach taken for action enablement in the Word view is just
+one way to go.&nbsp; It is also possible to imagine an implementation where
+each action is a selection listener, and will enable itself to reflect
+the selection.&nbsp; This approach would make the actions reusable beyond
+the context of the original view.
+<h3>
+Adding our Actions</h3>
+Once the actions have been created we can add them to the existing menu
+and toolbar for the view.&nbsp; In the WordView class, this is done in
+the createMenu and createToolbar methods (shown below), which are called
+from createPartControl.&nbsp; In each case the view site is used to access
+the menu and toolbar managers, and then actions are added.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Create menu.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void createMenu() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IMenuManager mgr = getViewSite().getActionBars().getMenuManager();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mgr.add(selectAllAction);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Create toolbar.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void createToolbar() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mgr.add(addItemAction);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mgr.add(deleteItemAction);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+At this point the definition of the menu and toolbar are complete.&nbsp;
+If the Word view is opened in the workbench, the toolbar will be populated
+with the Add and Delete items.&nbsp; If you click the down arrow for the
+menu, you will see the Select All item there.
+<h2>
+<a NAME="Context Menus"></a>Context Menus</h2>
+In Eclipse, it is very common to expose and invoke actions from the context
+menu.&nbsp; For instance, if you press and release the right mouse button
+over an IFile in the Navigator, a context menu appears with standard file
+operations like Open, Rename, and Delete.&nbsp; Experienced users come
+to expect this, so in this section we will define a context menu for the
+Word view.
+<p>But first, some background info.&nbsp; One of the primary goals for
+the platform UI is extensibility.&nbsp; In fact, it is this extensibility
+which gives you the freedom to add new views, editors, perspectives, actions,
+etc., to the platform.&nbsp; Of course, extensibility is a two way street.&nbsp;
+While you may wish to extend the platform, others may wish to extend your
+view.&nbsp; It is common for one plug-in to add actions to the menu, toolbar,
+or context menu of a view from another plugin.
+<p>Support for context menu extension is accomplished by collaboration
+between the view and the platform.&nbsp; In contrast to the local menu
+and toolbar for each view, which are created by the platform and populated
+by the view, each context menu within a view must be created by the view
+itself.&nbsp; This is because the context menus within a view are beyond
+the scope of platform visibility, and there may be zero, one, or many context
+menus within the view.&nbsp; Once a context menu has been created, the
+view must explicitly register each context menu with the platform.&nbsp;
+This makes it available for extension.
+<p>A context menu can be created using the SWT
+<tt>Menu</tt> and <tt>MenuItem</tt>
+classes directly, or it can be created using the JFace
+<tt>MenuManager</tt>
+class.&nbsp; If you define a context menu using the MenuManager class,
+the platform can extend this menu with actions.&nbsp; However, if you define
+a context menu using the SWT Menu and MenuItem classes directly, this is
+not possible.
+<h3>
+Creating the Context Menu</h3>
+In the WordView class, the context menu is created in the createContextMenu
+method (shown below), which is called from createPartControl.&nbsp;&nbsp;
+Within this method a MenuManager is created (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>),
+a menu is created (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>),
+and then the menu manager is passed to the platform for extension with
+other actions (<img SRC="tag_c.jpg" height=13 width=24 align=ABSCENTER>).
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void createContextMenu() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create menu manager.
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MenuManager menuMgr = new MenuManager();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; menuMgr.setRemoveAllWhenShown(true);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; menuMgr.addMenuListener(new IMenuListener() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void menuAboutToShow(IMenuManager mgr) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fillContextMenu(mgr);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create menu.
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Menu menu = menuMgr.createContextMenu(viewer.getControl());
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.getControl().setMenu(menu);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Register menu for extension.
+<img SRC="tag_c.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getSite().registerContextMenu(menuMgr, viewer);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+In the first few lines of <tt>createContextMenu</tt> a new <tt>MenuManager</tt>
+is created (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>),
+and it is configured for dynamic action population.&nbsp; In other words,
+w<font color="#000000">henever the menu is opened, the old actions will
+be removed, and new actions will be added to reflect the current selection.&nbsp;
+This behavior is a requirement for action extension, and if not implemented,
+the action extensions contributed by the platform will soon flood the context
+menu.&nbsp;&nbsp;&nbsp; To accomplish this, we invoke setRemoveAllWhenShown(true)
+to clear the menu when it opens.&nbsp; Then we add a menu listener to populate
+the menu when it opens.&nbsp; The menu listener just calls fillContextMenu,
+which will be discussed below.</font>
+<p>After creating the MenuManager, we can create the menu, and then register
+the menu manager with the site (<img SRC="tag_c.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+Take a good look at the last line of createContextMenu.&nbsp; In this statement
+we pass the menu manager and the viewer to the site.&nbsp; In general,
+the platform will only add action extensions to a menu if it opens.&nbsp;
+At that time, the action extensions for the menu are determined by examining
+the menu id and view selection.&nbsp; So where is the menu id?&nbsp; To
+answer, we need to look at the definition of IWorkbenchPartSite.registerContextMenu.&nbsp;
+There are two registerContextMenu methods (shown below).&nbsp; If there
+is only one context menu in the view, we should call the first.&nbsp; The
+menu id will be derived from the part id to ensure consistency.&nbsp; So
+in this case, our menu id is "org.eclipse.ui.articles.views.wordview".&nbsp;
+If there is more than one context menu in the view, we should use the second,
+where the menu id is explicit.
+<pre>&nbsp;&nbsp;&nbsp; // Defined on IWorkbenchPartSite.
+&nbsp;&nbsp;&nbsp; public void registerContextMenu(MenuManager menuManager,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ISelectionProvider selectionProvider);
+&nbsp;&nbsp;&nbsp; public void registerContextMenu(String menuId, MenuManager menuManager,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ISelectionProvider selectionProvider);</pre>
+If the user opens our context menu, the fillContextMenu method will be
+called.&nbsp;&nbsp; This method adds the Add, Delete and SelectAll actions
+to the menu.&nbsp; It is important to notice that a <tt>GroupMarker</tt>
+is also added to the menu for "additions" (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+This group will be used as a target for action extension by other plug-ins.&nbsp;
+If it does not exist, all of the action extensions will appear at the end
+of the menu.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void fillContextMenu(IMenuManager mgr) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mgr.add(addItemAction);
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mgr.add(deleteItemAction);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mgr.add(new Separator());
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mgr.add(selectAllAction);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+
+<h3>
+Supporting Extension of the Context Menu</h3>
+In the last section extensibility was a prominent issue.&nbsp; If we want
+to support context menu extension in the Word view, or any other view,
+the following process should be followed.
+<br>&nbsp;
+<ol>
+<li>
+If you create a context menu, publish the menu id in a public interface
+which other plug-in developers can reference.</li>
+
+<li>
+Add a GroupMarker with <i>id == IWorkbenchActionConstants.MB_ADDITIONS</i>
+to each context menu.&nbsp; Other plug-in developers will use this as a
+target for menu extensions.</li>
+
+<li>
+If you have additional groups in the menu, publish each id.</li>
+
+<li>
+Register each context menu with your IWorkbenchPartSite.&nbsp; If you don't
+do this the workbench can't extend it.</li>
+
+<li>
+Define an IActionFilter for each of the objects in your model.&nbsp; Within
+this filter, publish the filter attributes.&nbsp; This allows for more
+accurate targeting of menu extensions.</li>
+</ol>
+
+<p><br>The first couple of items have already been discussed.&nbsp; At
+this point we will focus on the last point: define an IActionFilter for
+each object in your model.
+<h3>
+The Simple Case of Action Extension</h3>
+An action can be added to a context menu by defining an extension for the
+<tt>org.eclipse.ui.popupMenus</tt>
+extension point in the workbench plug-in.&nbsp; For instance, the following
+XML can be used to add the "Word Action" to the context menu for Word objects.&nbsp;
+Without going into too many details, the target for the action is specified
+by declaring an <tt>objectContribution </tt>(<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>)
+with an <tt>objectClass</tt> of <tt>org.eclipse.ui.articles.views.Word
+</tt>(<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+Once this declaration is made, the action will appear within the context
+menu for any Word.
+<pre>&lt;extension point="org.eclipse.ui.popupMenus">
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp; &lt;objectContribution
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="org.eclipse.ui.articles.pm1"
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objectClass="org.eclipse.ui.articles.views.Word">
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="org.eclipse.ui.articles.a1"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label="Word Action"&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; menubarPath="additions"&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.eclipse.ui.articles.views.WordActionDelegate"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/objectContribution>
+&lt;/extension></pre>
+The target for an <tt>objectContribution</tt> can be defined using the
+<tt>objectClass</tt>
+attribute and an optional <tt>nameFilter</tt> attribute.&nbsp; The <tt>nameFilter</tt>
+is used to specify objects with a specific label.&nbsp; Together, these
+attributes provide reasonable accuracy when targeting objects.
+<h3>
+The Problem Case of Action Extension</h3>
+In some situations the <tt>objectClass</tt> and <tt>nameFilter</tt> attributes
+are not enough to describe the intended target object.&nbsp; For instance,
+what if we wanted to add an action to a .java file which is read only,
+or a project which has the java nature?&nbsp; Luckily, the platform can
+help.
+<p>Within an <tt>objectContribution</tt>, a plug-in developer may define
+<tt>filter</tt>
+sub elements. Each <tt>filter</tt> describes one attribute of the target
+object using a name value pair.&nbsp; For instance, the following XML can
+be used to target an action at any Word object with <i>name = "Blue"</i>.&nbsp;
+Notice how the <tt>filter</tt> sub element (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>)
+is used to define an attribute value pair.
+<pre>&lt;extension point="org.eclipse.ui.popupMenus">
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;objectContribution
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="org.eclipse.ui.articles.pm2"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objectClass="org.eclipse.ui.articles.views.Word">
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter name="name" value="Blue"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="org.eclipse.ui.articles.a2"
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label="Blue Action"&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; menubarPath="additions"&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.eclipse.ui.articles.views.BlueActionDelegate"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/objectContribution>
+&lt;/extension></pre>
+Now let's look at the implementation of the <tt>filter</tt> sub element.&nbsp;
+The attributes for an object are type specific, and beyond the domain of
+the workbench itself, so the workbench will delegate filtering at this
+level to the selection itself.&nbsp; To do this, the platform will test
+to see if the selected object implements an <tt>org.eclipse.ui.IActionFilter</tt>.&nbsp;
+This is a type specific filtering strategy.&nbsp; If the selection does
+not implement <tt>IActionFilter</tt>, the platform will ask the selection
+for a filter using the IAdaptable mechanism defined in org.eclipse.core.runtime.&nbsp;
+If a filter is found, the platform will pass each name value pair to the
+filter to determine if it matches the state of the selected object.&nbsp;
+If so, or there is no IActionFilter, the action will be added to the context
+menu for the object.
+<p>In order to support the XML above, we need to define an IActionFilter
+for the Word class.&nbsp; To do this, we define a class called WordActionFilter
+(shown below), which simply implements the IActionFilter interface (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+This class is defined as a singleton for memory efficiency (<img SRC="tag_c.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+It also publishes the filter attributes for the Word class (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>),
+so that they can be referenced outside the plugin.
+<pre><img SRC="tag_a.jpg" height=13 width=24 align=TEXTTOP> public class WordActionFilter implements IActionFilter {
+
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp; public static final String NAME = "name";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static WordActionFilter singleton;
+
+<img SRC="tag_c.jpg" height=13 width=24 align=TEXTTOP>&nbsp;&nbsp;&nbsp;&nbsp; public static WordActionFilter getSingleton() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (singleton == null)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = new WordActionFilter();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return singleton;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @see IActionFilter#testAttribute(Object, String, String)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public boolean testAttribute(Object target, String name, String value) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (name.equals(NAME)) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Word le = (Word)target;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return value.equals(le.toString());
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+}</pre>
+The action filter for the Word class will be exposed using the IAdaptable
+mechanism.&nbsp; To do this, we need to implement the IAdaptable interface
+on our Word object, and return the WordActionFilter singleton if the platform
+asks for an IActionFilter.&nbsp; The implementation of getAdapter is shown
+below.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object getAdapter(Class adapter) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (adapter == IActionFilter.class) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return WordActionFilter.getSingleton();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+At this point the WordActionFilter is complete.&nbsp; If we open the Word
+view and select a Word with <i>name = Blue</i>, the "Blue Action" will
+appear in the context menu.&nbsp; Stepping back from this example, the
+WordActionFilter is actually fairly useless.&nbsp; However, it does illustrate
+how precise action extension targeting should be supported by a model within
+a view (or editor).
+<p>In the platform, action filters already exist for markers, resources,
+and projects.&nbsp; The attribute names for each are defined in IMarkerActionFilter,
+IResourceActionFilter, and IProjectActionFilter within org.eclipse.ui,
+so other plug-in developers can reference them easily.&nbsp; If we look
+at an existing, production quality filter like IResourceActionFilter we
+can see that it contains matching attributes for NAME, EXTENSION, PATH,
+READ_ONLY and PROJECT_NATURE.&nbsp; You should define attributes which
+reflect your own model and permit precise action targeting.
+<h2>
+Integration with the Window Menu and Toolbar</h2>
+In the workbench window menu there are a number of pre-existing actions
+which target the active part (as indicated by a shaded title bar) .&nbsp;
+For instance, if the Delete action within the Edit menu is invoked when
+the Navigator view is active, the Delete implementation is delegated to
+the Navigator view.&nbsp; If the Tasks view is active the Delete implementation
+is delegated to that view.&nbsp; The Delete action is just one of many
+actions, known as <i>global actions</i>, which are always visible within
+the window menu and, when invoked, delegate their implementation to the
+active part.
+<p>In the Word view there are three actions (Add, Delete and Select All).&nbsp;
+The complete set of global actions is declared in IWorkbenchActionConstants.GLOBAL_ACTIONS
+(shown below).&nbsp; A quick comparison will demonstrate that there is
+no semantic equivalent to Add, but the Delete (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>)
+and Select all actions (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>)
+are represented within the global actions.&nbsp; So the Word view will
+hook both of these actions.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * From IWorkbenchActionConstants.&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Standard global actions in a workbench window.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String [] GLOBAL_ACTIONS = {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNDO,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; REDO,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CUT,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; COPY,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PASTE,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PRINT,
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER><font color="#000000"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </b>DELETE,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FIND,
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT_ALL,
+</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOKMARK
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };
+}</pre>
+In the WordView class, the global actions are hooked within hookGlobalActions
+(shown below), which is called from createPartControl.&nbsp; Within this
+method, the Word view retrieves the action bars from the workbench part
+site (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>) and then
+calls setGlobalActionHandler for each action (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+This establishes a link between the global action in the window and the
+implementation within the view.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void hookGlobalActions() {
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IActionBars bars = getViewSite().getActionBars();
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bars.setGlobalActionHandler(IWorkbenchActionConstants.SELECT_ALL, selectAllAction);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bars.setGlobalActionHandler(IWorkbenchActionConstants.DELETE, deleteItemAction);
+<img SRC="tag_c.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.getControl().addKeyListener(new KeyAdapter() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void keyPressed(KeyEvent event) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (event.character == SWT.DEL &amp;&amp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; event.stateMask == 0 &amp;&amp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteItemAction.isEnabled())&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteItemAction.run();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+On the last line of hookGlobalActions (<img SRC="tag_c.jpg" height=13 width=24 align=ABSCENTER>)
+we add a key listener to the viewer control.&nbsp; If the "delete" key
+is pressed, the Delete action should run.&nbsp; In the case of every other
+action except Delete, the accelerator is defined and implemented by the
+workbench, so there is no need for a key listener.&nbsp; In the case of
+Delete, however, a key listener must be defined in the part.&nbsp; This
+extra work is required because the platform cannot define an accelerator
+containing the delete key.&nbsp; In doing so, it would break any text editors
+where the "delete" key has two different behaviors: delete the selection,
+and delete the next character.
+<p>Registration of the global action handlers is complete.&nbsp; If the
+Select All or Delete action in the window is invoked, and the Word view
+is active, the corresponding handler within the Word view will be invoked.&nbsp;
+The approach taken here can be used for other actions, and you are encouraged
+to do so.&nbsp; For instance, most editors provide a handler for all of
+the global actions.&nbsp; The Navigator implements the Delete and Bookmark
+actions.&nbsp; The Tasks view implements the Delete and Select All actions.
+<h3>
+Can I add new actions to the window menu or toolbar?</h3>
+In general all view actions should be contributed to the local menu, toolbar,
+or context menu for a view.&nbsp; There is no way to add view specific
+actions to a window menu or toolbar. The justification for this is simple:
+the proximity of view actions to the view itself creates a stronger coupling
+between the two, and it also helps to reduce clutter on the window menu
+and toolbar.
+<h2>
+Integration with Other Views</h2>
+No view is an island.&nbsp; In most cases, a view co-exists with other
+views and selection within one view may affect the input of another.&nbsp;
+In this section we'll create a Listener view, which will listen for the
+selection of objects in the Word view.&nbsp; If a Word object is selected,
+the Listener view will display the word attributes.&nbsp; This behavior
+is similar to the existing Properties view in the workbench standard components.
+<p>To start out, we need to create a new Listener view.&nbsp; We've already
+done this twice, so let's skip the declaration within the plugin.xml and
+concentrate on the ListenerView class (shown below).&nbsp; This class is
+very similar to LabelView.&nbsp; In createPartControl we create a simple
+SWT Label (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>), where
+we will display the word attributes.
+<pre>public class ListenerView extends ViewPart&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; implements ISelectionListener
+{
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Label label;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ListenerView() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setFocus() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label.setFocus();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp; public void createPartControl(Composite parent) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label = new Label(parent, 0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label.setText("Hello World");
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getViewSite().getPage().addSelectionListener(this);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @see ISelectionListener#selectionChanged(IWorkbenchPart, ISelection)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
+<img SRC="tag_c.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp; public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (selection instanceof IStructuredSelection) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object first = ((IStructuredSelection)selection).getFirstElement();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (first instanceof Word) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; label.setText(((Word)first).toString());
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+}</pre>
+Things get interesting on the last line of createPartControl (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+The Listener view exists in a page with other views.&nbsp; If a selection
+is made in any of those views, the platform will forward the selection
+event to all interested parties.&nbsp; We are an interested party.&nbsp;
+To register our interest, we get the site, get the page, and add the ListenerView
+as a selection listener.&nbsp; If a selection occurs within the page, the
+ListenerView.selectionChanged method will be called (<img SRC="tag_c.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+Within this method, the selection is examined and, if it is a Word, the
+label text will be updated to reflect the Word name.
+<p>So far so good.&nbsp; The Listener view is ready to receive selection
+events.&nbsp; However, we have a problem: the Word view doesn't publish
+any selection events.
+<p>To reconcile our problem we add one line of code to the Word view (<img SRC="tag_d.jpg" height=13 width=24 align=ABSCENTER>)&nbsp;
+Within the createPartControl method, a selection provider is passed to
+the site.&nbsp; Fortunately, the viewer itself is an ISelectionProvider,
+so it is very easy to define the selection provider for the view.&nbsp;
+When the Word view is active (as indicated by shading in the title bar)
+the platform will redirect any selection events fired from viewer to selection
+listeners within the page.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void createPartControl(Composite parent) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create viewer.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer = new ListViewer(parent);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.setContentProvider(new ListContentProvider());
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.setLabelProvider(new LabelProvider());
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.setInput(input);
+<img SRC="tag_d.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getSite().setSelectionProvider(viewer);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create menu and toolbars.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createActions();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createMenu();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createToolbar();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createContextMenu();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hookGlobalActions();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Restore state from the previous session.
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; restoreState();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+Now we can try out the Listener view.&nbsp; Open up the Word view and the
+Listener view.&nbsp; Add a word to the Word view and then select it.&nbsp;
+The name of the Word will be displayed in the Listener view.&nbsp; A snapshot
+of the result is shown below.
+<center>
+<p><img SRC="ListenerView.jpg" height=397 width=534></center>
+
+<p>The linking approach demonstrated here can be described as <i>activation
+linking</i>.&nbsp; In activation linking, the listener receives selection
+from the active part.&nbsp; The benefit of this approach is that there
+is a loose coupling between the Listener view and other views within the
+same page.&nbsp; If we were to introduce another view, similar to the Word
+view, which published selection events for objects of type Word, these
+objects would also appear in the Listener view.&nbsp; This makes it very
+easy to add, remove, or replace the views in the workbench while maintaining
+good integration between views.
+<p>In contrast to activation linking, a view may also implement <i>explicit
+linking</i>.&nbsp; In explicit linking, the listener tracks selection within
+a specific source view, which is usually discovered by calling <tt>IWorkbenchPage.findView(String
+id)</tt>.&nbsp; There are two drawbacks to this approach.&nbsp; First,
+the listener will be disabled if the specific source view is nonexistent
+or closed by the user, and second, the listener will never work with additional
+views added by the user, or another plug-in.&nbsp; For this reason, the
+use of explicit linking is discouraged.
+<h2>
+Integration with the WorkbenchPage Input</h2>
+In a large, real world project the workspace may contain hundreds or thousands
+of resources.&nbsp; These resources are split among many projects, containing
+many folders, containing many files.&nbsp; It's a tree, and each subtree
+within the whole defines a physical subset of information.&nbsp; To avoid
+the information overload which can sometimes occur by looking at the whole,
+the user can "open a perspective" on any resource subtree within the workspace.&nbsp;
+This is done by selecting a resource in the Navigator view and invoking
+"Open Perspective".&nbsp; The result is a new workbench page where only
+the children of the subtree root are visible.&nbsp; This subtree root is
+known as the <i>input</i>.
+<p>In practice, the visibility of resources within a page is implemented
+through collaboration between the page and the views within that page.&nbsp;
+The page itself is just a visual container for views and editors.&nbsp;
+It doesn't provide any presentation for resources.&nbsp; That is delegated
+to the parts within the page.&nbsp; The hand off usually occurs during
+part creation.&nbsp; In the early stages of part lifecycle a part can obtain
+a handle to the containing <tt>IWorkbenchPage,</tt> and from this it can
+call <tt>IWorkbenchPage.getInput</tt>.&nbsp; The result can be used as
+the initial input for the view.&nbsp; For instance, if a new perspective
+containing the Navigator is opened, the Navigator will use the page input
+as its own input.&nbsp; The Packages view does the same.
+<p>The strategy should be adopted by any view which displays resources
+within the workspace.&nbsp; This will ensure a consistent navigational
+paradigm for users within the platform.
+<h2>
+State Persistence</h2>
+One of the primary goals for the platform UI is to provide efficient interaction
+with the workspace.&nbsp; In the platform this is promoted by saving the
+state of the workbench when a session ends.&nbsp; When a new session is
+started the state of the workbench is recreated.&nbsp; The state of each
+window, page, view and editor is persisted between sessions, reducing the
+time required for the user to get back to work.&nbsp; In this section we'll
+examine how the state of the Word view is saved.
+<p>Within any view there are at least two elements of state: the model
+itself and model presentation (widget state). In our Word view, the model
+is stored as a file in the file system, so it is a non issue.&nbsp; However,
+the widget state should be saved.&nbsp; To do this we need to implement
+the IViewPart.init and IViewPart.saveState methods (shown below) in WordView.
+<pre>&nbsp;&nbsp;&nbsp; public void init(IViewSite site,IMemento memento) throws PartInitException;
+&nbsp;&nbsp;&nbsp; public void saveState(IMemento memento);</pre>
+But first, some background info.&nbsp; When the workbench is closed, the
+IViewPart.saveState method is called on every view.&nbsp; An IMemento is
+passed to the saveState method.&nbsp; This is a structured, hierarchical
+object where you can store integers, floats, Strings, and other IMementos.&nbsp;
+The platform will store the IMemento data in a file called <tt>workbench.xml</tt>
+within the <tt>org.eclipse.ui</tt> metadata directory.&nbsp; When a new
+session is started, the platform will read this file, recreate each window,
+page, and view, and then pass an IMemento to each view in the init method.&nbsp;
+The view can use this to recreate the state of the previous session.
+<p>Now we can do some coding.&nbsp; We will implement the saveState method
+first (shown below).&nbsp; Within this method a memento is created for
+the selection (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>)
+and then one item is added to it for every word which is selected (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+In our code, the word string is used to identify the word.&nbsp; This may
+be an inaccurate way to identify words (two words may have the same string),
+but this is only an article.&nbsp; You should develop a more accurate strategy
+which reflects your own model.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void saveState(IMemento memento){
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sel.isEmpty())
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memento = memento.createChild("selection");
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Iterator iter = sel.iterator();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (iter.hasNext()) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Word word = (Word)iter.next();
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memento.createChild("descriptor", word.toString());
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+Next we implement the init method.&nbsp; When a new session is started,
+the init method will be called just after the part is instantiated, but
+before the createPartControl method is called.&nbsp; In our code all of
+the information within the memento must be restored to the control, so
+we have no choice but to hold on to the memento until createPartControl
+is called.
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void init(IViewSite site,IMemento memento) throws PartInitException {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init(site);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.memento = memento;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+Within createPartControl, the restoreState method is called.&nbsp; Within
+restoreState the selection memento is retrieved (<img SRC="tag_a.jpg" height=13 width=24 align=ABSCENTER>),
+and each descriptor within it is mapped to a real Word (<img SRC="tag_b.jpg" height=13 width=24 align=ABSCENTER>).&nbsp;
+The resulting array of words is used to restore the selection for the viewer
+(<img SRC="tag_c.jpg" height=13 width=24 align=ABSCENTER>).
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void restoreState() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (memento == null)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
+<img SRC="tag_a.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memento = memento.getChild("selection");
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (memento != null) {
+<img SRC="tag_b.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IMemento descriptors [] = memento.getChildren("descriptor");
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (descriptors.length > 0) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ArrayList objList = new ArrayList(descriptors.length);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int nX = 0; nX &lt; descriptors.length; nX ++) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String id = descriptors[nX].getID();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Word word = input.find(id);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (word != null)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objList.add(word);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+<img SRC="tag_c.jpg" height=13 width=24 align=CENTER>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewer.setSelection(new StructuredSelection(objList));
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memento = null;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateActionEnablement();
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
+You may notice certain limitations in the IMemento interface.&nbsp; For
+instance, it can only be used to store integers, floats, and Strings.&nbsp;
+This limitation is a reflection of the persistence requirements in the
+platform UI.
+<br>&nbsp;
+<ol>
+<li>
+Certain objects need to be saved and restored across platform sessions.</li>
+
+<li>
+When an object is restored, an appropriate class for an object might not
+be available. It must be possible to skip an object in this case.</li>
+
+<li>
+When an object is restored, the appropriate class for the object may be
+different from the one when the object was originally saved. If so, the
+new class should still be able to read the old form of the data.</li>
+</ol>
+
+<p><br>Java serialization could be used for persistence.&nbsp; However,
+serialization is only appropriate for RMI and light-weight persistence
+(the archival of an object for use in a later invocation of the same program).&nbsp;
+It is not considered robust for long term storage, where class names and
+structure may change.&nbsp; If any of these occur serialization will throw
+an exception.
+<h2>
+State Inheritance</h2>
+If we take a close look at the standard components in Eclipse an interesting
+pattern emerges.&nbsp; Most of them provide some degree of customization.&nbsp;
+For instance, in the Navigator view there are two actions in the menu,
+Sort and Filter, which can be used to sort or select the visible resources
+in the Navigator.&nbsp; Similar functionality exists within the Tasks view.&nbsp;
+In general, customization is a desirable feature.&nbsp; In this section
+we're not going to look at customization itself, as customization is very
+specific to a particular view and the underlying model.&nbsp; Instead,
+we'll look at some different strategies which you could use to share user
+preferences between views.
+<p>Let's start out with the assumption that the Word view has two sorting
+algorithms.&nbsp; The user may select one as the preferred algorithm.&nbsp;
+How do we share this preference with other views of the same type?
+<p><b>Approach #1: We don't.</b>
+<p>The initial value of the preference will be hard coded in some way,
+probably as a constant in the class declaration.&nbsp; If the user changes
+this preference in one view, it will not be reflected in other views.&nbsp;
+For instance, the Navigator preference for "Sort" is a local preference,
+and is not shared with other Navigator views.
+<p><b>Approach #2: We Use a Preference Page</b>
+<p>The initial value of the preference will be exposed in a preference
+page in the Workbench Preferences.&nbsp; If the user changes this preference,
+the new preference will apply to all instances of the view.&nbsp; For instance,
+the Navigator preference for "Link Navigator selection to active editor"
+is controlled by a check box in the Workbench Preferences.&nbsp; This option
+applies to all Navigator views.
+<p><b>Approach #3: Inheritance.</b>
+<p>The initial value of the preference will be defined in the plugin metadata.&nbsp;
+If a view is opened, it will read the plugin metadata to determine the
+preference.&nbsp; If the user changes the preference in one view, it will
+not affect other views, but it will be saved to the plugin metadata, so
+that any view created in the future will inherit the preference.&nbsp;
+For instance, if the user changes the sort preference in one Word view,
+it will have no affect on other Word views.&nbsp; However, if the user
+opens a new Word view it will inherit the most recent preference.
+<p>While each of these is a valid approach, the correct choice should reflect
+your own view and the underlying model.
+<h2> Summary</h2>
+In this article we have examined the design and implementation of two views,
+a simple Label view and a more comprehensive Word view.&nbsp; The features
+of your own view will probably vary greatly from what we have created.&nbsp;
+However, the integration of your view with the workbench will follow the
+same pattern demonstrated by these views. Further information on view implementation
+is available in the Platform Plug-in Developer Guide and in the javadoc
+for <tt>org.eclipse.ui</tt>.
+
+<p><small>Java and all Java-based trademarks and logos are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the United States, other countries, or
+both.</small></p>
+
+</body>
+</html>
diff --git a/viewArticle/WordView.jpg b/viewArticle/WordView.jpg
new file mode 100644
index 0000000..ad8db21
--- /dev/null
+++ b/viewArticle/WordView.jpg
Binary files differ
diff --git a/viewArticle/arrow.gif b/viewArticle/arrow.gif
new file mode 100644
index 0000000..5fc29ad
--- /dev/null
+++ b/viewArticle/arrow.gif
Binary files differ
diff --git a/viewArticle/default_style.css b/viewArticle/default_style.css
new file mode 100644
index 0000000..16277c9
--- /dev/null
+++ b/viewArticle/default_style.css
@@ -0,0 +1,11 @@
+p { font-family: arial, helvetica, geneva; font-size: 10pt}
+td { font-family: arial,helvetica,geneva; font-size: -1}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+th { font-family: arial,helvetica,geneva; font-size: 11px; font-weight: bold}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
diff --git a/viewArticle/menus.jpg b/viewArticle/menus.jpg
new file mode 100644
index 0000000..f115f7d
--- /dev/null
+++ b/viewArticle/menus.jpg
Binary files differ
diff --git a/viewArticle/tag_a.jpg b/viewArticle/tag_a.jpg
new file mode 100644
index 0000000..3728217
--- /dev/null
+++ b/viewArticle/tag_a.jpg
Binary files differ
diff --git a/viewArticle/tag_b.jpg b/viewArticle/tag_b.jpg
new file mode 100644
index 0000000..a7903ad
--- /dev/null
+++ b/viewArticle/tag_b.jpg
Binary files differ
diff --git a/viewArticle/tag_c.jpg b/viewArticle/tag_c.jpg
new file mode 100644
index 0000000..03516e7
--- /dev/null
+++ b/viewArticle/tag_c.jpg
Binary files differ
diff --git a/viewArticle/tag_d.jpg b/viewArticle/tag_d.jpg
new file mode 100644
index 0000000..8c27fb5
--- /dev/null
+++ b/viewArticle/tag_d.jpg
Binary files differ
diff --git a/viewArticle/tag_e.jpg b/viewArticle/tag_e.jpg
new file mode 100644
index 0000000..c28f7ce
--- /dev/null
+++ b/viewArticle/tag_e.jpg
Binary files differ
diff --git a/viewArticle/tag_f.jpg b/viewArticle/tag_f.jpg
new file mode 100644
index 0000000..7d1538c
--- /dev/null
+++ b/viewArticle/tag_f.jpg
Binary files differ
diff --git a/viewArticle/tag_g.jpg b/viewArticle/tag_g.jpg
new file mode 100644
index 0000000..b5441bd
--- /dev/null
+++ b/viewArticle/tag_g.jpg
Binary files differ
diff --git a/viewArticle/viewArticleSrc.zip b/viewArticle/viewArticleSrc.zip
new file mode 100644
index 0000000..354753d
--- /dev/null
+++ b/viewArticle/viewArticleSrc.zip
Binary files differ

Back to the top